如何在Google Apps Script中实现服务账户访问受限文件夹数据
解决方案
错误原因
ServiceAccountCredentials 不是Google Apps Script(GAS)的内置对象,它属于OAuth2 for Apps Script第三方库,未安装该库就会触发ReferenceError。
步骤1:安装OAuth2库
在GAS编辑器中完成以下操作:
- 点击顶部菜单「扩展程序」→「Apps Script」(已在编辑器中可跳过)
- 点击左侧「库」图标(📚)
- 在「添加库」输入框中填入库ID:
1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF - 选择最新版本号,点击「添加」
步骤2:配置服务账户权限
将服务账户的邮箱地址添加到受限文件夹/源文件的共享列表中,授予「编辑」权限(确保服务账户能正常访问目标资源)。
步骤3:修正脚本代码
替换原代码为以下实现,核心逻辑是通过OAuth2库创建服务账户授权,调用Sheets API拉取源数据(规避当前用户权限不足的问题):
function myFunction() { // 初始化服务账户授权服务 const service = getServiceAccountService(); if (!service.hasAccess()) { throw new Error('服务账户授权失败:' + service.getLastError()); } // 通过Sheets API拉取源文件数据 const sourceSpreadsheetId = '替换为源文件的ID'; // 直接使用源文件ID,无需通过DriveApp访问 const range = 'source!A:ZZ'; // 源数据所在工作表及范围 const url = `https://sheets.googleapis.com/v4/spreadsheets/${sourceSpreadsheetId}/values/${range}`; const response = UrlFetchApp.fetch(url, { headers: { 'Authorization': `Bearer ${service.getAccessToken()}` } }); const data1 = JSON.parse(response.getContentText()).values; if (!data1) { Logger.log('源文件无数据'); return; } // 过滤数据(保留原业务逻辑) const filteredData1 = data1.filter(row => { const nameColIndex = row[25]; // 对应第26列(索引从0开始) return nameColIndex === "Output"; }); // 写入当前文件的目标工作表 const existingSheet1 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Dest"); if (existingSheet1) { // 清空目标区域原有数据 existingSheet1.getRange(4, 1, existingSheet1.getLastRow(), existingSheet1.getLastColumn()).clearContent(); // 写入过滤后的数据 if (filteredData1.length > 0) { existingSheet1.getRange(4, 1, filteredData1.length, filteredData1[0].length).setValues(filteredData1); } } } // 创建服务账户OAuth2授权服务 function getServiceAccountService() { return OAuth2.createService('ServiceAccount') .setTokenUrl('https://oauth2.googleapis.com/token') .setPrivateKey('替换为你的服务账户私钥(需完整保留首尾标识及换行符:-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----)') .setIssuer('替换为服务账户邮箱') .setScope('https://www.googleapis.com/auth/sheets.readonly'); // 仅需读取权限,按需可改为auth/sheets }
关键说明
- 规避用户权限限制:
DriveApp/SpreadsheetApp.open使用当前运行脚本的用户权限,而用户本身无受限文件夹权限,因此必须通过服务账户授权调用API访问资源。 - 私钥格式要求:确保私钥完整复制,包括首尾的标识字符串和中间的换行符,否则会导致授权失败。
- 最小权限原则:服务账户的scope仅设置为
sheets.readonly即可(无需修改源文件时),降低权限风险。
内容的提问来源于stack exchange,提问作者TheExcelMan
相关产品推荐
相关产品推荐

