Gmail Add-Ons onTriggerFunction only ran once per email even if opening the email again

后端 未结 2 806
终归单人心
终归单人心 2021-02-05 18:34

We\'re building a Gmail Add-On however we wish to show a different card on depending on some business logic when the add-on\'s onTriggerFunction is called. This wor

相关标签:
2条回答
  • 2021-02-05 18:44

    There are a couple ways you can reload the UI of a card. Both of them have to happen in an ActionResponse.

    The first is if you want to reload the current card as the result of some state change caused by a user action:

    function buildCounterCard() {
      const card = CardService.newCardBuilder().setName('Counter');
    
      const count = CountApi.get(); // Or however you get this data
    
      const countWidget = CardService.newKeyValue().setTopLabel('Current Count').setContent(`${count}`);
    
      const incrementAction = CardService.newAction().setFunctionName('handleIncrement');
      const incrementButton = CardService.newTextButton().setText('Increment').setOnClickAction(incrementAction);
    
      const section = CardService.newCardSection().addWidget(countWidget).addWidget(incrementButton);
    
      card.addSection(section);
    
      return card.build();
    }
    
    function handleIncrement() {
      const actionResponse = CardService.newActionResponseBuilder();
    
      CountApi.update(); // Or however you update the data
    
      const nav = CardService.newNavigation().updateCard(buildCounterCard());
      actionResponse.setNavigation(nav);
    
      return actionResponse.build();
    }
    

    The only other way I've found so far is to update the previous card in the Navigation stack. Imagine the following scenario:

    1. User fills out a form and clicks "Save"
    2. Script posts the data to the API and on success pushes a "Success" card on to the stack.
    3. User sees the "Success" card with a message letting them know the data was saved and a button to go "Back" or "Home".

    The action handler for that button could look something like this:

    function handleBackClick(event) {
      const actionResponse = CardService.newActionResponseBuilder();
    
      clearPreviousCardState() // Otherwise the user sees the same data they filled out previously when they go back to the form
    
      const nav = CardService.newNavigation()
        .popCard()
        .updateCard(buildPreviousCard(event))
        .popToRoot();
      actionResponse.setNavigation(nav);
    
      return actionResponse.build();
    }
    

    For whatever reason this works, but updating multiple cards by chaining navigation steps along with updateCard() does not.

    Seems like these are the only options right now. I find it pretty crazy that there's a Linear Optimization Service, but not a way to reload the UI. A commenter mentioned ActionResponseBuilder.setStateChanged(true), which sounds like what we want based on the documentation, but in my experience, it does absolutely nothing.

    0 讨论(0)
  • 2021-02-05 18:50

    Unfortunately there is no way at the moment (July 2019) to force the trigger to run every time the email is opened. You can use ActionResponseBuilder.setStateChanged(true) as a response to a button click to instruct Gmail to clear the cache, but it can't be sent along with a normal card response.

    0 讨论(0)
提交回复
热议问题