Я пытаюсь запустить скрипт, используя RESTful API google-apps-script.Когда скрипт выполняется, я всегда получаю сообщение об ошибке Script function not found: function_name
.Где я ошибаюсь?
Это для нового проекта, где мне нужно запустить скрипт из приложения Django.Поэтому я пытаюсь вызвать функцию запуска скрипта после аутентификации пользователя (с помощью Google OAuth2).Непосредственно перед попыткой запустить скрипт, я обновляю скрипт, который работает без каких-либо проблем.
Я взял приложение фляги из https://developers.google.com/api-client-library/python/auth/web-app и преобразовал его в DRF * 1008.*
# 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,
}
Все, что я вижу на веб-странице скриптов приложений, - это ошибки, которые код не выполняется
Stackdriverтакже не показывает, в чем заключается ошибка, и почему код не выполняется
Поскольку я могу получить доступ к API-интерфейсу сценария и успешно обновить код без ошибок, я думаю, что используя тот же токен аутентификации, я долженбыть в состоянии выполнить сценарий также.Пожалуйста, помогите указать на ошибку.
Я даже пытался выполнить скрипт независимо в отдельном файле python, используя пример быстрого запуска скрипта Google App, но даже это дало ту же ошибку