You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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,或者部署版本未正确关联。

解决步骤

  1. 调整执行API访问权限
    打开GAS编辑器,点击右上角齿轮图标进入「项目设置」,找到「执行API访问权限」选项,将其改为「任何人,甚至匿名」或「组织内任何人」(根据需求选择,确保服务账号被包含在允许范围内)。

  2. 部署GAS项目为可执行API

    • 在GAS编辑器中,点击右上角「部署」→「新部署」。
    • 点击「类型」选择「API可执行文件」。
    • 设置部署描述,选择版本(建议选「新版本」)。
    • 点击「部署」,完成授权后即可完成部署。
  3. 添加服务账号为项目协作者
    在GAS编辑器中点击「共享」按钮,输入服务账号邮箱,给予编辑或查看权限,确保服务账号能访问该项目。

  4. 验证修改
    重新运行Python代码,即可正常调用helloworld函数。


内容的提问来源于stack exchange,提问作者user3245228

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 02:17:04