#StackBounty: #javascript #google-apps-script #oauth #gmail #gmail-addons Gmail Add-On: Oauth not being triggered

Bounty: 50

In the code below, ‘Test’ button triggers a function which calls an external endpoint to load data. However, nothing happens when the button is clicked and I get a 400 error in the console area saying Invalid Argument.


function buildAddOn(e) {
  // Create a section for that contains all user Labels.
  var section = CardService.newCardSection()  
  var action = CardService.newAction()

  var button = CardService.newTextButton().setText('Test').setOnClickAction(action);

//  section.addWidget(CardService.newTextParagraph()
//    .setText("This is a text paragraph widget. Multiple lines are allowed if needed.");)

  // Build the main card after adding the section.
  var card = CardService.newCardBuilder()
    .setTitle('Authentication Card')

  return [card];

function testCall(){
  var data = accessProtectedResource('https://api.ssdf.io/v1.0/asd/4/174203','get');
  return CardService.newActionResponseBuilder()


 * Attempts to access a non-Google API using a constructed service
 * object.
 * If your add-on needs access to non-Google APIs that require OAuth,
 * you need to implement this method. You can use the OAuth1 and
 * OAuth2 Apps Script libraries to help implement it.
 * @param {String} url         The URL to access.
 * @param {String} method_opt  The HTTP method. Defaults to GET.
 * @param {Object} headers_opt The HTTP headers. Defaults to an empty
 *                             object. The Authorization field is added
 *                             to the headers in this method.
 * @return {HttpResponse} the result from the UrlFetchApp.fetch() call.
function accessProtectedResource(url, method_opt, headers_opt) {
  var service = getOAuthService();
  var maybeAuthorized = service.hasAccess();
  if (maybeAuthorized) {
    // A token is present, but it may be expired or invalid. Make a
    // request and check the response code to be sure.

    // Make the UrlFetch request and return the result.
    var accessToken = service.getAccessToken();
    var method = method_opt || 'get';
    var headers = headers_opt || {};
    headers['Authorization'] =
        Utilities.formatString('Bearer %s', accessToken);
    var resp = UrlFetchApp.fetch(url, {
      'headers': headers,
      'method' : method,
      'muteHttpExceptions': true, // Prevents thrown HTTP exceptions.

    var code = resp.getResponseCode();
    if (code >= 200 && code < 300) {
      return resp.getContentText("utf-8"); // Success
    } else if (code == 401 || code == 403) {
       // Not fully authorized for this action.
       maybeAuthorized = false;
    } else {
       // Handle other response codes by logging them and throwing an
       // exception.
       console.error("Backend server error (%s): %s", code.toString(),
       throw ("Backend server error: " + code);

  if (!maybeAuthorized) {
    // Invoke the authorization flow using the default authorization
    // prompt card.
        .setResourceDisplayName("Login to ....")

 * Create a new OAuth service to facilitate accessing an API.
 * This example assumes there is a single service that the add-on needs to
 * access. Its name is used when persisting the authorized token, so ensure
 * it is unique within the scope of the property store. You must set the
 * client secret and client ID, which are obtained when registering your
 * add-on with the API.
 * See the Apps Script OAuth2 Library documentation for more
 * information:
 *   https://github.com/googlesamples/apps-script-oauth2#1-create-the-oauth2-service
 *  @return A configured OAuth2 service object.
function getOAuthService() {
  return OAuth2.createService('auth')

 * Boilerplate code to determine if a request is authorized and returns
 * a corresponding HTML message. When the user completes the OAuth2 flow
 * on the service provider's website, this function is invoked from the
 * service. In order for authorization to succeed you must make sure that
 * the service knows how to call this function by setting the correct
 * redirect URL.
 * The redirect URL to enter is:
 * https://script.google.com/macros/d/<Apps Script ID>/usercallback
 * See the Apps Script OAuth2 Library documentation for more
 * information:
 *   https://github.com/googlesamples/apps-script-oauth2#1-create-the-oauth2-service
 *  @param {Object} callbackRequest The request data received from the
 *                  callback function. Pass it to the service's
 *                  handleCallback() method to complete the
 *                  authorization process.
 *  @return {HtmlOutput} a success or denied HTML message to display to
 *          the user. Also sets a timer to close the window
 *          automatically.
function authCallback(callbackRequest) {
  var authorized = getOAuthService().handleCallback(callbackRequest);
  if (authorized) {
    return HtmlService.createHtmlOutput(
      'Success! setTimeout(function() { top.window.close() }, 1);');
  } else {
    return HtmlService.createHtmlOutput('Denied');

 * Unauthorizes the non-Google service. This is useful for OAuth
 * development/testing.  Run this method (Run > resetOAuth in the script
 * editor) to reset OAuth to re-prompt the user for OAuth.
function resetOAuth() {

Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.