0

We are looking for a way to trigger a function in the add-on in the user's context (authorization) from our web app. We tried using Apps Script Execution API to trigger that. The flow is add-on (apps script) registers the access token in our web app and the web app triggers execution API using the access token. This works for the first time. But the problem is, the access token is valid for only a few minutes. After which the web app is not able to initiate function through execution API due to authorization failure.

Questions:

Is our approach for triggering add-on/ apps script function from another web app in the user's context correct by using execution API?

If so, how do we avoid access token from expiring? Apparently, there is no API in apps script to 'get the refresh token'/ 'refresh the token'. How do we go about refreshing the token so that the token is valid forever (until the user cancels)?

Is there any radically different approach that will help in this case?

I see that add-ons like "PearDeck", "Form Approvals", "Form Publisher" etc are successfully doing this (triggering add-on function from the web app with user's authorization).

Hope to get some expert advice in this forum. Thanks

Used Execution API - with the problem in token getting expired

function prepareToken() {
// send to web app
    var token = ScriptApp.getOAuthToken();

    URLFetchApp.fetch("url?token="+token);
}

function doSomeWorkFromUserContext() {
    // impl here
}

POST https://script.googleapis.com/v1/scripts/{scriptId}:run

Request Header
Authorization: Bearer + {token}

Request Body 
{
  "function": "doSomeWorkFromUserContext"
}

The function doSomeWorkFromUserContext should get called all the time of invocation but getting Authorization error after some time.

ziganotschka
  • 25,866
  • 2
  • 16
  • 33
Michaes
  • 73
  • 6

1 Answers1

1

When a user authorizes your app for the first time you receive a refresh token along with the access token. The access token typically expires after one hour and you have to use the refresh token to fetch a new access token.

Note that the refresh token is only returned when the user initially authorizes your app.

You'll need to revoke the user's authorization (see below) and have them reauthorize the app to get the refresh token. Revoking access can be achieved in one of 3 ways:

Eric Koleda's GAS OAuth2 library does a great job of managing the entire OAuth2 flow (including automatically refreshing access tokens) so be sure to check that out.

TheAddonDepot
  • 8,408
  • 2
  • 20
  • 30
  • Thanks for your answer. However, what we need is to refresh the access (not to revoke the access). And the apps script is not explicitly using OAuth2 but implicitly getting the access token from pre-authorized apps script using ScriptApp.getOAuthToken(). So there is no refresh token available to refresh the access token. – Michaes Aug 28 '19 at 06:11
  • `ScriptApp.getOAuthToken()` automatically refreshes the token after one hour. So just call that function again to get a new one. – TheAddonDepot Aug 28 '19 at 10:22
  • Dimu Designs, within apps script ScriptApp.getOAuthToken() gives refreshed token. But we are storing the token in the web app and calling an Apps Script Execution API to trigger some function in user context/ authorization. Even if we are trying to get a new token from web app by calling Apps Script through Execution API every few minutes, after some time the token becomes invalid and we cannot call Apps Script Execution API from the web app. – Michaes Aug 28 '19 at 11:44
  • So, basically, we need a way to renew/ refresh the auth token from outside the apps script so that we can call Apps Script Execution API – Michaes Aug 28 '19 at 11:45
  • Storing the token provided by `ScriptApp.getAuthToken` is not a good way to go about it. When leveraging the Execution API you typically create a client application via the Google Cloud Console where you are issued a **client id** and **client secret**. You then use those credentials in your OAuth flow to obtain your access and refresh tokens. – TheAddonDepot Aug 28 '19 at 12:08
  • See [documentation](https://developers.google.com/apps-script/api/how-tos/execute#step_3_configure_the_calling_application). – TheAddonDepot Aug 28 '19 at 12:09
  • The scenario that we need 'approval workflow' like solution. When the approver (need not be a Gmail/ GSuite user) click on 'Approve' button on an email he/she received, we want to trigger an Apps Script function in the context of the user who set up the workflow (not in the context of approver who may not even have a google account) to do some process like creating Google Doc and send to the person who submitted the form. I am sure this can be done by Execution API (as in some add-ons). The missing point is how to retain access token valid to call API. Any pointer in this line is appreciated – Michaes Aug 31 '19 at 11:02
  • You cannot refresh access tokens that are managed by a GAS project, so you have to create a Web App (via the Google Cloud console) and use the provided credentials (**client id** and **client secret**) to create a custom OAuth flow to generate refresh and access tokens as needed. Its all covered in the [documentation](https://developers.google.com/apps-script/api/how-tos/execute#step_3_configure_the_calling_application) I linked to in my previous comment. – TheAddonDepot Aug 31 '19 at 12:25
  • I am aware of the credential route to acquire refresh token but that gives token of who logs into web app. I need token of who setup add on (apps script) so that the apps script function be the trigger in his/her context. For example, if the script sends an email, it should be coming from add-on user, not the user who is on the web app. (the web app user need not have google account at all) – Michaes Aug 31 '19 at 13:47
  • Add-ons like Pear Deck, Form Approvals and Form Publisher do this. I want to know to these do that. – Michaes Aug 31 '19 at 13:48