修改Google Apps Script发件人为触发用户及解决重复发信求助
谷歌表格Apps Script勾选复选框发信重复问题解决方案
问题根因
你目前遇到的重复发信问题,核心是两名用户各自创建的onEdit可安装触发器会在表格被编辑时同时触发,两个脚本并发读取行数据时,emailDupe字段还没被先执行的脚本写入已发送标记,因此两个脚本都满足发送条件,最终产生两封邮件。原有代码的判断逻辑无法覆盖并发场景,同时还存在一处语法错误:else if判断中column = 17是赋值操作,需改为等值判断column == 17。
解决方案
步骤1:清理现有触发器
两名用户分别进入当前表格关联的Apps Script后台,打开「触发器」页面,删除所有和onCheckboxEdit函数绑定的可安装触发器。
步骤2:替换为优化后代码
在Apps Script编辑器中替换原有代码,新增并发锁机制避免同时执行,同时修复语法问题:
function onCheckboxEdit(e) { // 新增并发锁,防止多触发器同时执行 const lock = LockService.getDocumentLock(); try { // 最多等待3秒获取锁,避免超时 lock.waitLock(3000); } catch (e) { // 没拿到锁直接退出,说明已经有其他实例在处理 return; } try { var source = e.source; var sheet = source.getActiveSheet(); var range = e.range; var row = range.getRow(); var column = range.getColumn(); console.log("column:: ", column); // 加锁后再读取最新的行数据,避免读取到旧值 var targetRange = sheet.getRange(row, 13, 1, 7); var targetValues = targetRange.getValues(); console.log("targetRange:: ", targetValues); var recipient = targetValues[0][2]; var checkboxValue = targetValues[0][4]; var body = targetValues[0][1]; var Replacement = targetValues[0][0]; var subject = "Replacement for " + Replacement; var ccmail = targetValues[0][3]; var Rname = targetValues[0][5]; var EMAIL_SENT = 'E-mail sent'; var emailDupe = targetValues[0][6]; if(emailDupe !== EMAIL_SENT && checkboxValue === true) { console.log("checkbox marked true"); GmailApp.sendEmail(recipient, subject, body, { cc: ccmail, name: Rname }); // 发送成功后立刻写入已发送标记 sheet.getRange(row, 19).setValue(EMAIL_SENT); } else if (column === 17 && checkboxValue === false) { console.log("checkbox marked false"); // 如果取消勾选,可以清空已发送标记方便重新触发 sheet.getRange(row, 19).setValue(""); } else { console.log("No clue"); } } catch (err) { console.error("执行出错:", err); } finally { // 最后释放锁,避免死锁 lock.releaseLock(); } }
步骤3:重新配置触发器与部署
- 保持原有Apps Script部署的运行身份为「访问Web应用的用户」
- 两名用户各自重新创建1个可安装触发器:触发事件类型选择「电子表格」,事件类型选择「编辑时」,绑定函数选
onCheckboxEdit
逻辑说明
新增的文档锁会确保同一时间只有一个触发器实例能处理同一次编辑操作:第一个拿到锁的实例完成发信、写入已发送标记后释放锁,后拿到锁的实例读取数据时已经能识别到已发送标记,会直接跳过发信逻辑,彻底解决重复发信问题,同时保留「谁触发操作就用谁的邮箱发信」的需求。
内容的提问来源于stack exchange,提问作者josh_97
相关产品推荐
相关产品推荐

