2

When requesting POST https://script.googleapis.com/v1/scripts/{script_id}:run with devMode: true I get a 404 error. I can run the script successfully with devMode: false.

Although other people (1, 2) have raised this issue, none of the other solutions work. I keep getting an HTTP 404 Not Found error whenever my request comes with devMode: true.

I have performed the following steps:

  • created a new Google account
  • created a Cloud project
  • set up an OAuth consent screen for the project
  • authorized the domain for the app (just in case)
  • created 'Desktop' OAuth2 credentials for this project with OAuth scopes listed below
  • enables Apps Script API on the project
  • created a standalone Apps Script using Google Drive ("Test 1")
  • set the Cloud Platform project ID for the script Test 1
  • deploy the script Test 1 as an API executable, with access to "Anyone"
  • obtain a valid access token with the exact same scopes listed below and used for the OAuth consent screen configuration in the Cloud project. The token is for the same account that owns the script and the cloud project.

After performing the above steps, running with devMode: false was successful, but when switching to devMode: true it failed.

The same happens when I set access to "Only Me".

To make clear the steps that I took, I provide a full flow of screenshots taken along the way (open image in new window to zoom in; the flows to top-to-bottom; the three columns from left to right are: Cloud console project flow; Apps Script flow; OAuth2 flow):

Flow screenshots

At the request of @ziganotschka I made a simpler copy of my Apps Script function:

function test() {
  return 1;
}

And the appsscript.json manifest is:

{
  "timeZone": "Asia/Jerusalem",
  "dependencies": {
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8"
}

The code for obtaining the OAuth2 token and running the script, in Python:

##
# %%
import requests
import urllib
import json

client_id = '...'
client_secret = '...'

script_id = '...'

is_dev_mode = True  # True or False

##
# %% Initiate OAuth2
url = 'https://accounts.google.com/o/oauth2/auth?' + urllib.parse.urlencode({
    'client_id': client_id,
    'redirect_uri': 'urn:ietf:wg:oauth:2.0:oob',
    'response_type': 'code',
    'scope': ' '.join([
        'https://www.googleapis.com/auth/userinfo.email',
        'https://www.googleapis.com/auth/userinfo.profile',
        'openid',
        'https://www.googleapis.com/auth/documents',
        'https://www.googleapis.com/auth/drive',
        'https://www.googleapis.com/auth/drive.scripts',
        'https://www.googleapis.com/auth/script.external_request',
        'https://www.googleapis.com/auth/script.projects',
        'https://www.googleapis.com/auth/script.scriptapp',
        'https://www.googleapis.com/auth/script.container.ui'
    ])
}, doseq=True)
print(url)

##
# %% Exchange authorization code with access and refresh tokens
print('Enter authorization token: ', end='')
authorization_code = input()

authorization_token_response = requests.post('https://accounts.google.com/o/oauth2/token', data={
    'code': authorization_code,
    'client_id': client_id,
    'client_secret': client_secret,
    'redirect_uri': 'urn:ietf:wg:oauth:2.0:oob',
    'grant_type': 'authorization_code'
})
authorization_token_response.raise_for_status()

authorization_data = authorization_token_response.json()
access_token = authorization_data["access_token"]
refresh_token = authorization_data["refresh_token"]


##
# %% 
response = requests.post(f'https://script.googleapis.com/v1/scripts/{script_id}:run',
  data=json.dumps({
    "function": "test",
    "parameters": [],
    "devMode": is_dev_mode
  }),
  headers={
      'content-type': 'application/json',
      'authorization': f'Bearer {access_token}'
      }
)

response.raise_for_status()

print(response.content)

I get similar results for a curl call:

$ curl 'https://script.googleapis.com/v1/scripts/x...x:run' -X POST -H 'content-type: application/json' -d '{"function":"test","parameters":[],"devMode":true}' -H 'authorization: Bearer x...x' --silent
{
  "error": {
    "code": 404,
    "message": "Requested entity was not found.",
    "status": "NOT_FOUND"
  }
}

I consider this as an issue report, as Google mention that they use Stack Overflow to field technical questions for Apps Script API. As well as a beacon to anyone who has been frustrated with this issue.

Any my question would be -- am doing anything wrong?

As an aside question: what's the difference between substituting script_id for the Current API ID (as suggested in 'How to Execute a function guide'; this identifier seems to be identical to the script Project key under File > Project properties) and the Script's Drive file ID (suggested everywhere else; this seems to be identical to Script ID)?

Yuval
  • 3,207
  • 32
  • 45
  • [Keep in mind](https://developers.google.com/apps-script/api/reference/rest/v1/scripts/run#request-body): `devMode` If true and the user is an owner of the script, the script runs at the most recently saved version rather than the version deployed for use with the Apps Script API. Optional; default is false. - Is there any discrepency between your currently deployed and the last saved version? – ziganotschka Aug 13 '20 at 14:13
  • @ziganotschka The user is the owner of the script in this case. `devMode: true` gives a 404 regardless to whether there is a discrepancy between the currently deployed and last saved version. – Yuval Aug 13 '20 at 16:12
  • Did you try both with the scriptId and the API id? Is the deploying as API executable enabled? Did the answer in [1](https://stackoverflow.com/questions/35079261/404-error-when-using-apps-script-execution-api-in-python) not solve the issue? (Publishing as `Anyone`)? – ziganotschka Aug 13 '20 at 16:14
  • I tried both with the script ID and the API ID. You can see in the screenshot that I deployed as API and to "Anyone". – Yuval Aug 13 '20 at 16:15
  • In my environment, I could confirm that your script and flow worked for both `devMode`. I deeply apologize that I cannot replicate your issue. So for example, when you redeploy the execution API as new version and testing it again, what result will you get? By the way, in your case, how about using more simple sample script at Google Apps Script side like `const sample = (e) => "Done:" + JSON.stringify(e);`? – Tanaike Aug 14 '20 at 01:37
  • I changed the function to `function test() { return 1; }` and re-deployed it as version 2 with access to `Anyone`. It still doesn't work with `devMode: true` but works OK with `devMode: false`. The manifest is `{"timeZone": "Asia/Jerusalem", "dependencies": {}, "exceptionLogging": "STACKDRIVER", "runtimeVersion": "V8"}`. Did you follow the flow I described in the screenshots? – Yuval Aug 14 '20 at 13:45
  • I included the OAuth2 flow I am using in Python, so you can see the scopes I'm requesting, as well as the app manifest. – Yuval Aug 14 '20 at 13:50
  • Thank you for replying. I noticed your replying just now. I apologize for this. When I did the same flow in your question, I could confirm that no error occurs for both `devMode: true` and `devMode: false`. So unfortunately, I cannot replicate your issue. This is due to my poor skill. I deeply apologize for this. For example, when you save the Google Apps Script with the script editor by clicking the save button and test it with `devMode: true` again, what result will you get? And/or, when you request it using the curl command instead of python, what result will you get? – Tanaike Aug 15 '20 at 02:24
  • @Tanaike I am sure your skills are great. It is just frustrating to not be able to use the `devMode` - and I know I haven't been alone on this. Oddly enough, after re-publishing the API executable and saving two times (?!) it started working with `devMode: true`. Now, every version I save works with `devMode: true`, regardless of 'Who has access' being set to 'Anyone' or 'Only myself', and regardless to whether there are changes made to the script or not after deploying. So unfortunately it's a heisenbug... – Yuval Aug 17 '20 at 13:42
  • I will continue to report on whether this still happens with my real code (rather than the test project I created for reporting this issue) – Yuval Aug 17 '20 at 13:42
  • @Yuval Thank you for replying. Although I'm not sure whether this is the same situation with you, my proposal in the comment is from [this thread](https://stackoverflow.com/a/49207288/7108653). – Tanaike Aug 17 '20 at 22:25
  • For future readers - note that the execution API is enabled only for *API executable* deployments; I had a *web app* deployment and was struggling to understand why I was getting a 404 with this exact same error - until I came across the [requirements section](https://developers.google.com/apps-script/api/how-tos/execute#the_scriptsrun_method) – Janaka Bandara Nov 14 '21 at 07:09

0 Answers0