Trang này mô tả cách ứng dụng Chat có thể mở và phản hồi hộp thoại.
Hộp thoại là giao diện cửa sổ dựa trên thẻ Các ứng dụng trong Chat mở để tương tác với người dùng. Để giúp người dùng hoàn tất quy trình nhiều bước, ứng dụng Chat có thể mở theo tuần tự .
Hộp thoại hữu ích cho các kiểu tương tác sau đây của người dùng:
- Thu thập thông tin từ người dùng
- Xác thực người dùng bằng các dịch vụ web
- Định cấu hình chế độ cài đặt ứng dụng Chat
Để mở, gửi hoặc huỷ hộp thoại, bạn phải có phản hồi đồng bộ
từ ứng dụng Chat có
DialogEventType
.
Các ứng dụng Chat không hỗ trợ hộp thoại
được tạo bằng cấu trúc không đồng bộ, chẳng hạn như
Pub/Sub hoặc
create
thư
. Nếu ứng dụng Chat của bạn sử dụng
hãy sử dụng
thông báo thẻ
thay vì một hộp thoại.
Điều kiện tiên quyết
Node.js
Một ứng dụng Google Chat đã bật các tính năng tương tác. Để tạo một ứng dụng Chat tương tác bằng dịch vụ HTTP, hãy hoàn thành phần bắt đầu nhanh này.
Apps Script
Một ứng dụng Google Chat đã bật các tính năng tương tác. Để tạo một ứng dụng Chat tương tác trong Apps Script, hãy hoàn thành phần bắt đầu nhanh này.
Python
Một ứng dụng Google Chat đã bật các tính năng tương tác. Để tạo một ứng dụng Chat tương tác bằng dịch vụ HTTP, hãy hoàn thành phần bắt đầu nhanh này.
Mở hộp thoại
Ứng dụng Chat có thể mở một hộp thoại để phản hồi người dùng nhấp vào một nút trên thông báo thẻ.
![Nhấp vào một nút trên thẻ để mở hộp thoại.](https://developers-dot-devsite-v2-prod.appspot.com/static/workspace/chat/images/dialogs-open-card-click.png?authuser=6&hl=vi)
Ứng dụng Chat có thể mở một hộp thoại để phản hồi người dùng cấp một lệnh dấu gạch chéo.
![Nhấp vào một nút trên thẻ để mở hộp thoại.](https://developers-dot-devsite-v2-prod.appspot.com/static/workspace/chat/images/dialogs-open-slash-command.png?authuser=6&hl=vi)
Khi người dùng mở hộp thoại, ứng dụng Chat của bạn sẽ nhận được một sự kiện tương tác với: của bạn:
isDialogEvent
làtrue
.DialogEventType
chỉ định một trong các hành động sau đây mà người dùng đã thực hiện:REQUEST_DIALOG
: Đã mở một hộp thoại.SUBMIT_DIALOG
: Đã nhấp vào một nút trong hộp thoại.CANCEL_DIALOG
: Đã huỷ một hộp thoại.
Ví dụ: khi người dùng mở hộp thoại, ứng dụng Chat của bạn sẽ nhận được một sự kiện tương tác tương tự như sau:
JSON
{
"type": enum (EventType),
"eventTime": string,
"threadKey": string,
"message": {
object (Message)
},
"user": {
object (User)
},
"space": {
object (Space)
},
"action": {
object (FormAction)
},
"configCompleteRedirectUrl": string,
"isDialogEvent": true,
"dialogEventType": "REQUEST_DIALOG",
"common": {
object (CommonEventObject)
}
}
Ứng dụng Chat có thể mở hộp thoại bằng cách trả về một
ActionResponse
của "type": "DIALOG"
có
DialogAction
có chứa nội dung mô tả JSON của hộp thoại:
JSON
{
"action_response": {
"type": "DIALOG",
"dialog_action": {
"dialog": {
"body": {
"sections": [
{
"header": "Add new contact",
"widgets": [
{
"textInput": {
"label": "Name",
"type": "SINGLE_LINE",
"name": "contactName"
}
},
{
"textInput": {
"label": "Address",
"type": "MULTIPLE_LINE",
"name": "address"
}
},
{
"decoratedText": {
"text": "Add to favorites",
"switchControl": {
"controlType": "SWITCH",
"name": "saveFavorite"
}
}
},
{
"decoratedText": {
"text": "Merge with existing contacts",
"switchControl": {
"controlType": "SWITCH",
"name": "mergeContact",
"selected": true
}
}
},
{
"buttonList": {
"buttons": [
{
"text": "Next",
"onClick": {
"action": {
"function": "openSequentialDialog"
}
}
}
]
}
}
]
}
]
}
}
}
}
}
Mở hộp thoại để phản hồi lại nhấp chuột vào nút thẻ
Để tạo nút thẻ, hãy mở hộp thoại, hãy chỉ định những thông tin sau:
onClick.action.function
dưới dạng tên của hàm mở ra hộp thoại.onClick.action.interaction
dưới dạngOPEN_DIALOG
. Tài sản này cho Chat biết rằng Ứng dụng Chat muốn mở một hộp thoại.
Khi người dùng nhấp vào một nút trên một thẻ, ứng dụng Chat của bạn sẽ nhận được một sự kiện tương tác có thông tin sau:
EventType
làCARD_CLICKED
.DialogEventType
làREQUEST_DIALOG
.common.invokedFunction
là tên của hàm trong thuộc tínhonClick
của lượt nhấp .
Để mở hộp thoại, hãy trả lời như sau:
- Một
ActionResponse
trong tổng số"type": "DIALOG"
. - Đáp
DialogAction
có chứa nội dung mô tả JSON của hộp thoại.
Trong ví dụ này, ứng dụng Chat phản hồi một MESSAGE
sự kiện tương tác bằng thẻ có nút mở hộp thoại:
Node.js
/**
* Responds to messages that have links whose URLs
* match URL patterns configured for link previews.
*
* @param {Object} event The event object from Chat
* API.
*
* @return {Object} Response from the Chat app
* attached to the message with the previewed link.
*/
exports.onMessage = function onMessage(req, res) {
// Store the Google Chat event as a variable.
const event = req.body;
if (req.method === "GET" || !event.message) {
res.send("Hello! This function is meant to be used in a Google Chat " +
"Space.");
}
// Responds with a card that prompts the user to add a contact
else {
res.json({
"cardsV2": [{
"cardId": "addContact",
"card": {
"header": {
"title": "Rolodex",
"subtitle": "Manage your contacts!",
"imageUrl": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
"imageType": "CIRCLE"
},
"sections": [
{
"widgets": [
{
"buttonList": {
"buttons": [
{
"text": "Add Contact",
"onClick": {
"action": {
"function": "openDialog",
"interaction": "OPEN_DIALOG"
}
}
}
]
}
}
]
}
]
}
}]
});
}
// Respond to button clicks on attached cards
if (event.type === "CARD_CLICKED") {
if (event.common.invokedFunction === "openDialog") {
openDialog(event);
};
/**
* Opens and starts a dialog that lets users add details about a contact.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openDialog(event) {
res.json({
"action_response": {
"type": "DIALOG",
"dialog_action": {
"dialog": {
"body": {
"sections": [
{
"header": "Add new contact",
"widgets": [
{
"textInput": {
"label": "Name",
"type": "SINGLE_LINE",
"name": "name"
}
},
{
"textInput": {
"label": "Address",
"type": "MULTIPLE_LINE",
"name": "address"
}
},
{
"decoratedText": {
"text": "Add to favorites",
"switchControl": {
"controlType": "SWITCH",
"name": "saveFavorite"
}
}
},
{
"decoratedText": {
"text": "Merge with existing contacts",
"switchControl": {
"controlType": "SWITCH",
"name": "mergeContact",
"selected": true
}
}
},
{
"buttonList": {
"buttons": [
{
"text": "Next",
"onClick": {
"action": {
"function": "openSequentialDialog"
}
}
}
]
}
}
]
}
]
}
}
}
}
});
};
}
}
Apps Script
Ví dụ này gửi thông báo thẻ bằng cách quay lại tệp JSON của thẻ. Bạn cũng có thể sử dụng Dịch vụ thẻ Apps Script.
/**
* Responds to a MESSAGE event in Google Chat with a card with a button
* that opens a dialog.
*
* @param {Object} event the event object from Chat API.
*
* @return {object} open a Dialog in response to a card's button click.
*/
function onMessage(event) {
return {
"cardsV2": [{
"cardId": "addContact",
"card": {
"header": {
"title": "Rolodex",
"subtitle": "Manage your contacts!",
"imageUrl": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
"imageType": "CIRCLE"
},
"sections": [
{
"widgets": [
{
"buttonList": {
"buttons": [
{
"text": "Add Contact",
"onClick": {
"action": {
"function": "openDialog",
"interaction": "OPEN_DIALOG"
}
}
}
]
},
"horizontalAlignment": "CENTER"
}
]
}
]
}
}]
};
}
/**
* Responds to a CARD_CLICKED event in Google Chat.
*
* @param {Object} event the event object from Google Chat
*/
function onCardClick(event) {
if (event.common.invokedFunction === "openDialog") {
return openDialog(event);
}
}
/**
* Opens a dialog in Google Chat.
*
* @param {Object} event the event object from Chat API.
*
* @return {object} open a Dialog in Google Chat.
*/
function openDialog(event) {
return {
"action_response": {
"type": "DIALOG",
"dialog_action": {
"dialog": {
"body": {
"sections": [
{
"header": "Add new contact",
"widgets": [
{
"textInput": {
"label": "Name",
"type": "SINGLE_LINE",
"name": "contactName"
}
},
{
"textInput": {
"label": "Address",
"type": "MULTIPLE_LINE",
"name": "address"
}
},
{
"decoratedText": {
"text": "Add to favorites",
"switchControl": {
"controlType": "SWITCH",
"name": "saveFavorite"
}
}
},
{
"decoratedText": {
"text": "Merge with existing contacts",
"switchControl": {
"controlType": "SWITCH",
"name": "mergeContact",
"selected": true
}
}
},
{
"buttonList": {
"buttons": [
{
"text": "Next",
"onClick": {
"action": {
"function": "openSequentialDialog"
}
}
}
]
}
}
]
}
]
}
}
}
}
};
}
Python
from typing import Any, Mapping
import flask
import functions_framework
@functions_framework.http
def main(req: flask.Request) -> Mapping[str, Any]:
"""Responds to a MESSAGE event in Google Chat that includes the /createContact
slash command by opening a dialog.
Args:
req (flask.Request): the event object from Chat API.
Returns:
Mapping[str, Any]: open a Dialog in response to a card's button click.
"""
if req.method == 'GET':
return 'Sorry, this function must be called from a Google Chat.'
request = req.get_json(silent=True)
if request.get('type') == 'CARD_CLICKED':
if request.get('common', dict()).get('invokedFunction') == 'open_dialog':
return open_dialog(request)
else:
return {
'cardsV2': [{
'cardId': 'addContact',
'card': {
'header': {
'title': 'Rolodex',
'subtitle': 'Manage your contacts!',
'imageUrl': 'https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png',
'imageType': 'CIRCLE'
},
'sections': [
{
'widgets': [
{
'buttonList': {
'buttons': [
{
'text': 'Add Contact',
'onClick': {
'action': {
'function': 'open_dialog',
'interaction': 'OPEN_DIALOG'
}
}
}
]
}
}
]
}
]
}
}]
}
def open_dialog(request: Mapping[str, Any]) -> Mapping[str, Any]:
"""Opens a dialog in Google Chat.
Args:
request (Mapping[str, Any]): the event object from Chat API.
Returns:
Mapping[str, Any]: open a Dialog in response to a card's button click.
"""
return {
'action_response': {
'type': 'DIALOG',
'dialog_action': {
'dialog': {
'body': {
'sections': [
{
'header': 'Add new contact',
'widgets': [
{
'textInput': {
'label': 'Name',
'type': 'SINGLE_LINE',
'name': 'name'
}
},
{
'textInput': {
'label': 'Address',
'type': 'MULTIPLE_LINE',
'name': 'address'
}
},
{
'decoratedText': {
'text': 'Add to favorites',
'switchControl': {
'controlType': 'SWITCH',
'name': 'saveFavorite'
}
}
},
{
'decoratedText': {
'text': 'Merge with existing contacts',
'switchControl': {
'controlType': 'SWITCH',
'name': 'mergeContact',
'selected': True
}
}
},
{
'buttonList': {
'buttons': [
{
'text': 'Next',
'onClick': {
'action': {
'function': 'open_sequential_dialog'
}
}
}
]
}
}
]
}
]
}
}
}
}
}
Mở hộp thoại để phản hồi lệnh dấu gạch chéo
Khi người dùng mở hộp thoại có lệnh dấu gạch chéo được định cấu hình để mở hộp thoại, ứng dụng Chat của bạn nhận được một sự kiện tương tác với các thông tin sau:
EventType
làMESSAGE
.DialogEventType
làREQUEST_DIALOG
.
Để mở hộp thoại, bạn phải định cấu hình lệnh dấu gạch chéo bằng cách chọn hộp đánh dấu Mở hộp thoại. Sau đó, hãy trả lời như sau:
- Một
ActionResponse
trong tổng số"type": "DIALOG"
. DialogAction
có chứa nội dung mô tả JSON của hộp thoại.
Trong ví dụ này, ứng dụng Chat phản hồi
Lệnh dấu gạch chéo /createContact
bằng cách mở một hộp thoại:
Node.js
/**
* Responds to messages that have links whose URLs
* match URL patterns configured for link previews.
*
* @param {Object} event The event object from Chat
* API.
*
* @return {Object} Response from the Chat app
* attached to the message with the previewed link.
*/
exports.onMessage = function onMessage(req, res) {
// Store the Google Chat event as a variable.
const event = req.body;
if (req.method === "GET" || !event.message) {
res.send("Hello! This function is meant to be used in a Google Chat " +
"Space.");
}
// Checks for the presence of event.message.slashCommand.
// If the slash command is "/help", responds with a text message.
// If the slash command is "/createContact", opens a dialog.
if (event.message.slashCommand) {
switch (event.message.slashCommand.commandId) {
case 1: // /help
res.json({"text": "Contact bot helps you update your address book!"});
case 2: // /createContact
openDialog(event);
}
}
};
/**
* Opens and starts a dialog that lets users add details about a contact.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openDialog(event) {
res.json({
"action_response": {
"type": "DIALOG",
"dialog_action": {
"dialog": {
"body": {
"sections": [
{
"header": "Add new contact",
"widgets": [
{
"textInput": {
"label": "Name",
"type": "SINGLE_LINE",
"name": "name"
}
},
{
"textInput": {
"label": "Address",
"type": "MULTIPLE_LINE",
"name": "address"
}
},
{
"decoratedText": {
"text": "Add to favorites",
"switchControl": {
"controlType": "SWITCH",
"name": "saveFavorite"
}
}
},
{
"decoratedText": {
"text": "Merge with existing contacts",
"switchControl": {
"controlType": "SWITCH",
"name": "mergeContact",
"selected": true
}
}
},
{
"buttonList": {
"buttons": [
{
"text": "Next",
"onClick": {
"action": {
"function": "openSequentialDialog"
}
}
}
]
}
}
]
}
]
}
}
}
}
});
};
Apps Script
Ví dụ này gửi thông báo thẻ bằng cách quay lại tệp JSON của thẻ. Bạn cũng có thể sử dụng Dịch vụ thẻ Apps Script.
/**
* Responds to a MESSAGE event in Google Chat that includes the /createContact
* slash command by opening a dialog.
*
* @param {Object} event the event object from Chat API.
*
* @return {object} open a Dialog in response to a slash command.
*/
function onMessage(event) {
// Checks for the presence of event.message.slashCommand.
// If the slash command is "/help", responds with a text message.
// If the slash command is "/createContact", opens a dialog.
if (event.message.slashCommand) {
switch (event.message.slashCommand.commandId) {
case 1: // /help
return {"text": "Contact bot helps you update your address book!"}
case 2: // /createContact
return openDialog(event);
}
}
}
/**
* Opens a dialog in Google Chat.
*
* @param {Object} event the event object from Chat API.
*
* @return {object} open a Dialog in Google Chat.
*/
function openDialog(event) {
return {
"action_response": {
"type": "DIALOG",
"dialog_action": {
"dialog": {
"body": {
"sections": [
{
"header": "Add new contact",
"widgets": [
{
"textInput": {
"label": "Name",
"type": "SINGLE_LINE",
"name": "contactName"
}
},
{
"textInput": {
"label": "Address",
"type": "MULTIPLE_LINE",
"name": "address"
}
},
{
"decoratedText": {
"text": "Add to favorites",
"switchControl": {
"controlType": "SWITCH",
"name": "saveFavorite"
}
}
},
{
"decoratedText": {
"text": "Merge with existing contacts",
"switchControl": {
"controlType": "SWITCH",
"name": "mergeContact",
"selected": true
}
}
},
{
"buttonList": {
"buttons": [
{
"text": "Next",
"onClick": {
"action": {
"function": "openSequentialDialog"
}
}
}
]
}
}
]
}
]
}
}
}
}
};
}
Python
from typing import Any, Mapping
import flask
import functions_framework
@functions_framework.http
def main(req: flask.Request) -> Mapping[str, Any]:
"""Responds to a MESSAGE event in Google Chat that includes the /createContact
slash command by opening a dialog.
Args:
req (flask.Request): the event object from Chat API.
Returns:
Mapping[str, Any]: open a Dialog in response to a slash command.
"""
if req.method == 'GET':
return 'Sorry, this function must be called from a Google Chat.'
request = req.get_json(silent=True)
if slash_command := request.get('message', dict()).get('slashCommand'):
command_id = slash_command['commandId']
if command_id == 1:
return {'text': 'Contact bot helps you update your address book!'}
elif command_id == 2:
return open_dialog(request)
def open_dialog(request: Mapping[str, Any]) -> Mapping[str, Any]:
"""Opens a dialog in Google Chat.
Args:
request (Mapping[str, Any]): the event object from Chat API.
Returns:
Mapping[str, Any]: open a Dialog in response to a slash command.
"""
return {
'action_response': {
'type': 'DIALOG',
'dialog_action': {
'dialog': {
'body': {
'sections': [
{
'header': 'Add new contact',
'widgets': [
{
'textInput': {
'label': 'Name',
'type': 'SINGLE_LINE',
'name': 'name'
}
},
{
'textInput': {
'label': 'Address',
'type': 'MULTIPLE_LINE',
'name': 'address'
}
},
{
'decoratedText': {
'text': 'Add to favorites',
'switchControl': {
'controlType': 'SWITCH',
'name': 'saveFavorite'
}
}
},
{
'decoratedText': {
'text': 'Merge with existing contacts',
'switchControl': {
'controlType': 'SWITCH',
'name': 'mergeContact',
'selected': True
}
}
},
{
'buttonList': {
'buttons': [
{
'text': 'Next',
'onClick': {
'action': {
'function': 'open_sequential_dialog'
}
}
}
]
}
}
]
}
]
}
}
}
}
}
Mở hộp thoại tuần tự
Khi hoạt động tương tác của người dùng cần có nhiều hộp thoại, bạn có thể mở một hộp thoại khác
bằng cách trả về hộp thoại tiếp theo trong trình tự để phản hồi một SUBMIT_DIALOG
DialogEventType
.
![Một hộp thoại hiển thị nhiều tiện ích.](https://developers-dot-devsite-v2-prod.appspot.com/static/workspace/chat/images/dialogs-card-1.png?authuser=6&hl=vi)
Trong nút thẻ cập nhật hộp thoại, hãy quay lại
onClick.action.function
đóng vai trò là
tên của một hàm mở ra hộp thoại tiếp theo và giữ lại
onClick.action.interaction
chưa chỉ định.
![Một hộp thoại hiển thị nhiều tiện ích.](https://developers-dot-devsite-v2-prod.appspot.com/static/workspace/chat/images/dialogs-card-2.png?authuser=6&hl=vi)
Sau khi hoàn tất, ứng dụng Chat sẽ nhận được các giá trị mà người dùng sử dụng đã nhập vào hộp thoại dưới dạng JSON. Thông báo cho người dùng rằng tương tác của họ đã thành công bằng trả lời bằng tin nhắn văn bản hoặc tin nhắn thẻ.
Khi người dùng nhấp vào một nút trong hộp thoại, ứng dụng Chat của bạn sẽ nhận được một sự kiện tương tác có thông tin sau:
EventType
làCARD_CLICKED
.DialogEventType
làSUBMIT_DIALOG
.
Trong ví dụ này, ứng dụng Chat phản hồi một
CARD_CLICKED
sự kiện tương tác từ một lượt nhấp vào nút hộp thoại bằng cách mở một sự kiện tương tác khác
hộp thoại:
Node.js
// Respond to button clicks on attached cards
if (event.type === "CARD_CLICKED") {
// Open the first dialog.
if (event.common.invokedFunction === "openDialog") {
openDialog(event);
}
// Open the second dialog.
if (event.common.invokedFunction === "openSequentialDialog") {
openSequentialDialog(event);
}
}
/**
* Opens and starts a dialog that lets users add details about a contact.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openDialog(event) {
res.json({
"action_response": {
"type": "DIALOG",
"dialog_action": {
"dialog": {
"body": {
"sections": [
{
"header": "Add new contact",
"widgets": [
{
"textInput": {
"label": "Name",
"type": "SINGLE_LINE",
"name": "name"
}
},
{
"textInput": {
"label": "Address",
"type": "MULTIPLE_LINE",
"name": "address"
}
},
{
"decoratedText": {
"text": "Add to favorites",
"switchControl": {
"controlType": "SWITCH",
"name": "saveFavorite"
}
}
},
{
"decoratedText": {
"text": "Merge with existing contacts",
"switchControl": {
"controlType": "SWITCH",
"name": "mergeContact",
"selected": true
}
}
},
{
"buttonList": {
"buttons": [
{
"text": "Next",
"onClick": {
"action": {
"function": "openSequentialDialog"
}
}
}
]
}
}
]
}
]
}
}
}
}
});
};
/**
* Opens a second dialog that lets users add more contact details.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openSequentialDialog(event) {
res.json({
"action_response": {
"type": "DIALOG",
"dialog_action": {
"dialog": {
"body": {
"sections": [
{
"header": "Add new contact",
"widgets": [
{
"textInput": {
"label": "Notes",
"type": "MULTIPLE_LINE",
"name": "notes"
}
},
{
"selectionInput": {
"type": "RADIO_BUTTON",
"label": "Contact type",
"name": "contactType",
"items": [
{
"text": "Work",
"value": "Work",
"selected": false
},
{
"text": "Personal",
"value": "Personal",
"selected": false
}
]
}
},
{
"buttonList": {
"buttons": [
{
"text": "Submit",
"onClick": {
"action": {
"function": "confirmDialogSuccess",
"parameters": [
{
"key": "confirmDialogSuccess",
"value": "confirmDialogSuccess"
}
]
}
}
}
]
},
"horizontalAlignment": "END"
}
]
}
]
}
}
}
}
});
}
Apps Script
Ví dụ này gửi thông báo thẻ bằng cách quay lại tệp JSON của thẻ. Bạn cũng có thể sử dụng Dịch vụ thẻ Apps Script.
/**
* Responds to a CARD_CLICKED event in Google Chat.
*
* @param {Object} event the event object from Google Chat
*/
function onCardClick(event) {
// When a user clicks a card, the Chat app checks to see which function to run.
if (event.common.invokedFunction === "openDialog") {
return openDialog(event);
}
if (event.common.invokedFunction === "openSequentialDialog") {
return openSequentialDialog(event);
}
}
/**
* Opens and starts a dialog that lets users add details about a contact.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openDialog(event) {
return {
"action_response": {
"type": "DIALOG",
"dialog_action": {
"dialog": {
"body": {
"sections": [
{
"header": "Add new contact",
"widgets": [
{
"textInput": {
"label": "Name",
"type": "SINGLE_LINE",
"name": "contactName"
}
},
{
"textInput": {
"label": "Address",
"type": "MULTIPLE_LINE",
"name": "address"
}
},
{
"decoratedText": {
"text": "Add to favorites",
"switchControl": {
"controlType": "SWITCH",
"name": "saveFavorite"
}
}
},
{
"decoratedText": {
"text": "Merge with existing contacts",
"switchControl": {
"controlType": "SWITCH",
"name": "mergeContact",
"selected": true
}
}
},
{
"buttonList": {
"buttons": [
{
"text": "Next",
"onClick": {
"action": {
// Specifies which function to run
// in response to the card click.
"function": "openSequentialDialog"
}
}
}
]
}
}
]
}
]
}
}
}
}
};
}
/**
* Opens a second dialog that lets users add more contact details.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openSequentialDialog(event) {
return {
"action_response": {
"type": "DIALOG",
"dialog_action": {
"dialog": {
"body": {
"sections": [
{
"header": "Add new contact",
"widgets": [
{
"textInput": {
"label": "Notes",
"type": "MULTIPLE_LINE",
"name": "notes"
}
},
{
"selectionInput": {
"type": "RADIO_BUTTON",
"label": "Contact type",
"name": "contactType",
"items": [
{
"text": "Work",
"value": "Work",
"selected": false
},
{
"text": "Personal",
"value": "Personal",
"selected": false
}
]
}
},
{
"buttonList": {
"buttons": [
{
"text": "Submit",
"onClick": {
"action": {
// Specifies which function to run
// in response to the card click.
"function": "receiveDialog",
"parameters": [
{
"key": "receiveDialog",
"value": "receiveDialog"
}
]
}
}
}
]
},
"horizontalAlignment": "END"
}
]
}
]
}
}
}
}
};
}
Python
from typing import Any, Mapping
import flask
import functions_framework
@functions_framework.http
def main(req: flask.Request) -> Mapping[str, Any]:
"""Responds to a MESSAGE event in Google Chat that includes the /createContact
slash command by opening a dialog.
Args:
req (flask.Request): the event object from Chat API.
Returns:
Mapping[str, Any]: open a Dialog in response to a card's button click.
"""
if req.method == 'GET':
return 'Sorry, this function must be called from a Google Chat.'
request = req.get_json(silent=True)
if request.get('type') == 'CARD_CLICKED':
if invoked_function := request.get('common', dict()).get('invokedFunction'):
if invoked_function == 'open_dialog':
return open_dialog(request)
elif invoked_function == 'open_sequential_dialog':
return open_dialog(request)
def open_dialog(request: Mapping[str, Any]) -> Mapping[str, Any]:
"""Opens a dialog in Google Chat.
Args:
request (Mapping[str, Any]): the event object from Chat API.
Returns:
Mapping[str, Any]: open a Dialog in response to a card's button click.
"""
return {
'action_response': {
'type': 'DIALOG',
'dialog_action': {
'dialog': {
'body': {
'sections': [
{
'header': 'Add new contact',
'widgets': [
{
'textInput': {
'label': 'Name',
'type': 'SINGLE_LINE',
'name': 'name'
}
},
{
'textInput': {
'label': 'Address',
'type': 'MULTIPLE_LINE',
'name': 'address'
}
},
{
'decoratedText': {
'text': 'Add to favorites',
'switchControl': {
'controlType': 'SWITCH',
'name': 'saveFavorite'
}
}
},
{
'decoratedText': {
'text': 'Merge with existing contacts',
'switchControl': {
'controlType': 'SWITCH',
'name': 'mergeContact',
'selected': True
}
}
},
{
'buttonList': {
'buttons': [
{
'text': 'Next',
'onClick': {
'action': {
'function': 'open_sequential_dialog'
}
}
}
]
}
}
]
}
]
}
}
}
}
}
def open_sequential_dialog(request: Mapping[str, Any]) -> Mapping[str, Any]:
"""Opens a second dialog that lets users add more contact details.
Args:
request (Mapping[str, Any]): the event object from Chat API.
Returns:
Mapping[str, Any]: open a Dialog in response to a card's button click.
"""
return {
'action_response': {
'type': 'DIALOG',
'dialog_action': {
'dialog': {
'body': {
'sections': [
{
'header': 'Add new contact',
'widgets': [
{
'textInput': {
'label': 'Notes',
'type': 'MULTIPLE_LINE',
'name': 'notes'
}
},
{
'selectionInput': {
'type': 'RADIO_BUTTON',
'label': 'Contact type',
'name': 'contactType',
'items': [
{
'text': 'Work',
'value': 'Work',
'selected': False
},
{
'text': 'Personal',
'value': 'Personal',
'selected': False
}
]
}
},
{
'buttonList': {
'buttons': [
{
'text': 'Submit',
'onClick': {
'action': {
'function': 'receiveDialog',
'parameters': [
{
'key': 'receiveDialog',
'value': 'receiveDialog'
}
]
}
}
}
]
},
'horizontalAlignment': 'END'
}
]
}
]
}
}
}
}
}
Mở hộp thoại để phản hồi hoạt động tương tác trong trang chủ ứng dụng
Chỉ dành cho trang chủ ứng dụng,
sử dụng render_actions
thay vì action_response
để mở hộp thoại:
Apps Script
Ví dụ này gửi thông báo thẻ bằng cách quay lại tệp JSON của thẻ. Bạn cũng có thể sử dụng Dịch vụ thẻ Apps Script.
function openDialog() {
return {
render_actions: {
action: {
navigations: [{
update_card: {
"sections": [
{
"header": "Add new contact",
"widgets": [
{
"textInput": {
"label": "Name",
"type": "SINGLE_LINE",
"name": "contactName"
}
},
{
"textInput": {
"label": "Address",
"type": "MULTIPLE_LINE",
"name": "address"
}
},
{
"decoratedText": {
"text": "Add to favorites",
"switchControl": {
"controlType": "SWITCH",
"name": "saveFavorite"
}
}
},
{
"decoratedText": {
"text": "Merge with existing contacts",
"switchControl": {
"controlType": "SWITCH",
"name": "mergeContact",
"selected": true
}
}
},
{
"buttonList": {
"buttons": [
{
"text": "Next",
"onClick": {
"action": {
"function": "openSequentialDialog"
}
}
}
]
}
}]
}]
}
}]
}
}
}
}
Nhận dữ liệu biểu mẫu từ hộp thoại
Khi người dùng nhấp vào một nút trên hộp thoại, dữ liệu mà họ đã nhập sẽ được gửi đến ứng dụng Chat và Ứng dụng Chat nhận được một sự kiện tương tác với các thông tin sau:
EventType
làCARD_CLICKED
.DialogEventType
làSUBMIT_DIALOG
.
Dữ liệu mà người dùng nhập vào hộp thoại có sẵn trong sự kiện tương tác dưới dạng
Event.common.formInputs
!
một bản đồ trong đó các khoá là các mã nhận dạng chuỗi được gán cho từng giá trị và tiện ích hộp thoại
biểu thị hoạt động đầu vào của người dùng cho mỗi tiện ích. Các đối tượng khác nhau biểu thị các đối tượng khác nhau
kiểu dữ liệu đầu vào. Ví dụ:
Event.common.formInputs.stringInputs
biểu thị đầu vào chuỗi.
Khi người dùng gửi một hộp thoại, ứng dụng Chat của bạn sẽ nhận được một sự kiện tương tác như sau từ Chat:
JSON
{
"type": enum (EventType),
"eventTime": string,
"threadKey": string,
"message": {
object (Message)
},
"user": {
object (User)
},
"space": {
object (Space)
},
"action": {
object (FormAction)
},
"configCompleteRedirectUrl": string,
// Indicates that this event is dialog-related.
"isDialogEvent": true,
// Indicates that a user clicked a button, and all data
// they entered in the dialog is included in Event.common.formInputs.
"dialogEventType": "SUBMIT_DIALOG",
"common": {
"userLocale": string,
"hostApp": enum (HostApp),
"platform": enum (Platform),
"timeZone": {
object (TimeZone)
},
// Represents user data entered in a dialog.
"formInputs": {
// Represents user data entered for a specific field in a dialog.
"NAME": {
// Represents string data entered in a dialog, like text input fields
// and check boxes.
"stringInputs": {
// An array of strings entered by the user in a dialog.
"value": [
string
]
}
}
},
"parameters": {
string: string,
...
},
"invokedFunction": string
}
}
Ứng dụng Chat có thể truy cập vào giá trị đầu tiên do người dùng nhập
lúc event.common.formInputs.NAME.stringInputs.value[0]
,
trong đó NAME là trường name
của
Tiện ích TextInput
.
Sau khi nhận được dữ liệu biểu mẫu hộp thoại, ứng dụng Chat
nên trả lời bằng một
ActionResponse
:
- Để xác nhận đã nhận thành công, hãy trả lời bằng
ActionResponse
có"actionStatus": "OK"
. Thao tác này sẽ đóng hộp thoại mà không đăng của bạn. - Để trả lời bằng tin nhắn văn bản hoặc tin nhắn thẻ, hãy trả lời bằng
ActionResponse
cóResponseType
NEW_MESSAGE
,UPDATE_MESSAGE
hoặcUPDATE_USER_MESSAGE_CARDS
. Để biết thêm thông tin, xem Phản hồi hộp thoại. - Để trả về lỗi, hãy phản hồi bằng
ActionResponse
có"actionStatus": "ERROR MESSAGE"
.
Ví dụ sau đây sẽ kiểm tra sự hiện diện của giá trị name
. Nếu không có,
ứng dụng Chat trả về một lỗi. Nếu có,
Ứng dụng Chat xác nhận đã nhận được dữ liệu biểu mẫu và
đóng hộp thoại.
Node.js
/**
* Checks for a form input error, the absence of
* a "name" value, and returns an error if absent.
* Otherwise, confirms successful receipt of a dialog.
*
* Confirms successful receipt of a dialog.
*
* @param {Object} event the event object from Chat API.
*
* @return {Object} open a Dialog in Google Chat.
*/
function receiveDialog(event) {
// Checks to make sure the user entered a name
// in a dialog. If no name value detected, returns
// an error message. Any "actionStatus" value other than "OK"
// gets returned as an error.
if (event.common.formInputs.WIDGET_NAME.stringInputs.value[0] === "") {
res.json({
"actionResponse": {
"type": "DIALOG",
"dialogAction": {
"actionStatus": "Don't forget to name your new contact!"
}
}
});
// Otherwise the Chat app indicates that it received
// form data from the dialog. An "actionStatus" of "OK" is
// interpreted as code 200, and the dialog closes.
} else {
res.json({
"actionResponse": {
"type": "DIALOG",
"dialogAction": {
"actionStatus": "OK"
}
}
});
}
}
Apps Script
Ví dụ này gửi thông báo thẻ bằng cách quay lại tệp JSON của thẻ. Bạn cũng có thể sử dụng Dịch vụ thẻ Apps Script.
/**
* Checks for a form input error, the absence of
* a "name" value, and returns an error if absent.
* Otherwise, confirms successful receipt of a dialog.
*
* Confirms successful receipt of a dialog.
*
* @param {Object} event the event object from Chat API.
*
* @return {object} open a Dialog in Google Chat.
*/
function receiveDialog(event) {
// Checks to make sure the user entered a name
// in a dialog. If no name value detected, returns
// an error message. Any "actionStatus" value other than "OK"
// gets returned as an error.
if (event.common.formInputs.WIDGET_NAME[""].stringInputs.value[0] === "") {
return {
"actionResponse": {
"type": "DIALOG",
"dialogAction": {
"actionStatus": "Don't forget to name your new contact!"
}
}
};
// Otherwise the Chat app indicates that it received
// form data from the dialog. An "actionStatus" of "OK" is
// interpreted as code 200, and the dialog closes.
} else {
return {
"actionResponse": {
"type": "DIALOG",
"dialogAction": {
"actionStatus": "OK"
}
}
};
}
}
Python
def receive_dialog(event: Mapping[str, Any]) -> Mapping[str, Any]:
"""Checks for a form input error, the absence of a "name" value, and returns
an error if absent. Otherwise, confirms successful receipt of a dialog.
Args:
event (Mapping[str, Any]): the event object from Chat API.
Returns:
Mapping[str, Any]: the response.
"""
if common := event.get('common'):
if form_inputs := common.get('formInputs'):
if contact_name := form_inputs.get('WIDGET_NAME'):
if string_inputs := contact_name.get('stringInputs'):
if name := string_inputs.get('value')[0]:
return {
'actionResponse': {
'type': 'DIALOG',
'dialogAction': {
'actionStatus': 'OK'
}
}
}
else:
return {
'actionResponse': {
'type': 'DIALOG',
'dialogAction': {
'actionStatus': 'Don\'t forget to name your new contact!'
}
}
}
Phản hồi hộp thoại
Bạn có thể trả lời hộp thoại bằng tin nhắn mới hoặc thông tin cập nhật tin nhắn hiện có.
Trả lời hộp thoại bằng tin nhắn mới
Để phản hồi việc gửi biểu mẫu trong hộp thoại bằng thông báo mới,
Ứng dụng Chat trả về một
ActionResponse
thuộc loại NEW_MESSAGE
, cùng với
đánh dấu
cho biết nội dung của tin nhắn mới. Sau khi nhận được phản hồi này,
hộp thoại đóng và tin nhắn mới được đăng.
Mã sau đây là ví dụ về phản hồi JSON cho hộp thoại do Ứng dụng Chat để tạo tin nhắn trả lời mới:
JSON
{
"actionResponse": {
"type": "NEW_MESSAGE",
},
"text": "This message is a reply to a dialog form submission.",
"cardsV2": [
{
"cardId": "reply-card-id",
"card": {
"header": {
"title": "Reply card title"
},
"sections": [
{
"widgets": [
{
"textParagraph": {
"text": "Reply card message"
}
}
]
}
]
}
}
]
}
Ứng dụng Chat cũng có thể trả lời không đồng bộ bằng văn bản hoặc thẻ .
Trả lời hộp thoại bằng thông báo đã cập nhật
Khi trả lời hộp thoại bằng thông báo cập nhật, bạn có thể cập nhật tin nhắn hiện có trong ứng dụng Chat hoặc cập nhật bản xem trước đường liên kết.
Tin nhắn của ứng dụng Chat
Để phản hồi lượt gửi biểu mẫu hộp thoại kèm theo thông tin cập nhật cho thông báo hiện có
do ứng dụng Chat gửi, ứng dụng sẽ trả về một
ActionResponse
thuộc loại UPDATE_MESSAGE
.
Câu trả lời bao gồm
đánh dấu
cho biết nội dung của thông báo đã cập nhật. Sau khi nhận được thông báo này
thì hộp thoại sẽ đóng và thông báo được cập nhật nội dung mới.
Mã sau đây là ví dụ về phản hồi JSON cho hộp thoại được gửi bởi ứng dụng Chat để cập nhật một Tin nhắn của ứng dụng Chat:
JSON
{
"actionResponse": {
"type": "UPDATE_MESSAGE",
},
"text": "This message has been updated with new content in response to a dialog form submission.",
"cardsV2": [
{
"cardId": "updated-card-id",
"card": {
"header": {
"title": "Updated card title"
},
"sections": [
{
"widgets": [
{
"textParagraph": {
"text": "Updated card message"
}
}
]
}
]
}
}
]
}
Ứng dụng Chat cũng có thể không đồng bộ cập nhật tin nhắn trong ứng dụng Chat bằng cách dùng API Google Chat.
Bản xem trước đường liên kết
Cần cập nhật
bản xem trước đường liên kết
nội dung mới để phản hồi lại lượt gửi biểu mẫu hộp thoại,
Ứng dụng Chat trả về một
ActionResponse
thuộc loại UPDATE_USER_MESSAGE_CARDS
. Câu trả lời bao gồm
đánh dấu
cho thông báo qua thẻ mới mà bạn đã cập nhật bản xem trước đường liên kết. Sau
nhận được phản hồi này, hộp thoại sẽ đóng và bản xem trước đường liên kết sẽ được cập nhật
bằng các thông báo mới trên thẻ.
Phản hồi JSON mẫu sau đây cập nhật bản xem trước đường liên kết bằng một thẻ mới thông báo:
JSON
{
"actionResponse": "UPDATE_USER_MESSAGE_CARDS",
"cardsV2": [
{
"cardId" : "updated-card-id",
"card" : {
"header": {
"title": "Updated card title"
},
"sections": [
{
"widgets" : [
{
"textParagraph": {
"text": "Updated card message"
}
}
]
}
]
}
}
]
}
Phản hồi hộp thoại xuất hiện trên trang chủ ứng dụng
Chỉ dành cho trang chủ ứng dụng, có hai cách để đóng hộp thoại:
CLOSE_DIALOG
: Đóng hộp thoại và quay lại thẻ trang chủ của ứng dụng.CLOSE_DIALOG_AND_EXECUTE
: Đóng hộp thoại và làm mới trang chủ ứng dụng .
Python
Mã mẫu sau đây dùng CLOSE_DIALOG
để đóng hộp thoại và quay lại
thẻ màn hình chính của ứng dụng:
def close_dialog():
"""Handles dismiss dialog request from Chat."""
return {
'render_actions': {
'action': {
'navigations': [{
'end_navigation': {'action': 'CLOSE_DIALOG'}
}]
}
}
}
Apps Script
Ví dụ này gửi thông báo thẻ bằng cách quay lại tệp JSON của thẻ. Bạn cũng có thể sử dụng Dịch vụ thẻ Apps Script.
Mã mẫu sau đây dùng CLOSE_DIALOG
để đóng hộp thoại và quay lại
thẻ màn hình chính của ứng dụng:
function closeDialog(event) {
return {
render_actions: {
action:{
navigations:[{
end_navigation:{
action: "CLOSE_DIALOG"
}
}]
}
}
};
}
Ví dụ đầy đủ: Rolodex, ứng dụng quản lý danh bạ trong Chat
Trong ví dụ này, ứng dụng Chat mở một hộp thoại để người dùng có thể thêm thông tin chi tiết về một người liên hệ, chẳng hạn như tên, email và địa chỉ:
Node.js
/**
* Responds to messages that have links whose URLs
* match URL patterns configured for link previews.
*
* @param {Object} event The event object from Chat
* API.
*
* @return {Object} Response from the Chat app
* attached to the message with the previewed link.
*/
exports.onMessage = function onMessage(req, res) {
// Store the Google Chat event as a variable.
const event = req.body;
if (req.method === "GET" || !event.message) {
res.send("Hello! This function is meant to be used in a Google Chat " +
"Space.");
}
// Checks for the presence of event.message.slashCommand.
// If the slash command is "/help", responds with a text message.
// If the slash command is "/createContact", opens a dialog.
if (event.message.slashCommand) {
switch (event.message.slashCommand.commandId) {
case 1: // /help
res.json({"text": "Contact bot helps you update your address book!"});
case 2: // /createContact
openDialog(event);
}
}
// If the Chat app doesn"t detect a slash command, it responds
// with a card that prompts the user to add a contact
else {
res.json({
"cardsV2": [{
"cardId": "addContact",
"card": {
"header": {
"title": "Rolodex",
"subtitle": "Manage your contacts!",
"imageUrl": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
"imageType": "CIRCLE"
},
"sections": [
{
"widgets": [
{
"buttonList": {
"buttons": [
{
"text": "Add Contact",
"onClick": {
"action": {
"function": "openDialog",
"interaction": "OPEN_DIALOG"
}
}
}
]
}
}
]
}
]
}
}]
});
}
// Respond to button clicks on attached cards
if (event.type === "CARD_CLICKED") {
if (event.common.invokedFunction === "openDialog") {
openDialog(event);
}
if (event.common.invokedFunction === "openSequentialDialog") {
openSequentialDialog(event);
}
if (event.common.invokedFunction === "confirmDialogSuccess") {
confirmDialogSuccess(event);
}
}
};
/**
* Opens and starts a dialog that lets users add details about a contact.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openDialog(event) {
res.json({
"action_response": {
"type": "DIALOG",
"dialog_action": {
"dialog": {
"body": {
"sections": [
{
"header": "Add new contact",
"widgets": [
{
"textInput": {
"label": "Name",
"type": "SINGLE_LINE",
"name": "name"
}
},
{
"textInput": {
"label": "Address",
"type": "MULTIPLE_LINE",
"name": "address"
}
},
{
"decoratedText": {
"text": "Add to favorites",
"switchControl": {
"controlType": "SWITCH",
"name": "saveFavorite"
}
}
},
{
"decoratedText": {
"text": "Merge with existing contacts",
"switchControl": {
"controlType": "SWITCH",
"name": "mergeContact",
"selected": true
}
}
},
{
"buttonList": {
"buttons": [
{
"text": "Next",
"onClick": {
"action": {
"function": "openSequentialDialog"
}
}
}
]
}
}
]
}
]
}
}
}
}
});
};
/**
* Opens a second dialog that lets users add more contact details.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openSequentialDialog(event) {
res.json({
"action_response": {
"type": "DIALOG",
"dialog_action": {
"dialog": {
"body": {
"sections": [
{
"header": "Add new contact",
"widgets": [
{
"textInput": {
"label": "Notes",
"type": "MULTIPLE_LINE",
"name": "notes"
}
},
{
"selectionInput": {
"type": "RADIO_BUTTON",
"label": "Contact type",
"name": "contactType",
"items": [
{
"text": "Work",
"value": "Work",
"selected": false
},
{
"text": "Personal",
"value": "Personal",
"selected": false
}
]
}
},
{
"buttonList": {
"buttons": [
{
"text": "Submit",
"onClick": {
"action": {
"function": "confirmDialogSuccess",
"parameters": [
{
"key": "confirmDialogSuccess",
"value": "confirmDialogSuccess"
}
]
}
}
}
]
},
"horizontalAlignment": "END"
}
]
}
]
}
}
}
}
});
}
/**
* Checks for a form input error, the absence of
* a "name" value, and returns an error if absent.
* Otherwise, confirms successful receipt of a dialog.
*
* Confirms successful receipt of a dialog.
*
* @param {Object} event the event object from Chat API.
*
* @return {object} open a Dialog in Google Chat.
*/
function receiveDialog(event) {
// Checks to make sure the user entered a name
// in a dialog. If no name value detected, returns
// an error message. Any "actionStatus" value other than "OK"
// gets returned as an error.
if (event.common.formInputs.contactName.stringInputs.value[0] === "") {
res.json({
"actionResponse": {
"type": "DIALOG",
"dialogAction": {
"actionStatus": "Don't forget to name your new contact!"
}
}
});
// Otherwise the Chat app indicates that it received
// form data from the dialog. An "actionStatus" of "OK" is
// interpreted as code 200, and the dialog closes.
} else {
res.json({
"actionResponse": {
"type": "DIALOG",
"dialogAction": {
"actionStatus": "OK"
}
}
});
}
}
Apps Script
Ví dụ này gửi thông báo thẻ bằng cách quay lại tệp JSON của thẻ. Bạn cũng có thể sử dụng Dịch vụ thẻ Apps Script.
Python
from typing import Any, Mapping
import flask
import functions_framework
@functions_framework.http
def main(req: flask.Request) -> Mapping[str, Any]:
"""Responds to a MESSAGE event in Google Chat that includes the /createContact
slash command by opening a dialog.
Args:
req (flask.Request): the event object from Chat API.
Returns:
Mapping[str, Any]: open a Dialog in response to a card's button click.
"""
if req.method == 'GET':
return 'Sorry, this function must be called from a Google Chat.'
request = req.get_json(silent=True)
if request.get('type') == 'CARD_CLICKED':
invoked_function = request.get('common', dict()).get('invokedFunction')
if invoked_function == 'open_dialog':
return open_dialog(request)
elif invoked_function == 'open_sequential_dialog':
return open_dialog(request)
elif invoked_function == "receive_dialog":
return receive_dialog(request)
else:
return {
'cardsV2': [{
'cardId': 'addContact',
'card': {
'header': {
'title': 'Rolodex',
'subtitle': 'Manage your contacts!',
'imageUrl': 'https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png',
'imageType': 'CIRCLE'
},
'sections': [
{
'widgets': [
{
'buttonList': {
'buttons': [
{
'text': 'Add Contact',
'onClick': {
'action': {
'function': 'open_dialog',
'interaction': 'OPEN_DIALOG'
}
}
}
]
}
}
]
}
]
}
}]
}
def open_dialog(request: Mapping[str, Any]) -> Mapping[str, Any]:
"""Opens a dialog in Google Chat.
Args:
request (Mapping[str, Any]): the event object from Chat API.
Returns:
Mapping[str, Any]: open a Dialog in response to a card's button click.
"""
return {
'action_response': {
'type': 'DIALOG',
'dialog_action': {
'dialog': {
'body': {
'sections': [
{
'header': 'Add new contact',
'widgets': [
{
'textInput': {
'label': 'Name',
'type': 'SINGLE_LINE',
'name': 'name'
}
},
{
'textInput': {
'label': 'Address',
'type': 'MULTIPLE_LINE',
'name': 'address'
}
},
{
'decoratedText': {
'text': 'Add to favorites',
'switchControl': {
'controlType': 'SWITCH',
'name': 'saveFavorite'
}
}
},
{
'decoratedText': {
'text': 'Merge with existing contacts',
'switchControl': {
'controlType': 'SWITCH',
'name': 'mergeContact',
'selected': True
}
}
},
{
'buttonList': {
'buttons': [
{
'text': 'Next',
'onClick': {
'action': {
'function': 'open_sequential_dialog'
}
}
}
]
}
}
]
}
]
}
}
}
}
}
def open_sequential_dialog(request: Mapping[str, Any]) -> Mapping[str, Any]:
"""Opens a second dialog that lets users add more contact details.
Args:
request (Mapping[str, Any]): the event object from Chat API.
Returns:
Mapping[str, Any]: open a Dialog in response to a card's button click.
"""
return {
'action_response': {
'type': 'DIALOG',
'dialog_action': {
'dialog': {
'body': {
'sections': [
{
'header': 'Add new contact',
'widgets': [
{
'textInput': {
'label': 'Notes',
'type': 'MULTIPLE_LINE',
'name': 'notes'
}
},
{
'selectionInput': {
'type': 'RADIO_BUTTON',
'label': 'Contact type',
'name': 'contactType',
'items': [
{
'text': 'Work',
'value': 'Work',
'selected': False
},
{
'text': 'Personal',
'value': 'Personal',
'selected': False
}
]
}
},
{
'buttonList': {
'buttons': [
{
'text': 'Submit',
'onClick': {
'action': {
'function': 'receive_dialog',
'parameters': [
{
'key': 'receiveDialog',
'value': 'receiveDialog'
}
]
}
}
}
]
},
'horizontalAlignment': 'END'
}
]
}
]
}
}
}
}
}
def receive_dialog(event: Mapping[str, Any]) -> Mapping[str, Any]:
"""Checks for a form input error, the absence of a "name" value, and returns
an error if absent. Otherwise, confirms successful receipt of a dialog.
Args:
event (Mapping[str, Any]): the event object from Chat API.
Returns:
Mapping[str, Any]: the response.
"""
if event.get('common', dict()) \
.get('formInputs', dict()).get('contactName', dict()) \
.get('stringInputs').get('value', list()):
return {
'actionResponse': {
'type': 'DIALOG',
'dialogAction': {
'actionStatus': 'OK'
}
}
}
else:
return {
'actionResponse': {
'type': 'DIALOG',
'dialogAction': {
'actionStatus': "Don't forget to name your new contact!"
}
}
}
Khắc phục sự cố
Khi một ứng dụng Google Chat hoặc card trả về một lỗi, thì phương thức Giao diện Chat hiển thị một thông báo với nội dung "Đã xảy ra lỗi". hoặc "Không thể xử lý yêu cầu của bạn". Đôi khi, giao diện người dùng của Chat không hiện thông báo lỗi nào ngoài ứng dụng Chat hoặc thẻ tạo ra kết quả không mong muốn; ví dụ: thông báo thẻ có thể không xuất hiện.
Mặc dù thông báo lỗi có thể không xuất hiện trong giao diện người dùng Chat, thông báo lỗi mô tả và dữ liệu nhật ký luôn có sẵn để giúp bạn sửa lỗi khi tính năng ghi nhật ký lỗi cho các ứng dụng trong Chat được bật. Để được trợ giúp xem, gỡ lỗi và sửa lỗi, hãy xem Khắc phục lỗi và khắc phục lỗi của Google Chat.
Chủ đề có liên quan
- Đường liên kết đến bản xem trước
- Thiết lập và phản hồi lệnh dấu gạch chéo
- Xử lý thông tin do người dùng nhập