Search code examples
google-apps-scriptgoogle-apps-script-addon

Google Apps Script - Add different menu item based on user settings in Properties service?


I'm working on a Form addon that needs 2 things:

  • On the first time that user opens the addon, he will see "Get Started" menu item, after that he will configure some settings in order to use the addon

  • After that, on the second time that he opens the addon menu, he will see other menu items such as "Feature 1", "Feature 2", ... and he won't see the "Get Started" menu item anymore because he has already configured the settings

I thought that it would related to the onOpen function. Here is what I tried:

const onOpen = () => {
  try {
    const userProperties = PropertiesService.getUserProperties()
    let isFinishedSetup = userProperties.getProperty('IS_FINISHED_SETUP')

    if (isFinishedSetup === '1') {
      FormApp.getUi()
        .createAddonMenu()
        .addItem('Feature One', 'featureOne')
        .addItem('Feature Two', 'featureTwo')
        .addToUi()
    } else {
      FormApp.getUi()
        .createAddonMenu()
        .addItem('Get Started', 'showGetStarted')
        .addToUi()
    }
  } catch (err) {
    FormApp.getUi()
      .createAddonMenu()
      .addItem('Get Started', 'showGetStarted')
      .addToUi()
  }
}

Basically, I try to get the IS_FINISHED_SETUP property from the PropertiesService, check if it's true.

In case it can not getUserProperties(), I handle it in the catch statement

But this won't work, the addon menu button doesn't show up.


In the console, I see the error you don't have the permission to call getUserProperties or something like that.

I searched Google and I found the reason is: the onOpen function can't use services that require scopes

But you can only authorize it after the menu is shown

So how can I handle this situation? I want different menus based on if user finished setup or not.


Solution

  • The answer is in this link https://developers.google.com/gsuite/add-ons/concepts/editor-auth-lifecycle#the_complete_lifecycle

    Thanks to @TheMaster

    const onOpen = (e) => {
      const menu = FormApp.getUi().createAddonMenu()
    
      if (e && e.authMode === ScriptApp.AuthMode.NONE) {
        // Add Get Started menu item (works in all authorization modes).
        menu.addItem('Get Started', 'showGetStarted')
      } else {
        // Add a menu item based on properties (doesn't work in AuthMode.NONE).
        const documentProperties = PropertiesService.getDocumentProperties()
    
        const isFinishedSetup = documentProperties.getProperty('isFinishedSetup')
    
        if (isFinishedSetup === '1') {
          menu.addItem('Feature One', 'featureOne')
          menu.addItem('Feature Two', 'featureTwo')
        } else {
          menu.addItem('Get Started', 'showGetStarted')
        }
      }
    
      menu.addToUi()
    }
    

    A note here when you try to test this by using "Test as add-on":

    You must manually choose the AuthMode when testing as add-on.

    If you choose AuthMode.NONE, it will NOT show anything other than Get Started menu item.

    You need to choose AuthMode.LIMITED

    enter image description here