如何解决Google Apps Script发送邮件的每日调用次数超限问题
Google Apps Script发送邮件触发每日限制的解决方案
问题背景
使用Google Apps Script发送邮件时遇到错误:Service invoked too many times for one day: email,已知存在每日发送限制,需解决以下问题:
- 在Google Apps Script中高效发送大量邮件不触发限制的推荐策略?
- 是否建议切换到Gmail API获取更高限制?如果是,如何在脚本中配置?
- Google Apps Script中有没有不受此类限制的替代或变通方法?
现有脚本说明
当前使用的sendEmails脚本基于Google Sheet自动发送邮件,流程如下:
- 变量设置:初始化邮件内容、主题、Drive文件夹ID及已发送记录文件名;
- 获取Sheet数据:读取邮箱地址(孩子和家长)、分数等数据;
- 校验发送:遍历数据行,检查分数是否以“+”结尾,同时验证邮箱未发送过,避免重复;
- 发送与记录:根据邮箱情况单独/同时发送,发送后将邮箱写入
sent_emails.txt记录。
现有代码
function sendEmails() { var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); var data = sheet.getDataRange().getValues(); var message = "Здравствуйте, вы получили плюс!"; var subject = "Поздравляем!"; var folderId = '19CAHVoMPr8mKlZumZ9mRXBF9VIL3woPy'; var fileName = "sent_emails.txt"; var folder = DriveApp.getFolderById(folderId); var file; try { file = folder.getFilesByName(fileName).next(); } catch (e) { file = folder.createFile(fileName, ''); } var sentEmails = file.getBlob().getDataAsString().split('\n'); for (var i = 1; i < data.length; i++) { var email1 = data[i][16]; var email2 = data[i][17]; var score = String(data[i][7]); if (score.match(/\+$/) && (!sentEmails.includes(email1) || !sentEmails.includes(email2))) { if (email1 && email2) { GmailApp.sendEmail([email1, email2], subject, message); file.setContent(file.getBlob().getDataAsString() + email1 + '\n'+ email2 + '\n'); } else if (email1) { GmailApp.sendEmail(email1, subject, message); file.setContent(file.getBlob().getDataAsString() + email1 + '\n'); } else if (email2) { GmailApp.sendEmail(email2, subject, message); file.setContent(file.getBlob().getDataAsString() + email2 + '\n'); } } } }
解决方案
1. 高效发送大量邮件的策略
- 批量合并收件人:若邮件内容一致,将多个收件人放入
Bcc(密送)字段,每发送1封邮件仅消耗1次配额,而非每个收件人各消耗1次。例如把同一批次的家长/孩子邮箱统一加入Bcc。 - 优化记录写入逻辑:现有代码每次发送后都调用
file.setContent()频繁读写Drive文件,既低效又可能触发Drive配额。建议先将待记录邮箱存入内存数组,遍历结束后一次性写入文件。 - 分批次定时发送:将发送任务拆分为多个小批次,通过时间驱动触发器设置间隔执行(如每小时发送一部分),避免单次发送量超过当日配额。
- 本地标记已发送:在Sheet中新增“已发送”列,标记处理完成的行,减少每次脚本运行时的校验开销,同时避免重复发送。
2. 切换到Gmail API获取更高限制
建议切换,Gmail API的每日发送配额远高于GmailApp:普通账号每日上限500封,Google Workspace账号上限2000封(GmailApp普通账号仅100封)。配置步骤如下:
- 在Apps Script编辑器中,点击资源 > 高级Google服务,找到Gmail API并启用。
- 替换原
GmailApp.sendEmail调用为Gmail API的发送方法,示例代码:
function sendEmailWithGmailAPI(to, subject, message) { // 构建符合RFC 2822格式的邮件内容 var emailContent = `To: ${to}\nSubject: ${subject}\n\n${message}`; // 编码为Base64格式 var encodedEmail = Utilities.base64EncodeWebSafe(emailContent, Utilities.Charset.UTF_8); // 调用Gmail API发送 Gmail.Users.Messages.send({raw: encodedEmail}, 'me'); }
- 首次运行脚本需完成授权流程,确保脚本拥有Gmail API的访问权限。
3. 替代或变通方法
- 升级Google Workspace账号:Workspace账号的邮件发送配额远高于免费账号,
GmailApp每日上限可达2000封,Gmail API上限更高,适合企业/团队场景。 - 调用第三方邮件服务:通过
UrlFetchApp调用SendGrid、Mailgun等第三方SMTP服务的API,这类服务通常有更高的发送配额,且不受Google Apps Script的邮件限制(需提前注册服务并获取API密钥)。 - 使用自带邮件合并插件:借助Google Sheets官方或第三方邮件合并插件(如Mail Merge with Attachments),这类工具已优化发送逻辑,能高效利用配额,无需大量修改代码。
内容的提问来源于stack exchange,提问作者Sarmat Karaf
相关产品推荐
相关产品推荐

