请求优化Google Apps Script以自动更新Drive文件夹共享权限
Google Drive文件夹权限自动化更新脚本
完整修正代码
function updateFolderPermissions() { // 配置参数,根据实际情况修改 const FOLDER_ID = '你的文件夹ID'; const EXCLUDED_EMAILS = ['例外邮箱1@example.com', '例外邮箱2@example.com']; const LOG_SHEET_NAME = 'Permission_Change_Log'; try { // 获取目标文件夹和权限配置工作表 const folder = DriveApp.getFolderById(FOLDER_ID); const ss = SpreadsheetApp.getActiveSpreadsheet(); const configSheet = ss.getSheetByName('Sharing_Opt'); if (!configSheet) throw new Error('未找到名为「Sharing_Opt」的工作表'); // 读取权限配置并构建权限映射(B列editor覆盖A列viewer) const permissionMap = {}; const data = configSheet.getDataRange().getValues(); // 先处理A列viewer data.forEach(row => { const viewerEmail = row[0]?.toString().trim(); if (viewerEmail && !permissionMap[viewerEmail]) { permissionMap[viewerEmail] = DriveApp.PermissionRole.VIEWER; } }); // 再处理B列editor,覆盖已有映射 data.forEach(row => { const editorEmail = row[1]?.toString().trim(); if (editorEmail) { permissionMap[editorEmail] = DriveApp.PermissionRole.EDITOR; } }); // 获取当前文件夹的用户权限(排除所有者和例外邮箱) const currentPermissions = folder.getPermissions().filter(perm => perm.getType() === DriveApp.PermissionType.USER && !perm.isOwner() && !EXCLUDED_EMAILS.includes(perm.getEmail()) ); // 处理现有权限:调整或移除 const logEntries = []; const existingEmails = new Set(); currentPermissions.forEach(perm => { const email = perm.getEmail(); existingEmails.add(email); const currentRole = perm.getRole(); const targetRole = permissionMap[email]; if (!targetRole) { // 不在权限列表中,移除权限 perm.remove(); logEntries.push([ new Date(), '移除权限', email, currentRole, '无' ]); } else if (currentRole !== targetRole) { // 权限不符,调整权限 perm.setRole(targetRole, { sendNotificationEmails: false }); logEntries.push([ new Date(), '调整权限', email, currentRole, targetRole ]); } // 权限匹配时不做操作,跳过日志 }); // 添加权限列表中存在但当前未共享的用户 Object.entries(permissionMap).forEach(([email, targetRole]) => { if (!existingEmails.has(email) && !EXCLUDED_EMAILS.includes(email)) { folder.addPermission(email, targetRole, { sendNotificationEmails: false }); logEntries.push([ new Date(), '添加权限', email, '无', targetRole ]); } }); // 记录变更日志到工作表 let logSheet = ss.getSheetByName(LOG_SHEET_NAME); if (!logSheet) { logSheet = ss.insertSheet(LOG_SHEET_NAME); // 写入表头 logSheet.appendRow(['日期时间', '操作类型', '用户邮箱', '原权限', '目标权限']); // 设置表头格式(可选) const headerRange = logSheet.getRange(1, 1, 1, 5); headerRange.setFontWeight('bold'); } // 批量写入日志 if (logEntries.length > 0) { logSheet.getRange(logSheet.getLastRow() + 1, 1, logEntries.length, 5).setValues(logEntries); } // 控制台输出日志数量 console.log(`权限更新完成,共记录 ${logEntries.length} 条变更`); } catch (error) { console.error('脚本执行失败:', error.message); // 将错误写入日志 const ss = SpreadsheetApp.getActiveSpreadsheet(); let logSheet = ss.getSheetByName(LOG_SHEET_NAME) || ss.insertSheet(LOG_SHEET_NAME); logSheet.appendRow([new Date(), '脚本错误', '', '', error.message]); } }
关键需求匹配说明
- 权限优先级处理:先读取A列设置viewer权限,再读取B列设置editor权限,自动覆盖重复邮箱的权限,满足「同时在两列以editor为准」的要求。
- 例外邮箱保护:在权限处理时直接跳过
EXCLUDED_EMAILS数组中的邮箱,始终保留其原有editor权限,不受脚本修改影响。 - 权限错误修正:遍历现有权限时,对比目标权限与当前权限,仅在不一致时调整(editor降viewer、viewer升editor),避免无意义操作。
- 空白单元格跳过:读取数据时通过
trim()和非空判断过滤空白单元格,不会处理无效邮箱。 - 增量更新与日志记录:仅处理权限不符的用户,不全删重加;日志记录包含日期时间、操作类型、权限变化,写入指定工作表。
- 无共享通知:调用
setRole和addPermission时传入{ sendNotificationEmails: false },避免发送系统共享邮件。
使用说明
- 将代码中的
FOLDER_ID替换为目标Drive文件夹的ID,EXCLUDED_EMAILS替换为需要保留权限的例外邮箱。 - 确保当前Google Sheets文档中存在名为「Sharing_Opt」的工作表,A列存viewer邮箱,B列存editor邮箱。
- 运行脚本时,需授权Drive和Spreadsheet的访问权限。
- 脚本会自动创建「Permission_Change_Log」工作表记录所有变更。
内容的提问来源于stack exchange,提问作者haephaistoss
相关产品推荐
相关产品推荐

