This page describes how a Google Chat app can open dialogs to display user interfaces (UIs) and respond to users.
In Google Chat, add-ons appear to users as Google Chat apps. To learn more, see the Extend Google Chat overview.
Dialogs are windowed, card-based interfaces that open from a Chat space or message. The dialog and its contents are only visible to the user that opened it.
Chat apps can use dialogs to request and collect information from Chat users, including multi-step forms. For more details on building form inputs, see Collect and process information from users.
Prerequisites
Node.js
A Google Workspace add-on that extends Google Chat. To build one, complete the HTTP quickstart.
Apps Script
A Google Workspace add-on that extends Google Chat. To build one, complete the Apps Script quickstart.
Open a dialog
This section explains how to respond and set up a dialog by doing the following:
- Trigger the dialog request from a user interaction.
- Handle the request by returning and opening a dialog.
- After users submit information, process the submission by either closing the dialog or returning another dialog.
Trigger a dialog request
A Chat app can only open dialogs to respond to a user interaction, such as a quick command, slash command, or a button click from a message in a card.
To respond to users with a dialog, a Chat app must build an interaction that triggers the dialog request, such as the following:
- Respond to a quick command or a slash command. To trigger the request from a quick command or a slash command, you must check the Opens a dialog checkbox when configuring the quick command or slash command.
- Respond to a button click in a
message,
either as part of a card or at the bottom of the message. To trigger the
request from a button in a message, you configure the
button's
onClick
action by setting itsinteraction
toOPEN_DIALOG
.
The following JSON shows how to trigger a dialog request from a button in a
card message. To open the dialog, set the field
onClick.action.interaction
of the button to OPEN_DIALOG
:
{
"buttonList": { "buttons": [{
"text": "BUTTON_TEXT",
"onClick": { "action": {
"function": "ACTION_FUNCTION",
"interaction": "OPEN_DIALOG"
}}
}]}
}
Where BUTTON_TEXT is the text that displays in the button and ACTION_FUNCTION is the function that runs to open the initial dialog.
Open the initial dialog
When a user triggers a dialog request, your Chat app
receives an
event object with a
payload that specifies that an dialogEventType
object as REQUEST_DIALOG
.
To open a dialog, your Chat app can respond to the
request by returning a
RenderActions
object with the navigation pushCard
to display a card. The card should contain
any user interface (UI) elements, including one or more
sections[]
of widgets. To collect information from users, you can specify form input
widgets and a button widget. To learn more about designing form inputs, see
Collect and process information from users.
The following JSON shows how a Chat app returns a response that opens a dialog:
{
"action": { "navigations": [{ "pushCard": { "sections": [{ "widgets": [{
WIDGETS,
{ "buttonList": { "buttons": [{
"text": "BUTTON_TEXT",
"onClick": {
"action": { "function": "ACTION_FUNCTION" }
}
}]}}
}]}]}}]}
}
Where BUTTON_TEXT is the text that displays in the button (such as
Next
or Submit
), WIDGETS represents one or more
form input widgets,
and ACTION_FUNCTION is the action's
callback function
that runs when users click a button.
Handle the dialog submission
When users click a button that submits a dialog, your
Chat app receives an event object with an
ButtonClickedPayload
object. In the payload, the dialogEventType
is set to SUBMIT_DIALOG
.
Your Chat app must handle the event object by doing one of the following:
- Return another dialog to populate another card or form.
- Close the dialog after validating the data the user submitted, and optionally, send a confirmation message.
Optional: Return another dialog
After users submit the initial dialog, Chat apps can return one or more additional dialogs to help users review information before submitting, complete multi-step forms, or populate form content dynamically.
To process the data that users input, the Chat app
handles the data in the event's
commonEventObject.formInputs
object. To learn more about retrieving values from input widgets, see
Collect and process information from users.
To keep track of any data that users input from the initial dialog, you must add parameters to the button that opens the next dialog. For details, see Transfer data to another card.
In this example, a Chat app opens an initial dialog that leads to a second dialog for confirmation before submitting:
Node.js
/**
* Google Cloud Function that handles all Google Workspace Add On events for
* the contact manager app.
*
* @param {Object} req Request sent from Google Chat space
* @param {Object} res Response to send back
*/
exports.contactManager = function contactManager(req, res) {
const chatEvent = req.body.chat;
// Handle MESSAGE events
if(chatEvent.messagePayload) {
return res.send(handleMessage(req.body));
// Handle button clicks
} else if(chatEvent.buttonClickedPayload) {
switch(req.body.commonEventObject.parameters.actionName) {
case "openInitialDialog":
return res.send(openInitialDialog(req.body));
case "openConfirmationDialog":
return res.send(openConfirmationDialog(req.body));
case "submitDialog":
return res.send(submitDialog(req.body));
}
}
};
/**
* Responds to a message in Google Chat.
*
* @param {Object} event The event object from the Google Workspace Add-on.
* @return {Object} response that handles dialogs.
*/
function handleMessage(event) {
// Reply with a message that contains a button to open the initial dialog
return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
text: "To add a contact, use the `ADD CONTACT` button below.",
accessoryWidgets: [{ buttonList: { buttons: [{
text: "ADD CONTACT",
onClick: { action: {
// Use runtime environment variable set with self URL
function: process.env.BASE_URL,
parameters: [{ key: "actionName", value: "openInitialDialog" }],
interaction: "OPEN_DIALOG"
}}
}]}}]
}}}}};
}
/**
* Opens the initial step of the dialog that lets users add contact details.
*
* @param {Object} event The event object from the Google Workspace Add-on.
* @return {Object} open the dialog.
*/
function openInitialDialog(event) {
return { action: { navigations: [{ pushCard: { sections: [{ widgets: [{
textInput: {
name: "contactName",
label: "First and last name",
type: "SINGLE_LINE"
}},
WIDGETS, {
buttonList: { buttons: [{
text: "NEXT",
onClick: { action: {
// Use runtime environment variable set with self URL
function: process.env.BASE_URL,
parameters: [{ key: "actionName", value: "openConfirmationDialog" }]
}}
}]}}
]}]}}]}};
}
/**
* Opens the second step of the dialog that lets users confirm details.
*
* @param {Object} event The event object from the Google Workspace Add-on.
* @return {Object} update the dialog.
*/
function openConfirmationDialog(event) {
// Retrieve the form input values
const name = event.commonEventObject.formInputs["contactName"].stringInputs.value[0];
return { action: { navigations: [{ pushCard: { sections: [{ widgets: [{
// Display the input values for confirmation
textParagraph: { text: "<b>Name:</b> " + name }},
WIDGETS, {
buttonList: { buttons: [{
text: "SUBMIT",
onClick: { action: {
// Use runtime environment variable set with self URL
function: process.env.BASE_URL,
parameters: [{
key: "actionName", value: "submitDialog" }, {
// Pass input values as parameters for last dialog step (submission)
key: "contactName", value: name
}]
}}
}]}}]
}]}}]}};
}
Apps Script
This example sends a card message by returning card JSON. You can also use the Apps Script card service.
/**
* Responds to a message in Google Chat.
*
* @param {Object} event The event object from the Google Workspace Add-on.
* @return {Object} response that handles dialogs.
*/
function onMessage(event) {
// Reply with a message that contains a button to open the initial dialog
return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
text: "To add a contact, use the `ADD CONTACT` button below.",
accessoryWidgets: [{ buttonList: { buttons: [{
text: "ADD CONTACT",
onClick: { action: {
function: "openInitialDialog",
interaction: "OPEN_DIALOG"
}}
}]}}]
}}}}};
}
/**
* Opens the initial step of the dialog that lets users add contact details.
*
* @param {Object} event The event object from the Google Workspace Add-on.
* @return {Object} open the dialog.
*/
function openInitialDialog(event) {
return { action: { navigations: [{ pushCard: { sections: [{ widgets: [{
textInput: {
name: "contactName",
label: "First and last name",
type: "SINGLE_LINE"
}},
WIDGETS, {
buttonList: { buttons: [{
text: "NEXT",
onClick: { action: { function : "openConfirmationDialog" }}
}]}}
]}]}}]}};
}
/**
* Opens the second step of the dialog that lets users confirm details.
*
* @param {Object} event The event object from the Google Workspace Add-on.
* @return {Object} update the dialog.
*/
function openConfirmationDialog(event) {
// Retrieve the form input values
const name = event.commonEventObject.formInputs["contactName"].stringInputs.value[0];
return { action: { navigations: [{ pushCard: { sections: [{ widgets: [{
// Display the input values for confirmation
textParagraph: { text: "<b>Name:</b> " + name }},
WIDGETS, {
buttonList: { buttons: [{
text: "SUBMIT",
onClick: { action: {
function: "submitDialog",
// Pass input values as parameters for last dialog step (submission)
parameters: [{ key: "contactName", value: name }]
}}
}]}}]
}]}}]}};
}
Where WIDGETS represents any other form input widgets.
Close the dialog
When users click a submit button on a dialog, your
Chat app executes its associated action and provides
the event object with buttonClickedPayload
set to the following:
isDialogEvent
istrue
.dialogEventType
isSUBMIT_DIALOG
.
The Chat app should return a
RenderActions
object with
EndNavigation
set to CLOSE_DIALOG
.
Optional: Display a notification
When you close the dialog, you can also display a text notification.
To display a notification, return the
RenderActions
object with the field notification
set.
The following example checks that parameters are valid and closes the dialog with text notification depending on the outcome:
Node.js
/**
* Handles submission and closes the dialog.
*
* @param {Object} event The event object from the Google Workspace Add-on.
* @return {Object} close the dialog with a status in text notification.
*/
function submitDialog(event) {
// Validate the parameters.
if (!event.commonEventObject.parameters["contactName"]) {
return { action: {
navigations: [{ endNavigation: "CLOSE_DIALOG"}],
notification: { text: "Failure, the contact name was missing!" }
}};
}
return { action: {
navigations: [{ endNavigation: "CLOSE_DIALOG"}],
notification: { text: "Success, the contact was added!" }
}};
}
Apps Script
/**
* Handles submission and closes the dialog.
*
* @param {Object} event The event object from the Google Workspace Add-on.
* @return {Object} close the dialog with a status in text notification.
*/
function submitDialog(event) {
// Validate the parameters.
if (!event.commonEventObject.parameters["contactName"]) {
return { action: {
navigations: [{ endNavigation: "CLOSE_DIALOG"}],
notification: { text: "Failure, the contact name was missing!" }
}};
}
return { action: {
navigations: [{ endNavigation: "CLOSE_DIALOG"}],
notification: { text: "Success, the contact was added!" }
}};
}
For details about passing parameters between dialogs, see Transfer data to another card.
Optional: Send a confirmation message
When you close the dialog, you can also send a new message, or update an existing one.
To send a new message, return a
DataActions
object with the field
CreateMessageAction
set with the new message. For example, to close the dialog
and send a text message, return the following:
{ "hostAppDataAction": { "chatDataAction": { "createMessageAction": { "message": {
"text": "Your information has been submitted."
}}}}}
To update a message after the user submits a dialog, return a DataActions
object that contains one of the following actions:
UpdateMessageAction
: Updates a message sent by the Chat app, such as the message from which the user requested the dialog.UpdateInlinePreviewAction
: Updates the card from a link preview.
Troubleshoot
When a Google Chat app or card returns an error, the Chat interface surfaces a message saying "Something went wrong." or "Unable to process your request." Sometimes the Chat UI doesn't display any error message, but the Chat app or card produces an unexpected result; for example, a card message might not appear.
Although an error message might not display in the Chat UI, descriptive error messages and log data are available to help you fix errors when error logging for Chat apps is turned on. For help viewing, debugging, and fixing errors, see Troubleshoot and fix Google Chat errors.