בדף הזה מוסבר איך אפליקציית Chat יכולה לפתוח להגיב לתיבות דו-שיח.
תיבות דו-שיח הן ממשקים מבוססי כרטיסים בחלון, אפליקציות צ'אט פתוחות לאינטראקציה עם משתמשים. כדי לעזור למשתמשים להשלים את התהליך תהליכים מרובי שלבים, אפליקציית Chat יכולה לפתוח ברצף תיבות דו-שיח.
תיבות דו-שיח מועילות לסוגים הבאים של אינטראקציות משתמשים:
- איסוף מידע ממשתמשים
- אימות משתמשים באמצעות שירותי אינטרנט
- קביעת ההגדרות של אפליקציית Chat
כדי לפתוח, לשלוח או לבטל תיבת דו-שיח נדרשת תגובה מסונכרנת
מאפליקציית Chat עם
DialogEventType
אפליקציות צ'אט לא תומכות בתיבות דו-שיח
שנוצר באמצעות ארכיטקטורה אסינכרונית, כמו
Pub/Sub או
הודעה אחת (create
)
. אם אפליקציית Chat משתמשת באפליקציה אסינכרונית
של ארכיטקטורת RNN, להשתמש
הודעה בכרטיס
במקום בתיבת דו-שיח.
דרישות מוקדמות
Node.js
אפליקציית Google Chat שמופעלת בה תכונות אינטראקטיביות. כדי ליצור להשתמש בשירות HTTP באפליקציית Chat האינטראקטיבית. במדריך למתחילים מוסבר איך עושים את זה.
Apps Script
אפליקציית Google Chat שמופעלת בה תכונות אינטראקטיביות. כדי ליצור כדי להשתמש באפליקציית Chat האינטראקטיבית ב-Apps Script, צריך להשלים את המדריך למתחילים.
Python
אפליקציית Google Chat שמופעלת בה תכונות אינטראקטיביות. כדי ליצור להשתמש בשירות HTTP באפליקציית Chat האינטראקטיבית. במדריך למתחילים מוסבר איך עושים את זה.
פתיחה של תיבת דו-שיח
אפליקציית Chat יכולה לפתוח תיבת דו-שיח בתגובה למשתמש לחיצה על לחצן על הודעה בכרטיס.
![לחיצה על לחצן בכרטיס כדי לפתוח תיבת דו-שיח.](https://developers.google.cn/static/workspace/chat/images/dialogs-open-card-click.png?authuser=8&hl=he)
אפליקציית Chat יכולה לפתוח תיבת דו-שיח בתגובה למשתמש מנפיק הפקודה לוכסן.
![לחיצה על לחצן בכרטיס כדי לפתוח תיבת דו-שיח.](https://developers.google.cn/static/workspace/chat/images/dialogs-open-slash-command.png?authuser=8&hl=he)
כשמשתמש פותח תיבת דו-שיח, אפליקציית Chat מקבלת ה אירוע אינטראקציה עם המאפיינים הבאים מידע:
isDialogEvent
היאtrue
.ב-
DialogEventType
אחת מהפעולות הבאות שהמשתמש ביצע:REQUEST_DIALOG
: נפתחה תיבת דו-שיח.SUBMIT_DIALOG
: לחצת על לחצן בתיבת דו-שיח.CANCEL_DIALOG
: בוטלה תיבת דו-שיח.
לדוגמה, כשמשתמש פותח תיבת דו-שיח, אפליקציית Chat מקבל אירוע אינטראקציה שדומה לזה:
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)
}
}
אפליקציית Chat יכולה לפתוח תיבת דו-שיח על ידי החזרת
ActionResponse
של "type": "DIALOG"
עם
DialogAction
שכולל תיאור JSON של תיבת הדו-שיח:
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"
}
}
}
]
}
}
]
}
]
}
}
}
}
}
פתיחת תיבת דו-שיח בתגובה ללחיצה על לחצן הכרטיס
כדי לפתוח תיבת דו-שיח עם לחצן כרטיס, מציינים את הפרטים הבאים:
onClick.action.function
בתור שם הפונקציה שפותחת תיבת דו-שיח.onClick.action.interaction
בתורOPEN_DIALOG
המאפיין הזה מציין ל-Chat אפליקציית Chat מבקשת לפתוח תיבת דו-שיח.
כשמשתמש לוחץ על לחצן בכרטיס, אפליקציית Chat מקבל אירוע אינטראקציה עם הפרטים הבאים:
EventType
היאCARD_CLICKED
.DialogEventType
הואREQUEST_DIALOG
common.invokedFunction
הוא שם הפונקציה מהמאפייןonClick
של הפונקציה לחצן הכרטיס.
כדי לפתוח תיבת דו-שיח, משיבים להודעה הבאה:
-
ActionResponse
מתוך"type": "DIALOG"
. - א'
DialogAction
שכולל תיאור JSON של תיבת הדו-שיח.
בדוגמה הזו, אפליקציית Chat משיבה לMESSAGE
אירוע אינטראקציה עם כרטיס שכולל לחצן שפותח תיבת דו-שיח:
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
בדוגמה הזו, נשלחת הודעת כרטיס על ידי חזרה כרטיס JSON. אפשר גם להשתמש שירות הכרטיסים של 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'
}
}
}
]
}
}
]
}
]
}
}
}
}
}
פתיחת תיבת דו-שיח בתגובה לפקודה של קו נטוי
כשמשתמש פותח תיבת דו-שיח עם פקודת לוכסן שמוגדרת לפתיחת תיבת דו-שיח, אפליקציית Chat מקבלת אירוע אינטראקציה עם הבאים:
EventType
היאMESSAGE
.DialogEventType
REQUEST_DIALOG
.
כדי לפתוח תיבת דו-שיח, צריך להגדיר את הפקודה של הלוכסן על ידי סימון התיבה פתיחת תיבת דו-שיח. לאחר מכן, השיבו עם הפרטים הבאים:
-
ActionResponse
מתוך"type": "DIALOG"
. DialogAction
שכולל תיאור JSON של תיבת הדו-שיח.
בדוגמה הזו, אפליקציית Chat משיבה
הפקודה /createContact
של לוכסן על ידי פתיחה של תיבת דו-שיח:
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
בדוגמה הזו, נשלחת הודעת כרטיס על ידי חזרה כרטיס JSON. אפשר גם להשתמש שירות הכרטיסים של 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'
}
}
}
]
}
}
]
}
]
}
}
}
}
}
פתיחה של תיבות דו-שיח עוקבות
אם לאינטראקציות של המשתמשים נדרשת יותר מתיבת דו-שיח אחת, אפשר לפתוח תיבת דו-שיח נוספת
על ידי החזרת תיבת הדו-שיח הבאה ברצף בתגובה לבקשה SUBMIT_DIALOG
DialogEventType
.
![תיבת דו-שיח עם מגוון ווידג'טים שונים.](https://developers.google.cn/static/workspace/chat/images/dialogs-card-1.png?authuser=8&hl=he)
בלחצן הכרטיס שמעדכן את תיבת הדו-שיח, חוזרים
onClick.action.function
בתור
שם של פונקציה שפותחת את תיבת הדו-שיח הבאה,
onClick.action.interaction
לא צוין.
![תיבת דו-שיח עם מגוון ווידג'טים שונים.](https://developers.google.cn/static/workspace/chat/images/dialogs-card-2.png?authuser=8&hl=he)
בסיום, אפליקציית Chat תקבל את ערכי המשתמשים שהוזן בתיבת הדו-שיח כ-JSON. הודעה למשתמשים שהאינטראקציה שלהם הצליחה להשיב בהודעות טקסט או בכרטיס.
כשמשתמשים לוחצים על לחצן בתיבת דו-שיח, אפליקציית Chat מקבל אירוע אינטראקציה עם הפרטים הבאים:
EventType
CARD_CLICKED
.DialogEventType
SUBMIT_DIALOG
.
בדוגמה הזו, אפליקציית Chat משיבה
אירוע אינטראקציה אחד (CARD_CLICKED
) מלחיצה על לחצן של תיבת דו-שיח על ידי פתיחת אירוע נוסף
תיבת דו-שיח:
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
בדוגמה הזו, נשלחת הודעת כרטיס על ידי חזרה כרטיס JSON. אפשר גם להשתמש שירות הכרטיסים של 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'
}
]
}
]
}
}
}
}
}
פתיחת תיבת דו-שיח בתגובה לאינטראקציה בדף הבית של האפליקציה
לגבי דף הבית של האפליקציה בלבד:
כדי לפתוח תיבת דו-שיח, יש להשתמש ב-render_actions
במקום ב-action_response
:
Apps Script
בדוגמה הזו, נשלחת הודעת כרטיס על ידי חזרה כרטיס JSON. אפשר גם להשתמש שירות הכרטיסים של 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"
}
}
}
]
}
}]
}]
}
}]
}
}
}
}
קבלת נתוני טפסים מתיבות דו-שיח
כשמשתמשים לוחצים על לחצן בתיבת דו-שיח, הנתונים שהם הזינו נשלחים אל אפליקציית Chat אפליקציית Chat מקבלת אירוע אינטראקציה עם הבאים:
EventType
CARD_CLICKED
.DialogEventType
SUBMIT_DIALOG
.
הנתונים שהמשתמשים מזינים בתיבת הדו-שיח זמינים באירוע האינטראקציה בתור
Event.common.formInputs
מפה שבה המפתחות הם מזהי מחרוזות שמוקצים לכל ווידג'ט של תיבת דו-שיח וערכים
שמייצג את הקלט של המשתמש עבור כל ווידג'ט. אובייקטים שונים מייצגים
של סוגי נתוני הקלט. לדוגמה,
Event.common.formInputs.stringInputs
שמייצג את ערכי הקלט של מחרוזות.
כשמשתמש שולח תיבת דו-שיח, אפליקציית Chat מקבלת אירוע אינטראקציה כמו זה מ-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
}
}
אפליקציית Chat יכולה לגשת לערך הראשון שהוזן על ידי המשתמש
בשעה event.common.formInputs.NAME.stringInputs.value[0]
,
כאשר NAME הוא השדה name
של
הווידג'ט TextInput
.
אחרי שיתקבלו הנתונים מהטופס של תיבת הדו-שיח, אפליקציית Chat
צריך להגיב עם
ActionResponse
- כדי לאשר שהקבלה בוצעה בהצלחה, יש להשיב עם
ActionResponse
שיש לו"actionStatus": "OK"
. הפעולה הזו סוגרת את תיבת הדו-שיח בלי לפרסם תשובה. - כדי להשיב בהודעת טקסט או בהודעה בכרטיס, צריך להשיב
ActionResponse
שיש לוResponseType
מתוךNEW_MESSAGE
,UPDATE_MESSAGE
אוUPDATE_USER_MESSAGE_CARDS
. לקבלת מידע נוסף מידע נוסף, ראה להשיב לתיבת דו-שיח. - כדי להחזיר שגיאה, צריך להשיב עם
ActionResponse
שיש לו"actionStatus": "ERROR MESSAGE"
.
הדוגמה הבאה בודקת אם יש ערך מסוג name
. אם השדה חסר,
ואפליקציית Chat תחזיר הודעת שגיאה. אם הוא קיים,
אפליקציית Chat מאשרת קבלה של נתוני הטופס
סוגר את תיבת הדו-שיח.
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
בדוגמה הזו, נשלחת הודעת כרטיס על ידי חזרה כרטיס JSON. אפשר גם להשתמש שירות הכרטיסים של 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!'
}
}
}
איך עונים לתיבת דו-שיח
ניתן להשיב לתיבת דו-שיח באמצעות הודעה חדשה או עדכון של הודעה קיימת.
איך עונים לתיבת דו-שיח עם הודעה חדשה
כדי להשיב להודעה חדשה שנשלחה בטופס תיבת דו-שיח:
אפליקציית Chat מחזירה
ActionResponse
מסוג NEW_MESSAGE
, יחד עם
תגי עיצוב
שמציין את תוכן ההודעה החדשה. לאחר קבלת התשובה הזו,
תיבת הדו-שיח תיסגר וההודעה החדשה תתפרסם.
הקוד הבא הוא דוגמה לתגובת JSON לתיבת דו-שיח שנשלחת אפליקציית Chat כדי ליצור הודעת תשובה חדשה:
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"
}
}
]
}
]
}
}
]
}
אפליקציית Chat יכולה גם לענות באופן אסינכרוני באמצעות טקסט או כרטיס הודעה.
איך עונים לתיבת דו-שיח עם הודעה מעודכנת
כשעונים לתיבת דו-שיח עם הודעה מעודכנת, אפשר לעדכן הודעה קיימת באפליקציית Chat או עדכון תצוגה מקדימה של הקישור.
הודעות באפליקציית Chat
כדי להשיב לטופס של תיבת דו-שיח שנשלחו עם עדכון להודעה קיימת
שנשלחת על ידי אפליקציית Chat, מחזירה
ActionResponse
מסוג UPDATE_MESSAGE
.
התגובה כוללת
תגי עיצוב
שמציין את תוכן ההודעה המעודכנת. עם קבלת ההודעה
תגובה, תיבת הדו-שיח תיסגר וההודעה תתעדכן בתוכן החדש.
הקוד הבא הוא דוגמה לתגובת JSON לתיבת דו-שיח שנשלחת על ידי אפליקציה של Chat כדי לעדכן אפליקציה קיימת הודעה מאפליקציית 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"
}
}
]
}
]
}
}
]
}
אפשר גם לבצע פעולות אסינכרוניות באפליקציית Chat. איך מעדכנים הודעות באפליקציית Chat באמצעות Google Chat API.
תצוגות מקדימות של קישורים
לעדכון
תצוגה מקדימה של קישורים
עם תוכן חדש בתגובה לטפסים של תיבת הדו-שיח,
אפליקציית Chat מחזירה
ActionResponse
מסוג UPDATE_USER_MESSAGE_CARDS
. התגובה כוללת
תגי עיצוב
עבור הודעות הכרטיסים החדשות שהתצוגה המקדימה של הקישורים מתעדכנת. אחרי
קבלת התשובה הזו, תיבת הדו-שיח תיסגר והתצוגות המקדימות של הקישורים יעודכנו
בהודעות החדשות בכרטיס.
בדוגמה הבאה לתשובת JSON מתבצע עדכון של תצוגה מקדימה של קישור עם כרטיס חדש message:
JSON
{
"actionResponse": "UPDATE_USER_MESSAGE_CARDS",
"cardsV2": [
{
"cardId" : "updated-card-id",
"card" : {
"header": {
"title": "Updated card title"
},
"sections": [
{
"widgets" : [
{
"textParagraph": {
"text": "Updated card message"
}
}
]
}
]
}
}
]
}
איך עונים לתיבת דו-שיח שמופיעה בדף הבית של האפליקציה
לגבי דף הבית של האפליקציה בלבד: יש שתי דרכים שונות לסגירת תיבת דו-שיח:
CLOSE_DIALOG
: הלחצן סוגר את תיבת הדו-שיח וחוזר לכרטיס הבית של האפליקציה.CLOSE_DIALOG_AND_EXECUTE
: סוגר את תיבת הדו-שיח ומרענן את דף הבית של האפליקציה של Google.
Python
בדוגמת הקוד הבאה נעשה שימוש ב-CLOSE_DIALOG
כדי לסגור תיבת דו-שיח ולחזור אל
כרטיס הבית של האפליקציה:
def close_dialog():
"""Handles dismiss dialog request from Chat."""
return {
'render_actions': {
'action': {
'navigations': [{
'end_navigation': {'action': 'CLOSE_DIALOG'}
}]
}
}
}
Apps Script
בדוגמה הזו, נשלחת הודעת כרטיס על ידי חזרה כרטיס JSON. אפשר גם להשתמש שירות הכרטיסים של Apps Script.
בדוגמת הקוד הבאה נעשה שימוש ב-CLOSE_DIALOG
כדי לסגור תיבת דו-שיח ולחזור אל
כרטיס הבית של האפליקציה:
function closeDialog(event) {
return {
render_actions: {
action:{
navigations:[{
end_navigation:{
action: "CLOSE_DIALOG"
}
}]
}
}
};
}
דוגמה מלאה: Rolodex, איש הקשר שמנהל את אפליקציית Chat
בדוגמה הזו, באפליקציית Chat נפתחת תיבת דו-שיח, יכולים להוסיף פרטים על איש הקשר, כמו שם, אימייל וכתובת:
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
בדוגמה הזו, נשלחת הודעת כרטיס על ידי חזרה כרטיס JSON. אפשר גם להשתמש שירות הכרטיסים של 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!"
}
}
}
פתרון בעיות
כשאפליקציית Google Chat או אפליקציית Google Chat הפונקציה card מחזירה שגיאה, בממשק של Chat מוצגת ההודעה "משהו השתבש". או "לא ניתן לעבד את הבקשה שלך". לפעמים בממשק המשתמש של Chat לא מציגה הודעות שגיאה, אבל אפליקציית Chat או והכרטיס מפיק תוצאה לא צפויה: לדוגמה, הודעה בכרטיס יופיעו.
יכול להיות שלא תופיע הודעת שגיאה בממשק המשתמש של Chat, אבל יש הודעות שגיאה תיאוריות ונתוני יומן זמינים כדי לעזור לכם לתקן שגיאות כשמופעלת רישום שגיאות ביומן של אפליקציות ל-Chat. כדי לקבל עזרה בצפייה: לניפוי באגים ולתיקון שגיאות: פתרון בעיות ותיקון שגיאות ב-Google Chat