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

Google Apps Script调用DriveApp.getFileById报错及批量发票邮件发送问题

报错原因

出现Unexpected error while getting the method or property getFileById on object DriveApp报错的核心原因是参数传递错误:你提前定义invoiceFileID = 2表示文件ID在每行数据的下标为2的位置,但调用DriveApp.getFileById()时直接传入了invoiceFileID变量,相当于固定传入数值2作为文件ID,而非每行对应位置的实际文件ID。

修复后完整代码
function invoiceDispatcher() {
  // 替换为你自己的表格ID
  const SPREADSHEET_ID = "SPREADSHEETID";
  const invoiceDispatcherSheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName("invoicedispatcherlog");
  
  // 字段索引定义(对应行数组的下标,从0开始)
  const INVOICE_NUMBER_INDEX = 0;
  const INVOICE_DATE_INDEX = 9;
  const CUSTOMER_EMAIL_INDEX = 8;
  const INVOICE_FILE_ID_INDEX = 2;
  // 发送时间戳写入列(K列对应第10列,Spreadsheet列号从1开始计数)
  const SEND_TIME_COLUMN = 10;

  // 读取所有有效行数据
  const transactionData = invoiceDispatcherSheet.getRange(2, 1, invoiceDispatcherSheet.getLastRow() - 1, 13).getValues();
  // 过滤出勾选了发送开关的行
  const cleanData = transactionData.filter(cases => cases[11] === true);

  cleanData.forEach((row, index) => {
    try {
      // 每次循环新建模板实例,避免参数污染
      const emailTemplate = HtmlService.createTemplateFromFile("invoiceEmailTemplate");
      // 填充模板参数
      emailTemplate.rn = row[INVOICE_NUMBER_INDEX];
      emailTemplate.rd = Utilities.formatDate(row[INVOICE_DATE_INDEX], "CEST", "dd.MM.yyyy");
      
      // 获取发票PDF文件
      const invoiceFile = DriveApp.getFileById(row[INVOICE_FILE_ID_INDEX]).getAs(MimeType.PDF);
      const invoiceMessage = emailTemplate.evaluate().getContent();
      
      // 发送邮件
      GmailApp.sendEmail(
        row[CUSTOMER_EMAIL_INDEX],
        `Your Invoice Document ${row[INVOICE_NUMBER_INDEX]}`,
        "Please open this message in an HTML-compatible email client. Thank you",
        {
          name: "Company Name",
          htmlBody: invoiceMessage,
          attachments: [invoiceFile]
        }
      );

      // 写入发送成功时间戳,对应表格行号 = 过滤后数组下标 + 起始行2
      const targetRow = index + 2;
      invoiceDispatcherSheet.getRange(targetRow, SEND_TIME_COLUMN).setValue(new Date());
      
    } catch (error) {
      // 出错时打印日志,不会中断其他邮件发送
      console.error(`发票号 ${row[INVOICE_NUMBER_INDEX]} 发送失败,错误信息:${error.message}`);
    }
  })
}
关键修改说明
  • 修复文件ID获取逻辑:将DriveApp.getFileById(invoiceFileID)调整为DriveApp.getFileById(row[invoiceFileID]),正确读取每行对应的Drive文件ID
  • 新增发送成功时间戳写入逻辑:邮件发送完成后自动向对应行的第10列(K列)写入当前时间,无需手动记录
  • 新增异常捕获逻辑:单条数据出错时只会打印错误日志,不会中断其余邮件的发送,可在Apps Script的执行日志中查看失败的发票号和错误原因
  • 优化HTML模板实例化位置:将模板实例化移至循环内部,避免多封邮件之间的参数残留污染
  • 常量命名优化:将固定配置的索引改为大写命名,后续调整字段位置时修改更方便
注意事项
  • 请先将代码中SPREADSHEETID替换为你自己的Google Sheets实际ID
  • 确保运行脚本的账号对所有发票文件有至少查看权限,否则依然会出现权限类报错
  • 首次运行需要按照提示授予脚本访问表格、Drive、Gmail的相关权限
  • 表格中第12列(下标11)的勾选框是发送开关,只有勾选为true的行才会被脚本处理,你可以根据需要自行添加发送后取消勾选的逻辑,避免重复发送

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 08:06:03