【问题标题】:Copying attachments from Gmail to Google Drive folder and overwriting old files with Apps Script将附件从 Gmail 复制到 Google Drive 文件夹并使用 Apps 脚本覆盖旧文件
【发布时间】:2021-08-28 17:30:36
【问题描述】:

我正在尝试使用 Google Apps 脚本自动将附件从 Gmail 收件箱下载到帐户 Google Drive 上的特定文件夹。我发现下面的代码可以很好地完成该部分,但我还需要它用新文件覆盖同名文件或删除旧文件并上传新文件。此外,当我只需要复制 .xlsx 文件时,它似乎仍在从具有多个附件的电子邮件中下载所有文件类型。任何帮助将非常感激。 (代码归功于 googleappsscript.org)

// GLOBALS
//Array of file extension which you would like to extract to Drive
var fileTypesToExtract = ['jpg', 'tif', 'png', 'gif', 'bmp', 'svg'];
//Name of the folder in google drive i which files will be put
var folderName = 'GmailToDrive';
//Name of the label which will be applied after processing the mail message
var labelName = '@indrive';



function GmailToDrive(){
  //build query to search emails
  var query = '';
  //filename:jpg OR filename:tif OR filename:gif OR fileName:png OR filename:bmp OR filename:svg'; //'after:'+getDateNDaysBack_(1)+
  for(var i in fileTypesToExtract){
    query += (query === '' ?('filename:'+fileTypesToExtract[i]) : (' OR filename:'+fileTypesToExtract[i]));
  }
  query = 'in:inbox has:nouserlabels ' + query;
//  query += ' after:'+getDateNDaysBack_(1);
  var threads = GmailApp.search(query);
  var label = getGmailLabel_(labelName);
  var parentFolder;
  if(threads.length > 0){
    parentFolder = getFolder_(folderName);
  }
  var root = DriveApp.getRootFolder();
  for(var i in threads){
    var mesgs = threads[i].getMessages();
    for(var j in mesgs){
      //get attachments
      var attachments = mesgs[j].getAttachments();
      for(var k in attachments){
        var attachment = attachments[k];
//      var isDefinedType = checkIfDefinedType_(attachment);
//      if(!isDefinedType) continue;
        var attachmentBlob = attachment.copyBlob();
        var file = DriveApp.createFile(attachmentBlob);
        parentFolder.addFile(file);
        root.removeFile(file);
      }
    }
    threads[i].addLabel(label);
  }
}

//This function will get the parent folder in Google drive
function getFolder_(folderName){
  var folder;
  var fi = DriveApp.getFoldersByName(folderName);
  if(fi.hasNext()){
    folder = fi.next();
  }
  else{
    folder = DriveApp.createFolder(folderName);
  }
  return folder;
}

//getDate n days back
// n must be integer
function getDateNDaysBack_(n){
  n = parseInt(n);
  var date = new Date();
  date.setDate(date.getDate() - n);
  return Utilities.formatDate(date, Session.getScriptTimeZone(), 'yyyy/MM/dd');
}

function getGmailLabel_(name){
  var label = GmailApp.getUserLabelByName(name);
  if(!label){
    label = GmailApp.createLabel(name);
  }
  return label;
}

//this function will check for filextension type.
// and return boolean
function checkIfDefinedType_(attachment){
  var fileName = attachment.getName();
  var temp = fileName.split('.');
  var fileExtension = temp[temp.length-1].toLowerCase();
  if(fileTypesToExtract.indexOf(fileExtension) !== -1) return true;
  else return false;
}

【问题讨论】:

  • 我只是想澄清一下,您只想下载/复制电子邮件中附加的 .xslx 文件?并将其上传到驱动器中的特定文件夹中(删除现有的类似文件名并将其替换为新文件)?这是正确的吗?
  • 您现在拥有的代码执行了一个 createFile,它每次都会创建一个新文件。您应该做的是搜索与您正在下载的文件同名的文件,然后执行更新文件。
  • @RonM 是的,只有 .xlsx 文件,是的,我想将它们上传到特定文件夹并替换具有相同文件名的文件。

标签: google-apps-script google-drive-api gmail gmail-api


【解决方案1】:

这是一个示例代码:

// GLOBALS
//Array of file extension which you would like to extract to Drive
var fileTypesToExtract = ['xlsx'];
//Name of the folder in google drive i which files will be put
var folderName = 'GmailToDrive';
//Name of the label which will be applied after processing the mail message
var labelName = '@indrive';

function GmailToDrive() {
  var query = '';

  for(var i in fileTypesToExtract){
    query += (query === '' ?('filename:'+fileTypesToExtract[i]) : (' OR filename:'+fileTypesToExtract[i]));
  }
  query = 'in:inbox has:nouserlabels ' + query;
  Logger.log(query);

  var threads = GmailApp.search(query);
  var label = getGmailLabel_(labelName);
  var parentFolder = getFolder_(folderName);

  for(var i in threads){
    var mesgs = threads[i].getMessages();
    for(var j in mesgs){
      //get attachments
      var attachments = mesgs[j].getAttachments();
      for(var k in attachments){
        var attachment = attachments[k];
        Logger.log(attachment.getName());
        Logger.log(attachment.getContentType())

        //Check if attached file is xlsx file
        if(attachment.getContentType() == MimeType.MICROSOFT_EXCEL){
          var attachmentBlob = attachment.copyBlob();

          //Check if filename exist in the drive folder then remove the file
          var files = parentFolder.getFilesByName(attachment.getName());
          while (files.hasNext()) {
            var file = files.next();
            Logger.log("FILE EXIST. Removing.....");
            //Remove existing file
            file.setTrashed(true);
          }
          
          //Create a new file in the drive folder
          var newFile = parentFolder.createFile(attachmentBlob);
        }
      }
    }
    threads[i].addLabel(label);
  }
}

function getGmailLabel_(name){
  var label = GmailApp.getUserLabelByName(name);
  if(!label){
    label = GmailApp.createLabel(name);
  }
  return label;
}

//This function will get the parent folder in Google drive
function getFolder_(folderName){
  var folder;
  var fi = DriveApp.getFoldersByName(folderName);
  if(fi.hasNext()){
    folder = fi.next();
  }
  else{
    folder = DriveApp.createFolder(folderName);
  }
  return folder;
}

修改完成:

【讨论】:

  • 如果您遇到问题,请告诉我,以便我可以相应地修复和更新答案。
  • 第 48 行出现错误,需要删除“=”。但是在我删除之后,一切都很完美!我已经在我能想到的所有场景中进行了测试,并且没有遇到任何其他问题。非常感谢!
  • 我删除了答案中多余的=。谢谢你告诉我
  • 顺便说一下,如果我们回答了您的问题,请点击接受按钮。通过这样做,社区中可能与您有同样担忧的其他人将知道他们的问题可以得到解决。如果您无法使用接受按钮,请随时告诉我。 How to accept answer
【解决方案2】:

在您的脚本中,您注释掉了 inDefinedType 功能。

关于替换文件内容或删除同名文件,您可以

使用 getFilesByName() 查找 parentFolder 中的所有文件并丢弃所有旧文件。

【讨论】:

    猜你喜欢
    • 2020-06-18
    • 1970-01-01
    • 2013-06-26
    • 2022-11-23
    • 1970-01-01
    • 2021-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多