使用Apps Script自动保存Gmail附件至Google Drive

609 阅读3分钟

需求

接收到特定的邮件, 自动将邮件中的附件保存到Google Drive中.

Gmail API允许开发人员通过编程方式访问和管理Gmail帐户中的电子邮件。线程(Thread)是一组具有相同主题的电子邮件消息的集合,通常在回复和转发邮件时会创建新的线程。而消息(Message)则是具体的电子邮件。

1. 第一版 BY GPT

  1. 直接使用GmailApp.search() 搜索特定的邮件
  2. message.getAttachments()获取附件
  3. 将附件保存到GoogleDrive中
  4. 将邮件状态变为已读 & 取掉星标
  5. 添加触发器 每5min执行一次
function saveAttachmentsByLabelNameToDrive() {
  var userProperties = PropertiesService.getUserProperties()
  
  var labelName = userProperties.getProperty("labelName"); // 邮件标签名称

  var folderName = userProperties.getProperty("folderName"); // 保存附件的文件夹名称
  
  const threads = GmailApp.search('is:starred label:'+labelName);
  var folder = getOrCreateFolder(folderName);

  for (const thread of threads) {
    var messages = thread.getMessages();
    for (var j = 0; j < messages.length; j++) {
      var message = messages[j];
      var attachments = message.getAttachments();
      if (message.isStarred()) {
        for (var k = 0; k < attachments.length; k++) {
          var attachment = attachments[k];
          var file = folder.createFile(attachment.getName(), attachment);
        }
        message.markRead()        
        message.unstar( )
      }
    }
  }
}

function getOrCreateFolder(folderName) {
  var folders = DriveApp.getFoldersByName(folderName);
  if (folders.hasNext()) {
    return folders.next();
  } else {
    return DriveApp.createFolder(folderName);
  }
}

2. 第二版

  1. 哪些邮件需要自动保存附件
    具体情况具体分析, 这里设置来自我另外一个邮箱的邮件需要保存.
  2. 如何识别这些邮件
    可以使用Gmail 中的标签去识别符合条件的邮件:
    • 新建标签 autoSaveAttach
    • 添加过滤器 ![[Pasted image 20230612145727.png]] 下一步, ![[Pasted image 20230612145840.png]] 这样创建过滤器, 来自 152*****@163.com 发送的邮件 并且包含"This is attach mail" 并带有附件的邮件会被自动加上星标 添加标签 autoAttach
// 自动保存含有标签的 附件到 google drive文件夹
function saveAttachmentsByLabelNameToDrive(labelName) {

	//labelName 邮件标签名称
	//folderName 保存附件的文件夹名称
	const threads = GmailApp.search('is:starred label:'+labelName);
	for (const thread of threads) {
	execThread(thread)
	}
}
  1. 如何去保存 通过DriveApp.createFolder(folderName).createFile(attachment.getName(), attachment);进行附件的保存
function execThread(thread){
  var labels = thread.getLabels()
  var folderName = getSaveFolderName(labels)
  var folder = getOrCreateFolder(folderName)
  var messages = thread.getMessages();
  for (var j = 0; j < messages.length; j++) {
    var message = messages[j];
    var attachments = message.getAttachments();
    if (message.isStarred()) {
      for (var k = 0; k < attachments.length; k++) {
        var attachment = attachments[k];
        var file = folder.createFile(attachment.getName(), attachment);
      }
      message.unstar()
    }
  }
}

// 获取google drive save folder
function getOrCreateFolder(folderName) {
  var folders = DriveApp.getFoldersByName(folderName);
  if (folders.hasNext()) {
    return folders.next();
  } else {
    return DriveApp.createFolder(folderName);
  }
}
  1. 保存到哪里 同第二步 配置过滤器 给邮件添加标签 autoSave-folder1 通过解析这个标签 将附件保存到folder1 中
//根据配置属性前缀取需要保存的文件夹
function getSaveFolderName(labels){
  for (var i = 0; i < labels.length; i++) {
    Logger.log(labels[i].getName());
    var labelName =labels[i].getName()
    if(labelName.startsWith(saveFolderPrefix)){
      return labelName.split(saveFolderPrefix)[1]
    }
  }
}

完整代码

/**
 * 当邮件包含 labelName:  autoAttach 时
 * 保存文件到 autoSave- 为前缀的文件夹中 
 * 
 */
var sriptProperties = PropertiesService.getScriptProperties()
var labelName =  sriptProperties.getProperty("labelName")
var saveFolderPrefix =  sriptProperties.getProperty("saveFolderPrefix")
function main(){
  saveAttachmentsByLabelNameToDrive(labelName)
}

// 自动保存含有标签的 附件到 google drive文件夹
function saveAttachmentsByLabelNameToDrive(labelName) {
  //labelName   邮件标签名称
  //folderName  保存附件的文件夹名称
  const threads = GmailApp.search('is:starred label:'+labelName);
  for (const thread of threads) {
    execThread(thread)
  }
}

function execThread(thread){
  var labels = thread.getLabels()
  var folderName = getSaveFolderName(labels)
  var folder = getOrCreateFolder(folderName)
  var messages = thread.getMessages();
  for (var j = 0; j < messages.length; j++) {
    var message = messages[j];
    var attachments = message.getAttachments();
    if (message.isStarred()) {
      for (var k = 0; k < attachments.length; k++) {
        var attachment = attachments[k];
        var file = folder.createFile(attachment.getName(), attachment);
      }
      message.unstar()
    }
  }
}

// 获取google drive save folder
function getOrCreateFolder(folderName) {
  var folders = DriveApp.getFoldersByName(folderName);
  if (folders.hasNext()) {
    return folders.next();
  } else {
    return DriveApp.createFolder(folderName);
  }
}

//根据配置属性前缀取需要保存的文件夹
function getSaveFolderName(labels){
  for (var i = 0; i < labels.length; i++) {
    Logger.log(labels[i].getName());
    var labelName =labels[i].getName()
    if(labelName.startsWith(saveFolderPrefix)){
      return labelName.split(saveFolderPrefix)[1]
    }
  }
}