Google Sheets脚本问题:仅以当前操作用户身份发送邮件
问题根源
每个授权用户都创建了独立的3个onEdit可安装触发器,导致每次编辑操作时,所有用户的触发器都会执行对应的邮件发送函数,因此所有授权用户都会发送邮件。同时,默认的可安装触发器会以创建者身份运行,无法确保邮件从操作用户的邮箱发出。
修复步骤
1. 清理现有重复触发器
所有授权用户先运行以下函数,删除自己创建的所有onEdit触发器:
function deleteAllMyOnEditTriggers() { var ss = SpreadsheetApp.getActive(); var triggers = ScriptApp.getUserTriggers(ss); triggers.forEach(function(trigger) { if (trigger.getEventType() === ScriptApp.EventType.ON_EDIT) { ScriptApp.deleteTrigger(trigger); } }); SpreadsheetApp.getUi().alert("已删除您创建的所有onEdit触发器"); }
2. 修改触发器创建逻辑,统一管理
替换原createSpreadsheetEditTrigger函数,只创建一个主触发器,并设置以编辑操作的用户身份运行:
function createSpreadsheetEditTrigger() { var ss = SpreadsheetApp.getActive(); // 先清理当前用户已有的onEdit触发器 var triggers = ScriptApp.getUserTriggers(ss); triggers.forEach(function(trigger) { if (trigger.getEventType() === ScriptApp.EventType.ON_EDIT) { ScriptApp.deleteTrigger(trigger); } }); // 创建主触发器,以编辑用户身份执行 ScriptApp.newTrigger('handleEdit') .forSpreadsheet(ss) .onEdit() .runAs(ScriptApp.RunAsUser.CURRENT_USER) .create(); SpreadsheetApp.getUi().alert("触发器创建成功"); }
只需要任意一个有权限的用户运行此函数即可,不需要所有用户都创建。
3. 创建主处理函数
新增handleEdit函数,统一处理编辑事件,根据下拉选项调用对应邮件函数:
function handleEdit(e) { // 仅处理第22列的下拉操作 if (e.range.getColumn() !== 22) return; // 根据选中值分发到对应函数 switch(e.value) { case "Approved": SendEmail(e); break; case "Denied": Denied(e); // 保留您原有的Denied函数逻辑 break; case "Pending": Pending(e); // 保留您原有的Pending函数逻辑 break; default: return; } }
4. 优化SendEmail函数
移除无效代码,确保逻辑清晰:
function SendEmail(e) { var EMAIL_SENT = 'EMAIL_SENT'; // 检查是否已发送过邮件 var emailSent = e.range.offset(0,5).getValue(); if (emailSent === EMAIL_SENT) return; // 获取表格数据 var dt = e.range.offset(0,-21).getValue(); var ldc = e.range.offset(0,-19).getValue(); var status = e.range.offset(0,0).getValue(); var notes = e.range.offset(0,-1).getValue(); var cost = e.range.offset(0,-5).getValue(); var start = e.range.offset(0,-4).getValue(); var end = e.range.offset(0,-3).getValue(); var Iemail = e.range.offset(0,-20).getValue(); var name = e.range.offset(0,-18).getValue(); var issue = e.range.offset(0,-16).getValue(); var userName = Session.getActiveUser().getUsername(); // 发送邮件(以操作用户的邮箱发出) var subject = "Exception Bill Pre-Approval Status - Approved"; var body = "Hello," + "\n\r" + "The following request has been Approved:" + "\n\n" + "Submitted on: " + dt + "\n" + "Submitted by: " + name + "\n" + "LDC: " + ldc + "\n" + "Service Needed: " + issue + "\n" + "Estimated Cost:" + cost + "\n" + "Start Date: " + start + "\n" + "End Date: " + end + "\n" + "Notes: " + notes + "\n\n" + "Status: " + status + "\n\r" + "\n\r" + "Thanks," + "\n" + userName; GmailApp.sendEmail(Iemail, subject, body); // 标记邮件已发送 e.range.offset(0,5).setValue(EMAIL_SENT); SpreadsheetApp.flush(); }
关键说明
runAs(ScriptApp.RunAsUser.CURRENT_USER):确保触发器以执行编辑操作的用户身份运行,邮件会从该用户的邮箱发出,且每次编辑仅触发一次执行。- 统一触发器管理:避免多个用户创建重复触发器,从根源解决全员发送邮件的问题。
内容的提问来源于stack exchange,提问作者kekigal
相关产品推荐
相关产品推荐

