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
Action
object, specifing the callback function that should execute, along with any required parameters. - Link the widget to the
Action
by 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 anAction
object and callback function. If you need to build the URL first, or take any other additional steps before opening the URL, define anAction
and usesetOnClickOpenLinkAction()
instead.When using the
setOpenLink()
orsetOnClickOpenLinkAction()
widget handler functions, you need to provide anOpenLink
object to define which URL to open. You can also use this object to specify opening and closing behavior using theOpenAs
andOnClose
enums.It is possible for more than one widget to use the same
Action
object. However, you need to define differentAction
objects 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
true
so that any existing client side cache is cleared. See theActionResponseBuilder.setStateChanged()
method description for additional details.