google-apps-scriptgmail-addonsgsuite-addons

Can't serve HTML on the Google Apps Script callback page in a GMail add-on


I am working on a GMail add-on that connects to a third-party service through OAuth2. To obtain the authorization code the following redirect URI is used: https://script.google.com/macros/d/[SCRIPT_ID]/usercallback . Here's a snippet that triggers authorization:

var stateToken = ScriptApp.newStateToken()
                          .withMethod( "authCallback" )
                          .withTimeout( 120 )
                          .createToken();

var authUrl = _authBaseUrl
              + "&client_id=" + encodeURIComponent( _clientId )
              + "&redirect_uri=" + encodeURIComponent( _redirectUri )
              + "&state=" + stateToken;

CardService.newAuthorizationException()
           .setAuthorizationUrl( authUrl )
           .setResourceDisplayName( "Resource" )
           .throwException();

And here's the callback function (the HTML snippet is taken from here):

function authCallback( request )
{
    createAccessToken( request.parameter.code );
    return HtmlService.createHtmlOutput('Success! <script>setTimeout(function() { top.window.close() }, 1);</script>');
}

The createAccessToken function gets successfully invoked and the add-on gets an access token. However, the HTML is not served in the popover window. Instead, there's a placeholder with the following error: "The script completed but did not return anything."

As a result, I am stuck with an error window which can't be closed automatically and doesn't tell user that they have to close the window to continue working with the add-on.

Is there anything wrong I am doing or this is some kind of bug or a dropped feature? Thanks for any suggestions.

UPD: The error looks like this


Solution

  • Turns out the HtmlService actually works in that case. I had a function name collision for authCallback, so the proper one wasn't invoked. Sorry for misinformation. If anyone has trouble handling the callback window, do as described in the question.