为何Google Apps Script仅向列中最后一个邮箱地址发送邮件?
问题排查:Google Apps Script 批量发送邮件仅最后一个收件人收到/移除pop()后报无效邮箱错误
仅最后一个邮箱收到邮件的原因
代码里的.pop()方法会直接取出数组的最后一个元素并移除其他内容,最终emailAddress只会是单个邮箱地址,自然只能给最后一个收件人发邮件。
移除pop()后出现"Invalid Email"的原因
移除.pop()后,emailAddress变成了邮箱数组,但存在两个核心问题:
- 范围选取错误:
sheet.getRange(2,2,sheet.getLastRow(),1)的第三个参数是整个表格的总行数,会导致从第2行开始取超出实际数据范围的行(比如表格实际有5行数据,这个范围会取到第6行的空行)。虽然.filter(String)能去掉空值,但如果表格里有格式不符合规范的邮箱内容,就会触发无效邮箱错误。 - 邮箱有效性未校验:
.filter(String)只能过滤空值,无法识别格式错误的邮箱(比如缺少@、域名不完整等),这类无效值会导致MailApp.sendEmail报错。
修复后的代码
function sendReminderEmailTest() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheet = ss.getSheetByName("Send_Email"); // 修正范围:从第2行开始,取实际有数据的行数(总行数-1,排除表头行) var lastRow = sheet.getLastRow(); var range = sheet.getRange(2, 2, lastRow - 1, 1); var emailAddresses = range.getValues() .flat() .filter(function(email) { // 增加邮箱格式校验,过滤无效邮箱 var emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return email && emailRegex.test(email); }); var html_link = "<a href='something.com'>Site Name</a>"; var html_body = "Good morning,<br><br>" + "This is just a reminder to check the " + html_link + " page to verify that today's attendance is up-to-date. <br>" + "Thank you, <br>" + "Management <br><br>" + "<em>This email is an automated notification. Please do not reply.</em>"; // 一次性发送给所有有效邮箱(转为逗号分隔字符串) if (emailAddresses.length > 0) { MailApp.sendEmail({ to: emailAddresses.join(','), subject: "Reminder", body: "", htmlBody: html_body, noReply: true }); } // 若需要给每个收件人单独发邮件,可替换为以下代码 // emailAddresses.forEach(function(email) { // MailApp.sendEmail({ // to: email, // subject: "Reminder", // body: "", // htmlBody: html_body, // noReply: true // }); // }); }
额外排查建议
- 检查表格B列,确认是否存在格式错误的邮箱(比如
test@.com、test.com这类不符合规范的内容)。 - 可在过滤函数中加入日志,排查无效邮箱:
.filter(function(email) { var isValid = email && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); if (!isValid && email) { console.log("无效邮箱:" + email); } return isValid; });
内容的提问来源于stack exchange,提问作者Codedabbler
相关产品推荐
相关产品推荐

