Функция скрипта Google Apps не найдена: имя_функции - PullRequest
0 голосов
/ 23 мая 2019

Я пытаюсь запустить скрипт, используя 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={}&param2={}".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={}&param2={}".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,
    }

Все, что я вижу на веб-странице скриптов приложений, - это ошибки, которые код не выполняется

google-apps-script-image

Stackdriverтакже не показывает, в чем заключается ошибка, и почему код не выполняется

Поскольку я могу получить доступ к API-интерфейсу сценария и успешно обновить код без ошибок, я думаю, что используя тот же токен аутентификации, я долженбыть в состоянии выполнить сценарий также.Пожалуйста, помогите указать на ошибку.

Я даже пытался выполнить скрипт независимо в отдельном файле python, используя пример быстрого запуска скрипта Google App, но даже это дало ту же ошибку

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...