You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google脚本超时且重复下载附件问题求助及优化建议

Google脚本优化:解决超时、重复下载问题并支持共享驱动器

问题分析

原脚本存在以下核心问题:

  • 执行超时:一次性处理所有匹配线程,线程数量大时易触发Google Apps Script 6分钟执行上限
  • 重复下载:仅给线程添加标签,脚本中断后会重复处理;未校验Drive中已存在的附件,导致重复占用空间
  • 无共享驱动器支持:仅默认使用"我的驱动器",未满足优先使用Workspace共享驱动器的需求

修改后的完整代码

// 配置项
var fileTypesToExtract = ['csv', 'xlsm', 'xlsx', 'xls', 'pdf'];
var folderName = 'Audit Grab to Sort';
var labelName = '@indrive';
var sharedDriveId = ''; // 替换为你的共享驱动器ID,留空则使用"我的驱动器"
var batchSize = 50; // 每次处理的线程数量,避免超时

function GmailToDrive() {
  // 构建搜索查询
  var queryParts = fileTypesToExtract.map(type => `filename:${type}`);
  var query = `in:inbox has:nouserlabels (${queryParts.join(' OR ')})`;

  var label = getGmailLabel_(labelName);
  var parentFolder = getFolder_(folderName);
  if (!parentFolder) return;

  var start = 0;
  var threads;
  do {
    // 分批获取线程,避免一次性处理过多导致超时
    threads = GmailApp.search(query, start, batchSize);
    if (threads.length === 0) break;

    for (var i = 0; i < threads.length; i++) {
      var thread = threads[i];
      var messages = thread.getMessages();
      
      try {
        for (var j = 0; j < messages.length; j++) {
          var message = messages[j];
          // 跳过已处理的邮件
          if (message.hasLabel(label)) continue;

          var attachments = message.getAttachments();
          for (var k = 0; k < attachments.length; k++) {
            var attachment = attachments[k];
            // 过滤非目标类型的附件
            if (!checkIfDefinedType_(attachment)) continue;

            var fileName = attachment.getName();
            var fileSize = attachment.getSize();
            var existingFile = findExistingFile_(parentFolder, fileName, fileSize);

            // 仅当Drive中不存在相同文件时创建
            if (!existingFile) {
              parentFolder.createFile(attachment.copyBlob());
              console.log(`已创建文件: ${fileName}`);
            } else {
              console.log(`文件已存在,跳过: ${fileName}`);
            }
          }
          // 处理完单封邮件后添加标签,精准标记已处理状态
          message.addLabel(label);
        }
        // 给线程添加标签(可选,便于可视化筛选)
        thread.addLabel(label);
      } catch (e) {
        console.error(`处理线程失败: ${e.message},线程ID: ${thread.getId()}`);
      }
    }
    start += batchSize;
  } while (threads.length === batchSize);
}

function getFolder_(folderName) {
  try {
    // 优先使用共享驱动器
    if (sharedDriveId) {
      var sharedDrive = DriveApp.getFolderById(sharedDriveId);
      var folders = sharedDrive.getFoldersByName(folderName);
      return folders.hasNext() ? folders.next() : sharedDrive.createFolder(folderName);
    }
    // 共享驱动器不可用时,回退到"我的驱动器"
    var folders = DriveApp.getFoldersByName(folderName);
    return folders.hasNext() ? folders.next() : DriveApp.createFolder(folderName);
  } catch (e) {
    console.error(`获取/创建文件夹失败: ${e.message}`);
    return null;
  }
}

function findExistingFile_(folder, fileName, fileSize) {
  // 查找同名且大小一致的文件,避免重复创建
  var files = folder.getFilesByName(fileName);
  while (files.hasNext()) {
    var file = files.next();
    if (file.getSize() === fileSize) {
      return file;
    }
  }
  return null;
}

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

function checkIfDefinedType_(attachment) {
  var fileName = attachment.getName();
  var extParts = fileName.split('.');
  if (extParts.length < 2) return false;
  var fileExtension = extParts[extParts.length - 1].toLowerCase();
  return fileTypesToExtract.indexOf(fileExtension) !== -1;
}

关键优化点

  1. 分批处理线程:通过GmailApp.search(query, start, batchSize)分页获取线程,每次处理50条,避免触发超时限制
  2. 精准标记已处理:给单封邮件添加标签而非线程,即使脚本中断,已处理的邮件也不会被重复扫描
  3. 附件重复校验:新增findExistingFile_函数,检查目标文件夹中是否存在同名且大小一致的附件,存在则跳过创建
  4. 共享驱动器支持:新增sharedDriveId配置项,优先从共享驱动器获取/创建文件夹,失败则回退到"我的驱动器"
  5. 错误容错:添加try-catch块,单个线程处理失败不会导致整个脚本终止,同时输出错误日志便于排查
  6. 优化查询构建:使用数组map和join简化查询字符串拼接,更易维护

内容的提问来源于stack exchange,提问作者Michael Williams

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 10:22:02