google-sheetsgoogle-apps-scriptadd-on

How can I get my add-ons menus available in newly created Google Sheets?


I'm having a bit of trouble understanding the workflow of a Google Sheet add-on. I'm using it in a sheet in which the script is bound too and it works perfectly fine. However, when I create a new Spreadsheet I can see my add-on menu created under Add-ons but not its submenus. Also, if I look at the executions I get: Exception: You do not have permission to perform that action. when trying to execute Spreadsheet.getUi() to create the menus.

I have deployed a new version and adjusted the settings in the Marketplace SDK to match with those of the deployment. Also, I have all the scopes of the script matching in the OAuth consent screen in my google project and in the Marketplace SDK.

The only way it works is if I go into Add-ons > Manage add-ons And click on Use in this document

What is the correct workflow here to have my add-on menus available automatically in newly created Spreadsheets?


Solution

  • The onOpen (e) is a simple trigger, and it is under a series of restrictions, specially

    They cannot access services that require authorization.

    Before you click "Use in this document", the add-on is in installed mode and the event object e.authMode has value AuthMode.NONE, so your trigger can't access the Properties service. Only after you click "Use in this document" the trigger goes into "enabled mode" (e.authMode === AuthMode.LIMITED), and you can access Properties.

    To fix that, you need to test if the add-on is installed or enabled, and show a menu option that allows the user to enable it if it is only installed. See the example below:

    function onOpen (e) {
      var menu = SpreadsheetApp.getUi().createAddonMenu(); // Or DocumentApp.
      if (e && e.authMode == ScriptApp.AuthMode.NONE) {
        // Add a normal menu item (works in all authorization modes).
        menu.addItem('Enable add-on', 'enableAddOn');
      } else {
        // Add a menu item based on properties (doesn't work in AuthMode.NONE).
        var properties = PropertiesService.getDocumentProperties();
        var workflowStarted = properties.getProperty('workflowStarted');
        if (workflowStarted) {
          menu.addItem('Check workflow status', 'checkWorkflow');
        } else {
          menu.addItem('Start workflow', 'startWorkflow');
        }
      }
      menu.addToUi();
    }
    
    function enableAddOn () {
      onOpen();
    }
    

    When it is only installed, user sees only the option "Enable add-on". By clicking on it, the add-on becomes enabled, so the function can simply call onOpen() and the if..else will load the correct menu options.

    Notice that you only need this fix because your simple trigger onOpen (e) is using the Properties service. If you remove that, there is no need to test the installed/enabled mode.