如何让Google Apps Script仅在工作日运行?
问题分析与修复方案
核心问题
- 发送流程未做工作日校验:当前每日触发器直接运行
sendMyEmail,但该函数没有检查当天是否为工作日,导致周末也执行发送。你写的isBusinessDay函数仅在setTrigger中使用,但setTrigger并未被自动调用,完全没起到作用。 - 触发器删除逻辑失效:
delTrigger中判断触发器的处理函数为"myFunction",但实际触发的函数是sendMyEmail,所以这个函数根本删不掉任何触发器,可能导致重复触发。 - 触发器创建逻辑不完整:
setTrigger只创建当天的一次性触发器,没有和发送流程联动,无法自动生成下一个工作日的触发任务。
具体修复步骤
1. 修正delTrigger函数,确保能删除目标触发器
把判断条件改为匹配实际触发函数sendMyEmail:
function delTrigger() { var triggers = ScriptApp.getProjectTriggers(); for(var i=0; i < triggers.length; i++) { if (triggers[i].getHandlerFunction() == "sendMyEmail") { ScriptApp.deleteTrigger(triggers[i]); } } }
2. 在sendMyEmail开头添加工作日判断
这样即使触发器在周末运行,也会直接退出,不发送邮件:
function sendMyEmail() { var today = new Date(); // 非工作日直接结束流程 if (!isBusinessDay(today)) { delTrigger(); createNextBusinessDayTrigger(); return; } // 原发送邮件逻辑保留 delTrigger(); var doc = DocumentApp.getActiveDocument(); var nextBusinessDay = getNextBusinessDay(new Date()) var month = ("0"+(nextBusinessDay.getMonth()+1)).slice(-2) var day = ("0"+(nextBusinessDay.getDate())).slice(-2) // 替换getYear()为getFullYear(),获取完整4位年份 var formattedDate = nextBusinessDay.getFullYear() + "." + month + "." + day; var subject = " --document name-- " + formattedDate; var emailTo = " --receipient emails-- "; var message = "Please see today's agenda attached and in redline."; var docFile = getBlobViaURL_(doc.getId(), MimeType.MICROSOFT_WORD); docFile.setName(" --document name--" + formattedDate + ".docx"); var mailObj = {attachments:[docFile]}; MailApp.sendEmail(emailTo, subject, message, mailObj); // 自动创建下一个工作日的触发器 createNextBusinessDayTrigger(); }
3. 添加自动创建下一个工作日触发器的函数
替代原setTrigger,实现发送完成后自动生成下一次任务:
function createNextBusinessDayTrigger() { var nextDay = getNextBusinessDay(new Date()); // 设置触发时间为21:00 nextDay.setHours(21); nextDay.setMinutes(0); nextDay.setSeconds(0); // 创建一次性触发器 ScriptApp.newTrigger('sendMyEmail').timeBased().at(nextDay).create(); }
4. 优化getNextBusinessDay函数可读性
复用isBusinessDay函数,让逻辑更清晰:
function getNextBusinessDay(date) { date = new Date(+date); do { date.setDate(date.getDate() + 1); } while (!isBusinessDay(date)); return date; }
初始化操作
- 删除所有旧的重复触发器(避免冲突)
- 手动运行一次
createNextBusinessDayTrigger,它会自动创建第一个工作日21点的触发器,之后每次发送邮件后会自动生成下一个工作日的触发任务,无需手动干预。
内容的提问来源于stack exchange,提问作者Sarah S
相关产品推荐
相关产品推荐

