Apps Script带附件邮件合并脚本效率优化方案咨询
你的现有脚本存在多处可优化效率的空间,具体优化点和优化后代码如下:
核心优化点
- 附件读取逻辑移出循环:原代码每次遍历收件人都会重复调用Drive接口拉取相同附件、生成Blob,不仅浪费请求配额还会大幅拉长执行时间,调整后仅在脚本启动时执行1次附件读取即可。
- 替换单条写入为批量更新状态:原代码每次发送成功后调用1次
setValue更新状态,表格单条读写开销极高,调整为先收集所有需要更新的状态,最后统一调用setValues批量写入,可将表格IO次数从N次降到1次。 - 新增单邮件异常捕获:用try-catch包裹单封邮件的发送逻辑,避免某一封邮件发送出错(比如收件人地址无效)导致整个脚本终止,后续邮件无法发送的问题。
- 固定配置抽离:将回复地址、附件ID、工作表名这类固定配置统一抽离到脚本开头,后续修改无需遍历业务逻辑,维护更方便。
- 变量声明规范:将原代码中混用的
var统一替换为const/let,避免变量提升带来的潜在问题。
优化后完整代码
function terminEinladungVersendenWithAttachments() { // 固定配置项,后续修改直接调整这里即可 const CONFIG = { REPLY_TO: "f.dore@skillgainer.de", ATTACHMENT_IDS: ["[FILE_ID1]", "[FILE_ID2]"], // 新增附件直接在数组中追加ID即可 SHEET_NAMES: { RECIPIENT: "terminBestaetigen", TEMPLATE: "Vorlagen" }, START_ROW: 3, // 数据起始行 STATUS_COL: 11, // 发送状态列(K列) SENT_STATUS: "EMAIL SENT", UNSENT_STATUS: "EMAIL NOT SENT YET" } // 列索引定义 const anrede = 2; const nachname = 3; const emailAdresse = 5; const terminTag = 6; const terminUhrzeit = 8; const terminURL = 9; // 初始化公共资源,仅执行1次 const emailTemp = HtmlService.createTemplateFromFile('emailEinladung'); const sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(CONFIG.SHEET_NAMES.RECIPIENT); const wsVorlagen = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(CONFIG.SHEET_NAMES.TEMPLATE); const betreff = wsVorlagen.getRange("B1").getValue(); // 提前读取所有附件生成Blob,避免循环中重复调用Drive接口 const attachments = CONFIG.ATTACHMENT_IDS.map(fileId => DriveApp.getFileById(fileId).getBlob()); // 读取所有收件人数据 const data = sh.getRange(CONFIG.START_ROW, 1, sh.getLastRow() - CONFIG.START_ROW + 1, 11).getValues(); // 初始化状态更新数组,保留原有状态 const statusUpdate = data.map(row => [row[10]]); // 遍历处理每个收件人 data.forEach((row, index) => { if (row[10] === CONFIG.UNSENT_STATUS) { try { // 填充模板变量 emailTemp.anrede1 = row[anrede]; emailTemp.nachname1 = row[nachname]; emailTemp.emailAdresse1 = row[emailAdresse]; emailTemp.terminTag1 = row[terminTag]; emailTemp.terminUhrzeit1 = row[terminUhrzeit]; emailTemp.terminURL1 = row[terminURL]; const htmlMessage = emailTemp.evaluate().getContent(); // 发送邮件 GmailApp.sendEmail( row[emailAdresse], betreff, "Dies ist eine Nachricht im HTML-Format. Sie müßen Ihre Email-Software entsprechend einrichten.", { htmlBody: htmlMessage, replyTo: CONFIG.REPLY_TO, attachments: attachments } ); // 标记为已发送 statusUpdate[index][0] = CONFIG.SENT_STATUS; } catch (error) { // 此处可添加错误日志,比如打印失败的收件人地址和报错信息,方便排查 console.error(`第${index + CONFIG.START_ROW}行邮件发送失败,收件人:${row[emailAdresse]},报错:${error.message}`); } } }); // 批量更新所有发送状态,仅执行1次表格写入 sh.getRange(CONFIG.START_ROW, CONFIG.STATUS_COL, statusUpdate.length, 1).setValues(statusUpdate); }
内容的提问来源于stack exchange,提问作者Bob Hardball
相关产品推荐
相关产品推荐

