במאמר הזה נסביר איך אפליקציית Chat יכולה להיפתח ולהשיב לתיבות דו-שיח.
תיבות דו-שיח הן ממשקים מבוססי כרטיסים עם חלונות שאפליקציות צ'אט פותחות כדי לקיים אינטראקציה עם משתמשים. כדי לעזור למשתמשים להשלים תהליכים מרובי שלבים, אפליקציית Chat יכולה לפתוח תיבות דו-שיח רציפות.
תיבות דו-שיח שימושיות לסוגים הבאים של אינטראקציות משתמשים:
- איסוף מידע ממשתמשים
- אימות משתמשים באמצעות שירותי אינטרנט
- קביעת ההגדרות של אפליקציית Chat
כדי לפתוח תיבת דו-שיח, לשלוח אותה או לבטל אותה, צריך לענות תשובה סינכרונית מאפליקציית Chat עם DialogEventType
.
האפליקציות ל-Chat לא תומכות בארכיטקטורה אסינכרונית, כמו Pub/Sub או שיטת create
הודעה. אם באפליקציית Chat יש ארכיטקטורה אסינכרונית, כדאי להשתמש בהודעה בכרטיס במקום בתיבת דו-שיח.
דרישות מוקדמות
Node.js
- חשבון Google Workspace עם גישה ל-Google Chat.
- אפליקציה ל-Chat. כדי ליצור אפליקציה ל-Chat, תוכלו להיעזר בquickstart.
- אם פותחים תיבת דו-שיח בתגובה לפקודה של לוכסן, צריך לבחור פקודת לוכסן עם האפשרות פתיחת תיבת דו-שיח.
דוגמאות הקוד של Node.js נכתבות כפונקציה של Cloud Functions.
Apps Script
- חשבון Google Workspace עם גישה ל-Google Chat.
- אפליקציה ל-Chat. כדי ליצור אפליקציה ל-Chat, תוכלו להיעזר בquickstart.
- אם פותחים תיבת דו-שיח בתגובה לפקודה של לוכסן, צריך לבחור פקודת לוכסן עם האפשרות פתיחת תיבת דו-שיח.
Python
- חשבון Google Workspace עם גישה ל-Google Chat.
- אפליקציה ל-Chat. כדי ליצור אפליקציה ל-Chat, תוכלו להיעזר בquickstart.
- אם פותחים תיבת דו-שיח בתגובה לפקודה של לוכסן, צריך לבחור פקודת לוכסן עם האפשרות פתיחת תיבת דו-שיח.
דוגמאות הקוד של Python נכתבות כפונקציה של Cloud Functions, באמצעות Python 3.9.
פתיחה של תיבת דו-שיח
אפליקציית Chat יכולה לפתוח תיבת דו-שיח בתגובה ללחיצה של משתמש על לחצן בהודעה בכרטיס.
אפליקציית Chat יכולה לפתוח תיבת דו-שיח בתגובה שמשתמש ישלח פקודה לוכסן.
כשמשתמש פותח תיבת דו-שיח, אפליקציית 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
בדוגמה הזו נשלחת הודעת כרטיס על ידי החזרת card 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
בדוגמה הזו נשלחת הודעת כרטיס על ידי החזרת card 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
.
בלחצן הכרטיס שמעדכן את תיבת הדו-שיח, מחזירים את הערך onClick.action.function
כשם של פונקציה שפותחת את תיבת הדו-שיח הבאה, בלי לציין את הערך onClick.action.interaction
.
בסיום, אפליקציית 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
בדוגמה הזו נשלחת הודעת כרטיס על ידי החזרת card 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
בדוגמה הזו נשלחת הודעת כרטיס על ידי החזרת card 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
בדוגמה הזו נשלחת הודעת כרטיס על ידי החזרת card 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 באופן אסינכרוני באמצעות Google Chat API.
תצוגות מקדימות של קישורים
כדי לעדכן את התצוגה המקדימה של הקישורים בתוכן חדש בתגובה לשליחת טפסים בתיבת הדו-שיח, אפליקציית Chat תחזיר את הערך ActionResponse
מסוג UPDATE_USER_MESSAGE_CARDS
. התשובה כוללת תגי עיצוב של ההודעות החדשות בכרטיסים שהתצוגה המקדימה של הקישורים מתעדכנת. אחרי שתקבלו את התשובה, תיבת הדו-שיח תיסגר והתצוגה המקדימה של הקישורים תתעדכן בהתאם להודעות החדשות בכרטיס.
תגובת JSON לדוגמה הבאה מעדכנת את התצוגה המקדימה של הקישור עם הודעת כרטיס חדשה:
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
: הלחצן סוגר את תיבת הדו-שיח ומרענן את הודעת הכרטיס בדף הבית של האפליקציה.
Python
דוגמת הקוד הבאה משתמשת ב-CLOSE_DIALOG
כדי לסגור תיבת דו-שיח ולחזור להודעה בכרטיס הבית של האפליקציה:
def close_dialog():
"""Handles dismiss dialog request from Chat."""
return {
'render_actions': {
'action': {
'navigations': [{
'end_navigation': {'action': 'CLOSE_DIALOG'}
}]
}
}
}
Apps Script
בדוגמה הזו נשלחת הודעת כרטיס על ידי החזרת card 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
בדוגמה הזו נשלחת הודעת כרטיס על ידי החזרת card 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, מוצגת בממשק של Chat ההודעה 'משהו השתבש'. או "לא ניתן לעבד את הבקשה". לפעמים לא מוצגות הודעות שגיאה בממשק המשתמש של Chat, אבל קיבלתי תוצאה לא צפויה באפליקציה או בכרטיס של Chat. למשל, יכול להיות שלא תופיע הודעה.
יכול להיות שהודעת השגיאה לא תוצג בממשק המשתמש של Chat, אבל יש הודעות שגיאה תיאוריות ונתוני יומן שיכולים לעזור לך לתקן שגיאות כשמפעילים רישום שגיאות באפליקציות של Chat. במאמר פתרון בעיות ותיקון שגיאות ב-Google Chat אפשר לקבל עזרה בהצגה, בניפוי באגים ובתיקון שגיאות.
נושאים קשורים
- תצוגה מקדימה של קישורים
- איך מגדירים פקודות דרך שורת הפקודות ועונים עליהן
- עיבוד מידע שהוזן על ידי משתמשים