Google Scripts 如何获取活跃编辑者姓名/邮箱及权限问题解决方案
Google Sheets 编辑协作者身份识别问题解决方案
核心问题根源
- 直接命名为
onEdit的简单触发器属于Google Apps Script的受限触发器,默认无高级授权:跨域普通Gmail协作者触发时,Session.getActiveUser()、事件对象e.user都会返回空值,仅同Google Workspace组织域用户可在受限范围内获取信息。 - 你使用保护范围的方法失效,本质是简单触发器运行时的身份为触发编辑的协作者本人,协作者默认无修改表格保护范围的权限,
removeEditors()会直接抛出权限错误,无法执行。 - 额外注意:推送到Discord需要调用
UrlFetchApp,该接口属于高级授权范围,简单触发器完全无法调用,协作者触发时连通知推送都无法执行。
可行解决方案
场景1:所有协作者属于同一Google Workspace组织域
不需要沿用你之前的保护范围逻辑,直接调整触发器配置即可:
- 把原绑定的
onEdit函数改名为非保留名(例如onEditNotification),避免被识别为简单触发器。 - 手动部署可安装编辑触发器,执行身份二选一:
- 以用户身份执行:每个协作者首次触发编辑时需给脚本授权一次,授权后
Session.getActiveUser()可正常返回所有协作者的邮箱。 - 以所有者身份执行:无需协作者额外授权,同域用户触发时
Session.getActiveUser()、事件对象e.user均可正常返回身份,脚本运行时使用你的权限,不会出现权限不足问题。
- 以用户身份执行:每个协作者首次触发编辑时需给脚本授权一次,授权后
- 优化后的身份获取脚本示例(无需额外操作保护范围):
function onEditNotification(e) { // 加锁防止并发编辑冲突 const lock = LockService.getScriptLock(); lock.waitLock(30000); try { // 仅触发指定列的编辑事件,替换为你需要监听的列号 const editColumn = e.range.getColumn(); if (editColumn !== 你的指定列号) return; // 直接获取触发用户邮箱 const userEmail = Session.getActiveUser().getEmail(); const sheetName = e.range.getSheet().getName(); // 后续推送Discord逻辑正常编写即可 } catch (error) { console.error(error); } finally { lock.releaseLock(); } }
场景2:存在跨域普通Gmail协作者(Google隐私政策限制无法直接获取邮箱)
Google出于隐私保护,不允许脚本在以所有者身份运行时获取跨域普通用户的邮箱信息,可通过以下两种方式变通:
- 方案A:修改身份识别逻辑,要求协作者在表格固定单元格填写自己的唯一标识(例如Discord用户名、自定义ID),编辑触发时直接读取该标识代替邮箱作为身份凭证,推送通知时使用该标识即可,无需调用需要权限的身份获取接口。
- 方案B:如果你之前的保护范围逻辑是唯一可行路径,可将触发器改为以所有者身份执行的可安装触发器,让脚本运行时拥有你的全部权限,直接解决协作者无权限调用
removeEditors的问题,同时加上LockService防止并发操作保护范围的冲突:
function getCurrentUserEmail() { const lock = LockService.getScriptLock(); lock.waitLock(30000); try { const ss = SpreadsheetApp.getActiveSpreadsheet(); // 临时创建保护范围 const protection = ss.getRange('A1').protect(); // 移除所有原有编辑器,仅保留所有者 protection.removeEditors(protection.getEditors()); // 同域场景下可直接通过Session获取当前用户,跨域场景下需配合固定标识使用 const currentUser = Session.getActiveUser().getEmail(); // 临时删除保护范围,不影响正常使用 protection.remove(); return currentUser; } catch (err) { console.error(err); return null; } finally { lock.releaseLock(); } }
注意事项
- 可安装触发器需手动在Apps Script的「触发器」页面添加,不要依赖自动触发的简单
onEdit。 - 如果部署为以所有者身份执行的触发器,所有协作者的编辑事件都会通过你的权限运行,注意限制脚本的操作范围,避免误改表格内容。
内容的提问来源于stack exchange,提问作者An29
相关产品推荐
相关产品推荐

