如何授权域内非管理员用户在Google Apps Script中运行Admin SDK代码
实现非管理员运行高权限Google Apps Script的方案
方案核心逻辑
- 现有代码调用了Admin Directory API,必须要有Google Workspace管理员权限才能调用,普通用户直接运行自然无权限
- 我们不需要给普通用户赋予管理员权限,只需要让代码以预先授权的管理员身份执行,操作权限和触发用户完全隔离即可
具体操作步骤
步骤1:管理员账号配置脚本基础环境
- 用具有Google Workspace超级管理员/组管理权限的账号打开对应的Google Sheet,进入脚本编辑器(扩展程序 -> Apps Script)
- 确认Admin Directory API已开启:点击编辑器左侧「服务」-> 找到「Admin Directory API」-> 添加,版本选择v1即可
- 替换脚本里的域名占位符:把
listAllGroups函数里的THEDOMAIN和YOURDOMAIN改成你司的实际域名
步骤2:把高权限逻辑封装为Web App(适配onEdit触发场景)
原有onEdit是简单触发器,只能以当前用户权限运行,且无法调用需要授权的API,因此需要改成通过Web App调用的模式:
第一步:新增Web App入口函数,粘贴到现有代码末尾
// Web App 入口函数,统一处理增删查请求,以部署者(管理员)权限运行 function doPost(e) { const params = JSON.parse(e.postData.contents); const action = params.action; try { if (action === 'add') { // 调用加人逻辑 const newMember = {email: params.userEmail, role: "MEMBER"}; AdminDirectory.Members.insert(newMember, params.groupId); // 更新表格数据 const groupData = SpreadsheetApp.getActive().getSheetByName('GroupAddress'); groupData.appendRow([params.userEmail, params.groupId]); return ContentService.createTextOutput(JSON.stringify({status: 'success'})).setMimeType(ContentService.MimeType.JSON); } else if (action === 'remove') { // 调用删人逻辑 AdminDirectory.Members.remove(params.groupId, params.userEmail); // 更新表格数据 const groupData = SpreadsheetApp.getActive().getSheetByName('GroupAddress'); const groupDataValues = groupData.getDataRange().getValues(); const resultArray = groupDataValues.filter(row => !(row[0] === params.userEmail && row[1] === params.groupId)); const start = 2; if (groupData.getLastRow() >= start) { groupData.deleteRows(start, groupData.getLastRow() - start + 1); } if (resultArray.length > 1) { groupData.getRange(2, 1, resultArray.length - 1, resultArray[0].length).setValues(resultArray.slice(1)); } return ContentService.createTextOutput(JSON.stringify({status: 'success'})).setMimeType(ContentService.MimeType.JSON); } else if (action === 'list') { // 调用列组逻辑 listAllGroups(); return ContentService.createTextOutput(JSON.stringify({status: 'success'})).setMimeType(ContentService.MimeType.JSON); } } catch (err) { return ContentService.createTextOutput(JSON.stringify({status: 'error', message: err.message})).setMimeType(ContentService.MimeType.JSON); } }
第二步:替换原有的onEdit触发逻辑
把原来的addUsertoGroup和deleteGroupMember函数替换为以下版本,不再直接调用Admin API,改为调用后续部署的Web App:
// 替换原有addUsertoGroup函数 function addUsertoGroup(e) { const sheet = e.source.getActiveSheet(); if (sheet.getName() !== 'AddUser') return; const userData = e.source.getSheetByName('AddUser'); const userEmail = userData.getRange(2, 1).getValue().trim(); const groupId = userData.getRange(2, 2).getValue().trim(); if (!userEmail || !groupId) return; // 这里替换为后续部署Web App得到的URL const WEB_APP_URL = "你的Web App部署链接"; const payload = JSON.stringify({ action: 'add', userEmail: userEmail, groupId: groupId }); const options = { method: 'POST', contentType: 'application/json', payload: payload, muteHttpExceptions: true }; UrlFetchApp.fetch(WEB_APP_URL, options); // 重置表单 const header = ['UserEmail', 'GroupID']; userData.clear(); userData.appendRow(header).setFrozenRows(1); } // 替换原有deleteGroupMember函数 function deleteGroupMember(e) { const sheet = e.source.getActiveSheet(); if (sheet.getName() !== 'RemoveUser') return; const removeUserData = e.source.getSheetByName('RemoveUser'); const userEmail = removeUserData.getRange(2, 1).getValue().trim(); const groupId = removeUserData.getRange(2, 2).getValue().trim(); if (!userEmail || !groupId) return; // 替换为你的Web App部署链接 const WEB_APP_URL = "你的Web App部署链接"; const payload = JSON.stringify({ action: 'remove', userEmail: userEmail, groupId: groupId }); const options = { method: 'POST', contentType: 'application/json', payload: payload, muteHttpExceptions: true }; UrlFetchApp.fetch(WEB_APP_URL, options); // 重置表单 const header = ['UserEmail', 'GroupID']; removeUserData.clear(); removeUserData.appendRow(header).setFrozenRows(1); }
第三步:部署Web App
- 脚本编辑器右上角点击「部署」->「新建部署」
- 点击设置图标(齿轮)选择「Web应用」
- 配置参数:
- 说明可随意填写,例如「组管理工具接口」
- 执行身份选择:我(即当前登录的管理员账号)
- 有权访问的用户选择:你司域名内的所有人
- 点击部署,完成权限授权后复制得到的Web App URL,替换上述两个函数里的
WEB_APP_URL变量
步骤3:配置定时同步触发器
listAllGroups函数不需要用户触发,直接用管理员账号添加可安装触发器即可:
- 脚本编辑器左侧点击「触发器」->「添加触发器」
- 选择要运行的函数:
listAllGroups - 选择事件源:「时间驱动」
- 按需求设置运行频率,例如每天凌晨运行一次
步骤4:表格权限配置
把Google Sheet的编辑权限开放给你司需要使用该工具的非管理员用户即可
注意事项
- Web App每次修改代码后都要重新部署新版本,否则修改不会生效
- 可在代码中添加额外权限校验,例如只允许指定用户组的人员调用,避免功能滥用
- 如果仅需要查看组列表,直接给普通用户开放GroupAddress工作表的只读权限即可
- 如果普通用户编辑表格后没有生效,可删除原有简单触发器,用管理员账号新增2个可安装的「编辑时」触发器,分别绑定
addUsertoGroup和deleteGroupMember函数即可
内容的提问来源于stack exchange,提问作者Riccardo
相关产品推荐
相关产品推荐

