in this post we'll cover how to invoke the google apps script rest apis from the apps script browser editor.


update [as on 17 nov, 2019]: you don't really need an apiKey to run the rest apis via this process 😅 feel free to totally skip those parts, as required

backstory

while i don't consider myself as an extremely skilled coder - which is to say that almost every piece of code that i write is bound to have some errors and/or if not, a few bugs - when i planned on building some metrics around all of my "script usage", the rest apis provided by google apps script seemed like the only option (where it also gave me an opportunity to work with google oauth 2.0) and i must admit that i did not expect to having encountered a plethora of errors that i might've otherwise not predicted while invoking any other, typical rest api, while using the apps script browser editor.

video

for those of you who prefer a different medium to consume information, here's a short video covering what's written in detail below -


how to trigger google apps script rest api from browser editor

learning

so, the idea was straightforward where, step 1 was to read the documentation.

for the purposes of my needs, i chose to go with the processes.list api. thanks to google's api explorer, i was able to quickly experiment with the api right from the browser and fairly understand what was required to invoke it on-the-go (or so i thought 😅).

the obvious first

as part of step 2, i wrote a simple script that makes use of UrlFetchApp (ref) for the most part (available below), "ran" with it and bam! the script threw my first error -


{
  "error": {
    "code": 403,
    "message": "Request had insufficient authentication scopes.",
    "status": "PERMISSION_DENIED"
  }
}
error # 1

turns out that while we're conditioned for the script's browser editor to automatically add all necessary resources and oauth scopes by itself (you know, without bothering us with these silly errors), in this case it simply added the one required to connect to an "external" resource (i.e. the https://script.googleapis.com/v1/processes endpoint) but did not actually add the corresponding oauth scope required by the script to access it.

note: oauth scope is not to be confused with the api key!


once i revisited the documentation, it clearly had indicated the exact oauth scope that this resource (endpoint) would require and i then added that to the manifest file (manually).

the unexpected second

just when i thought that the one above could've potentially been the only problem, there it was - yet another error and this time, it was a rather an atypical one which led me to a whole another journey of research and to read more documentation.


{
  "error": {
    "code": 400,
    "message": "The API Key and the authentication credential are from different projects.",
    "status": "INVALID_ARGUMENT",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.Help",
        "links": [
          {
            "description": "Google developer console API key",
            "url": "https://console.developers.google.com/project/<Project number>/apiui/credential"
          }
        ]
      }
    ]
  }
}
error # 2

fun fact about the default cloud platform projects -


when a new apps script project is created, a default gcp project is also created behind the scenes. This gcp project is hidden, meaning most users aren't able to directly locate, view, or update the project in the google cloud platform console.

the even-more-unexpected third

i was feeling great about myself after having understood error # 2, figured out my way towards resolving it and while on that road, encountered yet another error -

...error # 3


You cannot switch to a project without a configured OAuth consent screen. To configure the consent screen, please visit here.

demo code

you can experiment with practically any of the rest apis but the one i chose to work with was to do with metrics and these were the lines of code i used to achieve them -

the main apps script file

function myFunction() {
  var token = ScriptApp.getOAuthToken();
  var apiKey = 'Your-API-Key-Goes-Here'; 
  var endPoint = 'https://script.googleapis.com/v1/processes';
  var headers = {
    'Accept':'application/json',
    'Authorization': 'Bearer ' + token
  };
  var options = {
    'method': 'GET',
    'headers': headers,
    'muteHttpExceptions': true
  }
  var url = endPoint + '?key=' + apiKey;
  var response = UrlFetchApp.fetch(url, options);
  Logger.log(response);
}
Code.gs

the manifest file

{
  "timeZone": "Asia/Kolkata",
  "dependencies": {
  },
  "oauthScopes": [
    "https://www.googleapis.com/auth/script.external_request",
    "https://www.googleapis.com/auth/script.processes"
  ],
  "exceptionLogging": "STACKDRIVER"
}
appscript.json