AI-generated Key Takeaways
- 
          Card-based add-ons use interactive widgets like buttons and menus to collect user input and enhance user interactions. 
- 
          Widgets are made interactive by linking them to actions, which trigger callback functions to execute specific behaviors when interacted with. 
- 
          When defining widget actions, you can specify a callback function and any necessary parameters using the Actionobject and appropriate handler functions.
- 
          For opening URLs, setOpenLink()orsetOnClickOpenLinkAction()can be used with anOpenLinkobject to define the URL and behavior.
- 
          Keep callback functions concise, as they have execution time limits, and consider using setStateChanged()to update the UI when backend data changes due to user interactions.
Most add-ons, in addition to presenting data, require the user to enter information. When you build a card-based add-on, you can use interactive widgets such as buttons, toolbar menu items, or checkboxes to ask the user for data that your add-on needs or provide other interaction controls.
Adding actions to widgets
For the most part, you make widgets interactive by linking them to specific actions and implementing the required behavior in a callback function. See add-on actions for details.
In most cases, you can follow this general procedure to configure a widget to take a specific action when selected or updated:
- Create an Actionobject, specifing the callback function that should execute, along with any required parameters.
- Link the widget to the Actionby calling the appropriate widget handler function.
- Implement the callback function to enact the required behavior.
Example
The following example sets a button that displays a user notification
after it is clicked. The click triggers the notifyUser() callback function
with an argument that specifies the notification text. Returning a built
ActionResponse
results in a displayed notification.
  /**
   * Build a simple card with a button that sends a notification.
   * @return {Card}
   */
  function buildSimpleCard() {
    var buttonAction = CardService.newAction()
        .setFunctionName('notifyUser')
        .setParameters({'notifyText': 'Button clicked!'});
    var button = CardService.newTextButton()
        .setText('Notify')
        .setOnClickAction(buttonAction);
    // ...continue creating widgets, then create a Card object
    // to add them to. Return the built Card object.
  }
  /**
   * Callback function for a button action. Constructs a
   * notification action response and returns it.
   * @param {Object} e the action event object
   * @return {ActionResponse}
   */
  function notifyUser(e) {
    var parameters = e.parameters;
    var notificationText = parameters['notifyText'];
    return CardService.newActionResponseBuilder()
        .setNotification(CardService.newNotification()
            .setText(notificationText))
        .build();      // Don't forget to build the response!
  }
Design effective interactions
When designing interactive cards, keep the following in mind:
- Interactive widgets usually need at least one handler method to define their behavior. 
- Use the - setOpenLink()widget handler function when you have a URL and just want to open it in a tab. This avoids the need to define an- Actionobject and callback function. If you need to build the URL first, or take any other additional steps before opening the URL, define an- Actionand use- setOnClickOpenLinkAction()instead.
- When using the - setOpenLink()or- setOnClickOpenLinkAction()widget handler functions, you need to provide an- OpenLinkobject to define which URL to open. You can also use this object to specify opening and closing behavior using the- OpenAsand- OnCloseenums.
- It is possible for more than one widget to use the same - Actionobject. However, you need to define different- Actionobjects if you want to provide the callback function different parameters.
- Keep your callback functions simple. To keep the add-ons responsive, the Card service limits callback functions to a maximum of 30 seconds of execution time. If the execution takes longer than that, your add-on UI may not update its card display properly in response to the - Action.
- If a data status on a third-party backend changes as the result of a user interaction with your add-on UI, it is recommended that the add-on set a 'state changed' bit to - trueso that any existing client side cache is cleared. See the- ActionResponseBuilder.setStateChanged()method description for additional details.