python-3.x - 未找到 Google Apps 脚本函数:function_name
问题描述
我正在尝试使用 google-apps-script RESTful API 运行脚本。执行脚本时,我总是收到一条错误消息Script function not found: function_name
。我哪里错了?
这是一个新项目,我需要从 Django 应用程序运行脚本。因此,一旦用户通过身份验证(使用 Google OAuth2),我就会尝试调用脚本运行函数。就在尝试运行脚本之前,我正在更新运行没有任何问题的脚本。
我从 https://developers.google.com/api-client-library/python/auth/web-app获取了烧瓶应用程序并将其转换为 DRF
# Default imports
import base64
import google.oauth2.credentials
import google_auth_oauthlib.flow
import googleapiclient.discovery
from django.shortcuts import redirect, reverse
from rest_framework import generics, status
from rest_framework.response import Response
CLIENT_SECRETS_FILE = "credentials.json"
SCOPES = [
"https://www.googleapis.com/auth/script.projects",
"https://www.googleapis.com/auth/script.deployments",
"https://www.googleapis.com/auth/forms",
"https://www.googleapis.com/auth/forms.currentonly",
"https://www.googleapis.com/auth/script.processes",
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/script.scriptapp",
"https://www.googleapis.com/auth/drive",
]
def get_form_template(param1, param2):
# Google Script code template being generated
# using param1 and param2
return (
"""
// executionScript function
function executionScript() {
var param1 = '""" + param1 + """'
var param2 = '""" + param2 + """'
Logger.log("param1 is : " + param1)
Logger.log("param2 is : " + param2)
// And some extra functionality
// that is why all the extra scopes in
// the manifest
}
""".strip()
)
def get_manifest():
return """
{
"timeZone": "Asia/Kolkata",
"exceptionLogging": "STACKDRIVER",
"oauthScopes": [
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/script.scriptapp",
"https://www.googleapis.com/auth/script.projects",
"https://www.googleapis.com/auth/script.deployments",
"https://www.googleapis.com/auth/forms",
"https://www.googleapis.com/auth/forms.currentonly",
"https://www.googleapis.com/auth/script.processes",
"https://www.googleapis.com/auth/drive"
]
}
""".strip()
class TestAPIPage(generics.ListAPIView):
def get(self, request, *args, **kwargs):
#################################################################
# Code to make sure param1 and param2 are not null or undefined
#################################################################
param1 = self.request.query_params.get("param1")
param2 = self.request.query_params.get("param2")
if "credentials" not in self.request.session:
return redirect(
reverse("oauth2_google:authorize")
+ "?param1={}¶m2={}".format(param1, param2)
)
# Load credentials from the session.
credentials = google.oauth2.credentials.Credentials(
**self.request.session["credentials"]
)
# Save credentials back to session in case access token was refreshed.
# ACTION ITEM: In a production app, you likely want to save these
# credentials in a persistent database instead.
self.request.session["credentials"] = credentials_to_dict(credentials)
service = googleapiclient.discovery.build(
"script", "v1", credentials=credentials
)
SCRIPT_ID = " ################## SCRIPT_ID ################## "
# Checking if project exists
project_get_response = service.projects().get(scriptId=SCRIPT_ID).execute()
print("Project get response : ", project_get_response)
update_request = {
"files": [
{
"name": "Code",
"type": "SERVER_JS",
"source": get_form_template(param1, param2),
},
{"name": "appsscript", "type": "JSON", "source": get_manifest()},
]
}
project_update_response = service.projects().updateContent(body=update_request, scriptId=SCRIPT_ID).execute()
print("Project Update Response : ", project_update_response)
##########################################
## Till here code runs without a problem
##########################################
execute_request = {"function": "executionScript"}
try:
###############################################
## Exception raised below, whose response is
# {
# 'done': True,
# 'error': {
# 'code': 3,
# 'message': 'ScriptError',
# 'details': [
# {
# '@type': 'type.googleapis.com/google.apps.script.v1.ExecutionError',
# 'errorMessage': 'Script function not found: executionScript',
# 'errorType': 'ScriptError'
# }
# ]
# }
# }
###############################################
execute_response = (
service.scripts()
.run(body=execute_request, scriptId=SCRIPT_ID)
.execute()
)
print("Response when exexuting script is : ", execute_response)
return Response(
{"status": 200, "content": "Successfully executed the script"},
status=status.HTTP_200_OK,
)
except Exception as e:
# The API encountered a problem before the script started executing.
print("Exception raised is : ", e)
class AuthorizePage(generics.ListAPIView):
def get(self, request, *args, **kwargs):
param1 = self.request.query_params.get("param1")
param2 = self.request.query_params.get("param2")
# Store the state so the callback can verify the auth server response.
bytes_string = "?param1={}¶m2={}".format(param1, param2)
bytes_string = bytes_string.encode()
encoded_state = base64.b64encode(bytes_string)
encoded_state_string = encoded_state.decode("UTF-8")
self.request.session["state"] = encoded_state_string
# Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps.
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
CLIENT_SECRETS_FILE, scopes=SCOPES, state=encoded_state_string
)
flow.redirect_uri = request.build_absolute_uri(
reverse("oauth2_google:oauth2callback")
)
authorization_url, _ = flow.authorization_url(
# Enable offline access so that you can refresh an access token without
# re-prompting the user for permission. Recommended for web server apps.
access_type="offline",
# Enable incremental authorization. Recommended as the best practice.
include_granted_scopes="false",
)
return redirect(authorization_url)
class OAuth2CallbackPage(generics.ListAPIView):
def get(self, request, *ars, **kwargs):
# Specify the state when creating the flow in the callback so that it can
# verified in the authorization server response.
state = self.request.session["state"]
decoded_state_bytes = state.encode()
decoded_bytes = base64.b64decode(decoded_state_bytes)
decoded_string = decoded_bytes.decode("UTF-8")
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
CLIENT_SECRETS_FILE, scopes=SCOPES, state=state
)
flow.redirect_uri = request.build_absolute_uri(
reverse("oauth2_google:oauth2callback")
)
# Use the authorization server's response to fetch the OAuth 2.0 tokens.
authorization_response = request.build_absolute_uri()
flow.fetch_token(authorization_response=authorization_response)
# Store credentials in the session.
# ACTION ITEM: In a production app, you likely want to save these
# credentials in a persistent database instead.
credentials = flow.credentials
self.request.session["credentials"] = credentials_to_dict(credentials)
return redirect(reverse("oauth2_google:test_api_request") + decoded_string)
def credentials_to_dict(credentials):
return {
"token": credentials.token,
"refresh_token": credentials.refresh_token,
"token_uri": credentials.token_uri,
"client_id": credentials.client_id,
"client_secret": credentials.client_secret,
"scopes": credentials.scopes,
}
我在 Apps 脚本网页中看到的只是代码未执行的错误
Stackdriver 也没有显示错误是什么,以及为什么没有执行代码
由于我能够访问 Script API 并成功更新代码而没有错误,我认为使用相同的 Auth 令牌,我也应该能够执行脚本。请帮忙指出错误。
我什至尝试使用 Google App Script QuickStart Example 在单独的 python 文件中独立执行脚本,但即使这样也给出了相同的错误
解决方案
推荐阅读
- math - OpenGL:使用四元数从位置和方向获取lookAt中心
- matlab - 表中的散点图 - Matlab
- powershell - 使用 Out-GridView 选择对象
- jquery - 使用 JSON & JQUERY 返回数据
- google-colaboratory - 如何在上传的笔记本上保留单元格输出?
- excel - 1004 错误:无法获取 WorksheetFunction 类的 StDev_S 属性
- php - Yii2 验证,允许几种不同的格式
- c# - C# LINQ 查询导致 DB2 错误 CASE 表达式或 DECODE 函数的结果表达式的数据类型不兼容
- continuous-deployment - 无人机 IO 从另一个帐户发布到 ECR
- python - python从十进制(10,2)中获取每个