Multiple Goa consent dialogs

This describes how to handle multiple consent dialogs while using the Goa library as described in Oauth2 for Apps Script in a few lines of code (which you should read first for background).

The library, cGoa, is available under this project key.

MZx5DzNPsYjVyZaR67xXJQai_d-phDA33

The problem

As discussed in Goa Setup, when a consent dialog is initiated, a new session of your Apps Script is initiated - meaning that the context and flow is lost. Consider the example where authentication to multiple services are required in the same script, some of which might need consent dialogs and some of which might not. 

Take this extreme case, where authentication is needed for all these services, how is going to be possible to keep track of which have been done and which have not?
 
  var fs = [
    'githubgoa',
    'onedrive', 
    'asanaCredentials', 
    'soundcloud',
    'DriverDatastore_example',
    'DriverDatastore_serviceaccount',
    'podio',
    'reddit',
    'asanaCredentials'//,
  ];

Since Goa is able to detect whether consent dialogs are needed, and also to detect which service is being called back for each initiation, it is possible to handle a mixture of consent requests in the same app.

Pattern for multiple Oauth2 consent requests.


The pattern actually turns out to be quite simple. The app will be re-entered for consent as many times as there are consent dialogs needed. Whether the app instance is because of a consent dialog request is detectable by the presence of a goa request name, in which case we return to get consent. If not then we continue to search the list of packages for those that still don't have a token. Eventually all the consent requests are completed and we can fall through to execute the app.
function doGet(e) {
 var fs = [
     'githubgoa',
     'onedrive', 
     'asanaCredentials', 
     'soundcloud',
     'DriverDatastore_example',
     'DriverDatastore_serviceaccount',
     'podio',
     'reddit',
     'asanaCredentials'
   ];

   // if we are being called back to get consent then the name of the package will be in the parameters
   var name = cGoa.Goat.getName(e);
   if(name) {
     var goa = new cGoa.Goa(name,PropertiesService.getScriptProperties()).execute(e); 
     // renter for consent
     if (goa.needsConsent()) {
      return goa.getConsent();
     }
   }
  
   // if we get here then we look through each one to see if any more consent is needed
   for (var i = 0; i < fs.length ; i++ ) {
     var goa = new cGoa.Goa(fs[i],PropertiesService.getScriptProperties()).execute(); 
     if (goa.needsConsent()) {
       return goa.getConsent();
     }
     if (!goa.hasToken()) throw 'something went wrong with goa - did you check if consent was needed?';
   }
  
  
   return HtmlService.createHtmlOutput ('all tokens created for each of ' + fs.join(','))
    .setSandboxMode(HtmlService.SandboxMode.IFRAME);
}

For more like this, see OAuth2 for Apps Script in a few lines of code. Why not join our forumfollow the blog or follow me on twitter to ensure you get updates when they are available. 

You want to learn Google Apps Script?

Learning Apps Script, (and transitioning from VBA) are covered comprehensively in my my book, Going Gas - from VBA to Apps script, All formats are available from O'ReillyAmazon and all good bookshops. You can also read a preview on O'Reilly

If you prefer Video style learning I also have two courses available. also published by O'Reilly.
Google Apps Script for Developers and Google Apps Script for Beginners.


Comments