使用Python调用Google Apps Script函数遇404:请求实体未找到
问题描述
我在Cloud Shell Editor中尝试用Python调用Google Apps Script(GAS)函数时碰到了问题。查过Stack Overflow后试过使用可执行API,但该方式强制要求OAuth2.0,我始终配置不成功(授权后出现403错误)。目前我的代码能列出GAS里的函数,但调用函数时返回404错误。
代码示例
from __future__ import print_function # bot.py import os import pickle import os.path import google.auth from google.oauth2 import service_account from googleapiclient.discovery import build # 替换为你的服务账号JSON文件路径 service_account_json = 'service.json' # 替换为你的Google Apps Script项目ID script_id = 'UNIQUE-SCRIPTID' # 定义Google Apps Script API所需的权限范围 SCOPES = [ 'https://www.googleapis.com/auth/script.projects', 'https://www.googleapis.com/auth/script.scriptapp' ] def authorize_script_api(service_account_json): # 从JSON文件加载服务账号凭证 creds = google.oauth2.service_account.Credentials.from_service_account_file( service_account_json, scopes=SCOPES) return creds def list_functions(script_id, credentials): try: # 构建Google Apps Script API服务 service = build('script', 'v1', credentials=credentials) # 获取指定GAS项目的内容 content = service.projects().getContent(scriptId=script_id).execute() if 'files' in content: for file in content['files']: if 'functionSet' in file: function_set = file['functionSet'] if 'values' in function_set: for func in function_set['values']: if 'name' in func: print(func['name']) except Exception as e: print(f"发生错误: {e}") def run_function(script_id, credentials, function_name): try: # 构建Google Apps Script API服务 service = build('script', 'v1', credentials=credentials) # 创建调用指定函数的请求 request = { "function": function_name } # 执行GAS项目中的函数 response = service.scripts().run(scriptId=script_id, body=request).execute() print(response) except Exception as e: print(f"发生错误: {e}") if __name__ == '__main__': # 授权Script API credentials = authorize_script_api(service_account_json) # 列出GAS项目中的函数 list_functions(script_id, credentials) # 指定要调用的函数名 function_name = "helloworld" # 调用GAS项目中的指定函数 run_function(script_id, credentials, function_name)
运行输出
helloworld setTrigger scheduledTrigger deleteTriggers 发生错误: <HttpError 404 when requesting https://script.googleapis.com/v1/scripts/UNIQUE-SCRIPTID:run?alt=json returned "Requested entity was not found.". Details: "Requested entity was not found.">
content返回结果
{'scriptId': 'UNIQUE-SCRIPTID', 'files': [{'name': 'appsscript', 'type': 'JSON', 'source': '{ "timeZone": "America/Los_Angeles", "dependencies": {}, "exceptionLogging": "STACKDRIVER", "runtimeVersion": "V8", "executionApi": { "access": "MYSELF" }, "oauthScopes": [ "https://www.googleapis.com/auth/drive.readonly", "https://www.googleapis.com/auth/drive", "https://www.googleapis.com/auth/spreadsheets", "https://www.googleapis.com/auth/script.external_request", "https://www.googleapis.com/auth/script.scriptapp" ] }', 'lastModifyUser': {'photoUrl': 'redacted'}, 'createTime': '2022-09-06T01:19:20.404Z', 'updateTime': '2023-10-09T07:08:55.871Z', 'functionSet': {}}, {'name': 'Code', 'type': 'SERVER_JS', 'source': 'function helloworld() { console.log("hello!"); } function setTrigger() { deleteTriggers(); var times = [[19,15]]; // 19:15 times.forEach(t_el => scheduledTrigger(t_el[0],t_el[1])); } function scheduledTrigger(hours,minutes) { var today_D = new Date(); var year = today_D.getFullYear(); var month = today_D.getMonth(); var day = today_D.getDate(); pars = [year,month,day,hours,minutes]; var scheduled_D = new Date(...pars); var hours_remain=Math.abs(scheduled_D - today_D) / 36e5; ScriptApp.newTrigger("Announcement") .timeBased() .after(hours_remain * 60 *60 * 1000) .create() } function deleteTriggers() { var triggers = ScriptApp.getProjectTriggers(); for (var i = 0; i < triggers.length; i++) { if ( triggers[i].getHandlerFunction() == "Announcement") { ScriptApp.deleteTrigger(triggers[i]); } } } }', 'lastModifyUser': {'photoUrl': 'redacted'}, 'createTime': '2022-09-06T01:19:20.397Z', 'updateTime': '2023-10-09T07:08:55.871Z', 'functionSet': {'values': [{'name': 'helloworld'}, {'name': 'setTrigger'}, {'name': 'scheduledTrigger', 'parameters': ['hours', 'minutes']}, {'name': 'deleteTriggers'}]}}]}
解决方案
核心问题分析
出现404错误的关键原因:
- 执行API权限限制:从
content返回结果可见,executionApi.access设置为MYSELF,这意味着仅项目所有者能通过执行API调用函数,服务账号不在允许范围内。 - 未完成可执行API部署:你的GAS项目可能未部署为可执行API,或者部署版本未正确关联。
解决步骤
调整执行API访问权限
打开GAS编辑器,点击右上角齿轮图标进入「项目设置」,找到「执行API访问权限」选项,将其改为「任何人,甚至匿名」或「组织内任何人」(根据需求选择,确保服务账号被包含在允许范围内)。部署GAS项目为可执行API
- 在GAS编辑器中,点击右上角「部署」→「新部署」。
- 点击「类型」选择「API可执行文件」。
- 设置部署描述,选择版本(建议选「新版本」)。
- 点击「部署」,完成授权后即可完成部署。
添加服务账号为项目协作者
在GAS编辑器中点击「共享」按钮,输入服务账号邮箱,给予编辑或查看权限,确保服务账号能访问该项目。验证修改
重新运行Python代码,即可正常调用helloworld函数。
内容的提问来源于stack exchange,提问作者user3245228
相关产品推荐
相关产品推荐

