goa in a sidebar

This describes how to implement goa in a sidebar. The example will assume that the authorization process should be repeated for each new user (like a web app published in Accessing as the user running the script)

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

MZx5DzNPsYjVyZaR67xXJQai_d-phDA33

Goa -vs- gapi

If you are creating a sidebar, you can of course use the gapi library to run client side, but goa allows you to create an infrastructure that works server side, to keep your credentials more securely and also to be able to use it for both server and client side purposes. The goa dialog can be customized if you want to make it more the style of your add-on or sidebar content, since the default content is designed for a web app, or since the dialog only happens once, you may want to just leave it as  is. Of course if you are using a service account, there is no dialog anyway, and if you are running the sidebar 'as you', then the dialog would only happen once with you - not with each user.

Setting everything up

There is no difference between setting up goa for a sidebar or a webapp, and the setup in the Google Developer console is also exactly the same. 

You still need a one-off initialization of your credentials, like this, which you can run once and then remove from your project.  I've downloaded my credentials and want goa to read them from drive. You can enter the credentials directly if you prefer, as described in other examples. The scopes should be provided here for whatever you want to get to.
// force a drive auth
// DriveApp.getFileById(id)
function oneOff() {
  cGoa.GoaApp.setPackage (PropertiesService.getScriptProperties() , 
    cGoa.GoaApp.createPackageFromFile (DriveApp , {
      packageName: 'drivedemo',
      fileId:'0B92ExLh4xxxxxbWtRdWhtanc',
      scopes : cGoa.GoaApp.scopesGoogleExpand (['drive.readonly']),
      service:'google',
      reset:new Date().getTime()
    }));
};


Your app.

This is a slightly different structure than a web app, since you are not using doGet(), but instead using the UI that manages the sidebar. It's only a minor difference.

The main points are
  • The .userClone() method is the same as for a webapp as described in Accessing as the user running the script
  • The name 'drivedemo' matches the one used in the onceoff credentials store.
  • If it needs consent, it will pass the content to the sidebar UI, in contrast to the webapp implementation, where it exits doGet() at this point.
  • if it doesn't need consent, you can go ahead and use the UI to display your App. In my example, I'm just displaying the token
  • It's fairly counter-intuitive how that last return HtmlService ever get's executed, but it's needed to provide a message back to the Google Auth dialog. Here you should put some instruction that the user will see after having gone through the Google Auth dialog, and given permission to access the requested scopes.
  • The reason that all this works seamlessly is because  the last thing that goa.getConsent() does is to re-enter the script at whichever function it was initiated from - so actually, if consent is required (which is asked for in the sidebar) - this script gets executed twice. Once to get consent, then the second time it doesn't need consent anymore, gets the token and initiates your app in the sidebar. In parallel with rendering your app in the sidebar, it returns the last message to the authorization dialog saying its done.
function onOpen() {
  
  var ui = SpreadsheetApp
  .getUi()
  .createMenu('sidebar')
  .addItem('run', 'sidebar')
  .addToUi();
  
  
}
function sidebar (e) {
  
  // I'm running as the user, so clone it if its a new user
  cGoa.GoaApp.userClone( 
    'drivedemo', 
    PropertiesService.getScriptProperties() , 
    PropertiesService.getUserProperties()
  );
  
  
  // get the goa
  var goa = cGoa.GoaApp.createGoa(
    'drivedemo', 
    PropertiesService.getUserProperties()
  ).execute(e);
  
  
  // it's possible that we need consent - this will cause a consent dialog
  if (goa.needsConsent()) {
    SpreadsheetApp.getUi().showSidebar(goa.getConsent());
  }
  else {
    // and we should have a token, or thrown an error somewhere
    if (!goa.hasToken()) { 
      throw 'something went wrong with goa - did you check if consent was needed?';
    }
    SpreadsheetApp.getUi().showSidebar(
      HtmlService.createHtmlOutput('hello world'+'this is the token ' + goa.getToken())
      .setSandboxMode(HtmlService.SandboxMode.IFRAME)
      .setTitle('goa in a sidebar'));
  }
  
  return HtmlService.createHtmlOutput ('You can close this tab and return to your add-on').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