-3

I have created a script in APPS script and deployed it as API Executable. I started to get 500 error when connecting to it. I decided to create a script from tutorial to localize the issue with this error. To my surprise i received the same results. Probably the issue is with service account, because i associated script with project where i have service account and i try to authorize with it.

I read that there were issues with connecting to Execution API with service account, which can still be true today.

***Update: I have successfully accessed Execution API with tutorial script when using OAuth2 user client ID. Is there still any issue with connecting to Execution API using Service Account?

Here is the Apps Script that i deployed as API Executable to the project where i have service account:

/**
   * The function in this script will be called by the Apps Script Execution  API.    */

/**
* Return the set of folder names contained in the user's root folder as an
* object (with folder IDs as keys).
* @return {Object} A set of folder names keyed by folder ID.
*/
function getFoldersUnderRoot() {
  var root = DriveApp.getRootFolder();
  var folders = root.getFolders();
  var folderSet = {};
  while (folders.hasNext()) {
    var folder = folders.next();
    folderSet[folder.getId()] = folder.getName();
}
 return folderSet;
}

Here is my partly modified code that i took from tutorial. I changed it to work with service account:

from googlepackage.api_client import *
from googlepackage.constants import *
from googleapiclient.errors import HttpError
from httplib2 import Http


def __get_credentials(scopes: list) -> ServiceAccountCredentials:

credential_dir = os.path.join("..\\", SERVICE_ACCOUNT_FOLDER)
print(credential_dir)
if not os.path.exists(credential_dir):
    raise Exception("Cannot find the directory with credentials")
try:
    credentials = ServiceAccountCredentials.from_json_keyfile_name(
        os.path.join(credential_dir, 'file.json'),
        scopes)
except (ValueError, KeyError) as error:
    raise Exception(error)

return credentials


def main():
"""Shows basic usage of the Apps Script Execution API.

Creates a Apps Script Execution API service object and uses it to call an
Apps Script function to print out a list of folders in the user's root
directory.
"""
SCRIPT_ID = 'API ID'

http_auth = __get_credentials([READ_AND_WRITE_SCOPE, DRIVE_API_SCOPE]).authorize(Http())

# Authorize and create a service object.
service = discovery.build('script', 'v1', http=http_auth)

# Create an execution request object.
request = {"function": "getFoldersUnderRoot"}

try:
    # Make the API request.
    response = service.scripts().run(body=request, scriptId=SCRIPT_ID).execute()

    if 'error' in response:
        # The API executed, but the script returned an error.

        # Extract the first (and only) set of error details. The values of
        # this object are the script's 'errorMessage' and 'errorType', and
        # an list of stack trace elements.
        error = response['error']['details'][0]
        print("Script error message: {0}".format(error['errorMessage']))

        if 'scriptStackTraceElements' in error:
            # There may not be a stacktrace if the script didn't start
            # executing.
            print("Script error stacktrace:")
            for trace in error['scriptStackTraceElements']:
                print("\t{0}: {1}".format(trace['function'],
                                          trace['lineNumber']))
    else:
        # The structure of the result will depend upon what the Apps Script
        # function returns. Here, the function returns an Apps Script Object
        # with String keys and values, and so the result is treated as a
        # Python dictionary (folderSet).
        folderSet = response['response'].get('result', {})
        if not folderSet:
            print('No folders returned!')
        else:
            print('Folders under your root folder:')
            for (folderId, folder) in folderSet.items():
                print("\t{0} ({1})".format(folder, folderId))

except HttpError as e:
    # The API encountered a problem before the script started executing.
    print(e.content)

if __name__ == '__main__':
    main()

Here is the HttpError Content from my response:

b'{\n  "error": {\n    "code": 500,\n    "message": "Internal error 
encountered.",\n    "errors": [\n      {\n        "message": "Internal error 
encountered.",\n        "domain": "global",\n        "reason": 
"backendError"\n      }\n    ],\n    "status": "INTERNAL"\n  }\n}\n'
ziganotschka
  • 25,866
  • 2
  • 16
  • 33
Paulus
  • 138
  • 1
  • 11
  • 1
    Welcome to Stack Overflow! You should explain more about your problem, what you've already try/done et try to be more specific. Please take a look at [How to ask a good question](https://stackoverflow.com/help/how-to-ask) – Pierre-Marie Richard Jul 28 '17 at 13:56
  • 1
    Sorry for that, i added some more information about my investigation – Paulus Jul 28 '17 at 14:57

1 Answers1

0

Update: I have successfully accessed Execution API with tutorial script when using OAuth2 user client ID.

I still am not able to get through to execution api using service account and its credentials. I could connect to Execution API only with OAuth2 client ID.

So for now, i would suggest using 2 accounts to access google sheets api with service account and execution api with OAuth2 client ID

Paulus
  • 138
  • 1
  • 11