- Borrowing the Apps Script generated token. This is by far the most straightforward way and can be used in cases where Apps Script has generated the scopes your API needs (For example mentioning DriveApp in your code will generate a token that allows you to use the Drive API directly).
- Using a Service Account. This is the most straightforward since there is no user dialog required. However, not all APIS support Service account flow, and in any case, any script that requires access to user resources should use a flow that explicitly requests them.
- A script that is only going to access resources belonging to its owner. In this case, only 1 initial dialog is required, and thereafter access tokens will be refreshed automatically. This initial dialog needs a UI to ask for permission of course, but it’s not required after that.
- A script that is going to be used by multiple users to access their resources. In this case, you’ll need a permanent UI so that new users can give consent.
UI Types
- A webapp will already have a doGet() function that can be used for a consent dialog.
- A standalone script not using a spreadsheet, form, slide or doc will need a doGet() function to host a dialog.
- A script that has access to any of these documents can host a dialog in either a sidebar or a dialog, so it can use the document’s UI.
Property Stores
- Service accounts should use the ScriptProperties store, or the UserProperties if the owner is the only one who will run it.
- Scripts that will only be run by the script owner with access to their resources should use the UserProperties
- Scripts that will be used by multiple users should store the initial credentials in the ScriptProperties store and use Goa to Clone those properties into the UserProperties store. This will allow you to have one master set of credentials, but each user will have their own token maintenance infrastructure. Changing any credentials in the script Properties will automatically provoke a re-consent request.
One off initialization Scripts
Services supported by Goa
"google_service": "google": "linkedin": "soundcloud": "podio": "shoeboxed": "github": , "reddit":, "asana": , "live": "paypal_sandbox": "paypal_live": , "firebase":
What’s new in Goa
- Write the credentials using a one off function, then delete it once run.
cGoa.GoaApp.setPackage ( propertyStore,{ packageName: 'yt-client', clientId: '4.......b.apps.googleusercontent.com', clientSecret:'5.........w', scopes : cGoa.GoaApp.scopesGoogleExpand ( ["youtube", "youtube.force-ssl", "youtubepartner", "youtubepartner-channel-audit", "yt-analytics-monetary.readonly", "yt-analytics.readonly"]), service:'google' });
- Use ScriptProperties, since he’s the only one that will be running this script
- Create a temporary
doGet()
and publish the app to be able to provoke a dialog.
This is the UI that needs to be published, run once to provoke the authentication dialog, and then deleted. However, if your app is a webapp, goa.done()
can be replaced by returning the code of your app as an HTML service and the rest of the code can be left in place.
function doGet(e) { // create a goa using the client // info stored in script properties var goa = cGoa.GoaApp.createGoa( 'yt-client', PropertiesService.getScriptProperties()) // this builds it - the (e) is important... .execute(e); return goa.needsConsent() ? goa.getConsent() : goa.done(); }
The App main code gets its token like this
function spreadsheetAnalytics() { var goa = cGoa.make('yt-client',PropertiesService.getScriptProperties()); // when this re-enters if (!goa.hasToken()) throw 'something went wrong- didnt get token'; YouTube.setTokenService( function() { return goa.getToken(); }); YouTubeAnalytics.setTokenService(function() { return goa.getToken(); }); etc....
Since this particular App is running with access to a spreadsheet, we might as well use the Spreadsheet UI rather than bothering with a doGet() function. Goa can take care of that automatically using this pattern.
function main (e) { // create a goa using the client // info stored in script properties var goa = cGoa.GoaApp.createGoa( 'yt-client', PropertiesService.getScriptProperties()) // this builds it .execute(e); // this gets consent in a sidebar if its necessary if (goa.needsConsent()) { return goa.getConsentUi (SpreadsheetApp.getUi(), { type:"SIDEBAR" }); } // do the work spreadsheetAnalytics(); return goa.done(); }
That creates a consent dialog like this in the sidebar but only if it’s needed. Note that you can just run this function normally. There’s no need to publish anything. Goa is able to take care of the UI if you pass the UI to use to it as in
goa.getConsentUi (SpreadsheetApp.getUi(), { type:"SIDEBAR" });
You may prefer to provoke the consent dialog as a dialog box – especially if you are already using the sidebar for something else. In this case, you can do this. Everything else in the pattern is the same.
if (goa.needsConsent()) { return goa.getConsentUi (SpreadsheetApp.getUi(), { type:"DIALOG", modal:true, height:600, width:400, title:"authentication with modal" }); }
Behavior
var goa = cGoa.GoaApp.createGoa( 'yt-client', PropertiesService.getScriptProperties()) // add any special UI requirements .setUiBehavior ({ close:true, // whether to close the UI after dialog closeConsent:true, // whether to close the UI after consent dialog showRedirect:false // whether to show the redirect URL (for the developer's use) }) // this builds it .execute(e);
Without the redirect URI the default consent screen looks like this
The library, cGoa, is available under this project key.
MZx5DzNPsYjVyZaR67xXJQai_d-phDA33
For more like this, see OAuth2 for Apps Script in a few lines of code
Why not join our forum, follow the blog or follow me on Twitter to ensure you get updates when they are available.