GAS技术问题:按指定日期时间自动发送表格邮件失败排查
Google Apps Script 自动提醒邮件失效问题排查与修复
问题背景
Google表格包含以下列:email、name、link、date、time、file、subject、title,示例数据如下:
| name | link | date | time | file | subject | title | |
|---|---|---|---|---|---|---|---|
| a.d@abc.com | Sam Z | abc | 18.01.23 | 14:41:00 | def | abc | Hello World |
已部署以下Google Apps Script为插件,并设置每分钟运行的触发器,期望在表格指定的日期时间自动发送提醒邮件,但功能失效,已确认表格关联正确。
原代码:
function sendReminderEmails() { var spreadsheet = SpreadsheetApp.openById("1h570Eb4IqAaAHciQzz0U9oY_uqGo9UDzpWtth78NkCY").getSheetByName("test"); var data = spreadsheet.getDataRange().getValues(); // console.log(data); for (var i = 1; i < data.length; i++) { var email = data[i][0]; var name = data[i][1]; var link = data[i][2]; var date = data[i][3]; var time = data[i][4]; var file = data[i][5]; var now = new Date(); if (now.toLocaleDateString() == date && now.toLocaleTimeString() == time) { MailApp.sendEmail(email, "Reminder: " + file, "Hello " + name + ",\n\nThis is a reminder about the " + file + " at " + link + " on " + date + " at " + time + "."); } } }
失效原因分析
日期时间字符串匹配逻辑不可靠
toLocaleDateString()的输出格式依赖脚本运行的区域设置,比如可能输出1/18/2023或18/01/2023,和表格中的18.01.23格式完全不匹配,导致条件永远不成立。toLocaleTimeString()会包含秒数、时区或AM/PM标识(比如2:41:00 PM),和表格中的14:41:00格式不一致;同时触发器每分钟运行一次,很难刚好在精确到秒的时间点触发,直接错过匹配窗口。
未处理日期时间的类型转换
表格中的date和time是字符串格式,直接和Date对象的本地化字符串比较,存在格式、精度不匹配的问题,应该将字符串转换为Date对象后再进行范围比较。
修复方案
修正后的代码
function sendReminderEmails() { var spreadsheet = SpreadsheetApp.openById("1h570Eb4IqAaAHciQzz0U9oY_uqGo9UDzpWtth78NkCY").getSheetByName("test"); var data = spreadsheet.getDataRange().getValues(); var now = new Date(); // 设置允许的误差范围(分钟),适配触发器的运行间隔 var timeTolerance = 1; var toleranceMs = timeTolerance * 60 * 1000; for (var i = 1; i < data.length; i++) { var email = data[i][0]; var name = data[i][1]; var link = data[i][2]; var dateStr = data[i][3]; var timeStr = data[i][4]; var file = data[i][5]; // 将表格中的日期(DD.MM.YY)和时间转换为Date对象 var dateParts = dateStr.split("."); // 注意月份是0-11,所以要减1 var reminderDate = new Date(2000 + parseInt(dateParts[2]), parseInt(dateParts[1]) - 1, parseInt(dateParts[0])); // 添加时间 var timeParts = timeStr.split(":"); reminderDate.setHours(parseInt(timeParts[0]), parseInt(timeParts[1]), parseInt(timeParts[2])); // 计算当前时间和提醒时间的时间差(毫秒) var timeDiff = Math.abs(now.getTime() - reminderDate.getTime()); // 检查是否在误差范围内,且未标记为已发送(可添加已发送列避免重复发送) if (timeDiff <= toleranceMs) { // 可选:添加已发送标记列(比如第9列,索引8),避免重复发送 // spreadsheet.getRange(i+1, 9).setValue("已发送"); MailApp.sendEmail( email, "Reminder: " + file, "Hello " + name + ",\n\nThis is a reminder about the " + file + " at " + link + " on " + dateStr + " at " + timeStr + "." ); } } }
关键优化点
- 将表格中的日期字符串(
DD.MM.YY)转换为Date对象,彻底避免格式不匹配问题。 - 使用1分钟时间误差范围代替精确匹配,适配触发器的运行间隔,不会因为触发延迟错过提醒。
- 可选添加“已发送”标记列,避免重复发送邮件。
额外建议
- 检查表格中的日期时间格式是否统一,确保都是
DD.MM.YY和HH:MM:SS格式。 - 测试脚本时,可以手动修改表格中的提醒时间为当前时间1分钟内,触发脚本验证是否发送邮件。
- 查看脚本的执行日志(Google Apps Script编辑器→查看→执行日志),排查是否有报错信息。
内容的提问来源于stack exchange,提问作者Anthony Admin
相关产品推荐
相关产品推荐

