【发布时间】:2019-05-26 13:52:06
【问题描述】:
我按照 Hugo Fierro 的教程添加了 Google Apps 脚本以从 Google 表格发送电子邮件。 tut 在https://developers.google.com/apps-script/articles/sending_emails。
我自定义了脚本:
1) 我用“GmailApp.sendEmail”替换了“MailApp.sendEmail”API,因为我遇到了身份验证错误并且电子邮件没有发送。 Gmail API 运行良好。
2) 我添加了一个选项,可以使用“DriveApp.getFileById”在每封邮件中发送 PDF 附件。
3) 我在 IF 语句中添加了第二个条件,以在发送前检查 PDF 文档是否可用(通过引用工作表中的列)。
问题在于,如果脚本仅引用 5 行,则它会在 30 秒内处理完毕。当我尝试处理 10 行或更多行时,处理时间会显着增加。
我用“sheet.getLastRow()”替换了“sheet.getRange”,试图减少脚本引用的行数。
var READY = 'READY';
var SENT = 'SENT';
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Email'); // Get the active spreadsheet, then get the "Email" sheet
var startRow = 2; // Select data row to start at
var endRow = sheet.getLastRow(); // Get the last row in the sheet
var data = sheet.getRange(startRow, 1, endRow, 6).getValues(); // Get the range of cells, then get the values
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var email = row[0]; // Column 1
var subject = row[1]; // Column 2
var message = row[2]; // Column 3
var attachment = DriveApp.getFileById(row[3]); // Returns the attachment file ID
var emailReady = row[4]; // Column 5
var emailSent = row[5]; // Column 6
var name = 'VFISA'; // Set "from" name in email
var bcc = 'myaddress@gmail.com'; // Blind carbon copy this email address
if (emailReady==READY && emailSent!==SENT) { // Prevents sending duplicates, waits for attachment cell to confirm available
GmailApp.sendEmail(email, subject, message,{
name: name,
bcc: bcc,
htmlBody: message,
attachments: attachment
});
sheet.getRange(startRow + i, 6).setValue(SENT); // Set the cell in column F to "SENT"
SpreadsheetApp.flush(); // Make sure the cell is updated right away in case the script is interrupted
}
}
}
我希望脚本运行得更快。我得到的错误是“一天使用太多计算机时间的服务”。当我引用 20 行时,运行最多需要 4 分钟。
【问题讨论】:
-
我有一个类似的脚本,它也很慢,它最多可以处理 40 封电子邮件,即使没有附件也没有附件。您可以通过在脚本编辑器中选择“显示”然后选择“执行脚本”来检查每个操作所花费的时间。
-
除了best practices 指南的强制性链接之外,在这种情况下,最好的办法可能是它提出的最后一个建议——拆分你的执行。调用电子表格、驱动器和发送邮件都可能需要一段时间。我假设您是在时间触发器上执行此操作 - 尝试使用
var n = data.length > 5 ? 5 : data.length;和i < n作为 for 循环中的条件怎么样? -
作为测试,我将删除以下两行:
sheet.getRange(startRow + i, 6).setValue(SENT); // Set the cell in column F to "SENT" SpreadsheetApp.flush();如果它对您产生的影响足够大,那么我将删除flush()语句,并替换单个单元格 setValue用别的东西。您可以更新数据,然后在一个操作中将数据写回电子表格。此外,您可以添加文件链接而不是附件。 -
更新:问题已解决。再次感谢。我已经删除了
DriveApp.getFileById,而是使用了内联链接(基于 Alan Wells 的建议)。我添加了 500 行,脚本执行 -
@SheldonKennedy 请发布您应用的解决方案作为答案。
标签: google-apps-script google-sheets gmail