onOpen()中的Google Apps脚本OAuth2无效

时间:2017-04-24 22:50:56

标签: javascript google-apps-script google-sheets

我正在使用Sheets文档中的脚本从Google Search Console获取数据。该脚本使用OAuth2 library from GitHub,它似乎在大多数情况下都能正常工作。

我正在使用一个函数来检查用户是否仍然具有API访问权限 - 名为hasAccess() - 以便正确显示菜单项。麻烦的是,尽管该函数在其他地方都可以工作,但它在onOpen函数中不起作用...我真正需要它的地方!

我想知道这是否与权限有关?我将非常感激任何帮助,因为我失去了生存的意愿!

你可以在这里看到我的代码(我已经删除了大部分似乎无关紧要的内容):

// Setup on sheet open
function onOpen(e) {
  // Set date validation
  range = sheet.getRange('A2:A');
  range.setDataValidation(dateRule);

  // Check auth mode
  if (e && e.authMode === ScriptApp.AuthMode.NONE) {
    // Add an enable menu item (works in all authorization modes).
    menu.addItem('Enable add-on', 'onOpen');
  } else {
    // Add setup option
    menu
    .addItem('Setup', 'setupDialog')
    .addToUi();

    // Check if API service has been authorized and allow functions
    var service = getService();

    // THE FOLLOWING RESULT IS ALWAYS FALSE :(
    Logger.log(service.hasAccess());

    if (service.hasAccess()) {
      // Add start option
      menu
      .addItem('Start', 'startDialog')
      .addToUi();

      // Add get dates option
      menu
      .addItem('Get dates', 'getDates')
      .addToUi();
    }
  }

  // Add help option
  menu
  .addItem('Help...', 'helpDialog')
  .addToUi();
}

function test() {
  var service = getService();

  // BUT THIS WORKS..?
  Logger.log(service.hasAccess());
}


/*** OAUTH2 FUNCTIONS ***/

// Much of the following is adapted from Martin Hawksey's OAuth2 solution for Blogger - check it out!
// https://mashe.hawksey.info/2015/10/setting-up-oauth2-access-with-google-apps-script-blogger-api-example/

// Create OAuth2 service using library
function getService() {
  // Create a new service with the given name. The name will be used when
  // persisting the authorized token, so ensure it is unique within the
  // scope of the property store.
  return OAuth2.createService('searchConsole')

  // Set the endpoint URLs, which are the same for all Google services.
  .setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
  .setTokenUrl('https://accounts.google.com/o/oauth2/token')

  // Set the client ID and secret, from the Google Developers Console.
  .setClientId(userProperties.getProperty('clientId'))
  .setClientSecret(userProperties.getProperty('clientSecret'))

  // Set the name of the callback function in the script referenced
  // above that should be invoked to complete the OAuth flow.
  .setCallbackFunction('authCallback')

  // Set the property store where authorized tokens should be persisted.
  .setPropertyStore(PropertiesService.getUserProperties())

  // Set the scopes to request (space-separated for Google services).
  // this is blogger read only scope for write access is:
  // https://www.googleapis.com/auth/blogger
  .setScope('https://www.googleapis.com/auth/webmasters.readonly')

  // Below are Google-specific OAuth2 parameters.

  // Sets the login hint, which will prevent the account chooser screen
  // from being shown to users logged in with multiple accounts.
  .setParam('login_hint', Session.getActiveUser().getEmail())

  // Requests offline access.
  .setParam('access_type', 'offline')

  // Forces the approval prompt every time. This is useful for testing,
  // but not desirable in a production application.
  .setParam('approval_prompt', 'force');
}

// Handle OAuth2 callback
function authCallback(request) {
  var searchConsoleService = getService(),
      isAuthorized = searchConsoleService.handleCallback(request);
  if (isAuthorized) {
    return HtmlService.createHtmlOutput('Success! You can close this tab.');
  } else {
    return HtmlService.createHtmlOutput('Denied. You can close this tab');
  }
} 

1 个答案:

答案 0 :(得分:0)

我为 make onOpen 函数所做的工作方式如下:

  • 使用您的自定义代码(即功能)创建 onOpen 函数。
  • 在您的主函数(电子表格打开后执行的函数)中,添加以下代码:

// Set trigger programatically - adding the "onOpen" function: 
ScriptApp.newTrigger("onOpen")
.forSpreadsheet(SPREADSHEET_ID)
.onOpen()
.create();

这是完整的代码:

/** This is the main function that executes once the spreadsheet is open: */
function startProgram() {
    // Set trigger programatically - adding the "onOpen" function: 
      ScriptApp.newTrigger("onOpen")
      .forSpreadsheet(SPREADSHEET_ID)
      .onOpen()
      .create();
}

/** onOpen function that adds items to select in the spreadsheet: */
function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('My Menu')
    .addItem('Show message', 'showMessage_') // This is the name of the function to call.
    .addToUi();
}

/** Show alert message. */
function loadCards_() {
  SpreadsheetApp.getUi().alert("Today is: " + new Date());
}

然后,执行代码并重新加载/刷新电子表格。您会看到新菜单,其中的项目已添加到电子表格中。