Mở hộp thoại tương tác

Hộp thoại là giao diện dựa trên cửa sổ, dạng cửa sổ mà các ứng dụng Chat mở để tương tác với người dùng. Để giúp người dùng hoàn tất các quy trình gồm nhiều bước, ứng dụng có thể mở hộp thoại tuần tự.

Hộp thoại hữu ích cho nhiều loại tương tác của người dùng, bao gồm:

  • Thu thập thông tin từ người dùng
  • Xác thực người dùng bằng Dịch vụ web
  • Định cấu hình cài đặt ứng dụng Chat

Hướng dẫn này mô tả cách triển khai hộp thoại cho ứng dụng Chat.

Điều kiện tiên quyết

Để triển khai hộp thoại và chạy các ví dụ trong hướng dẫn này, bạn cần:

Node.js

Apps Script

Python

Cách hộp thoại hoạt động

Khi người dùng nhấp vào một nút trên thẻ hoặc tạo lệnh gạch chéo, ứng dụng Chat có thể mở hộp thoại để tương tác với người dùng đó.

Nhấp vào một nút trên thẻ để mở hộp thoại.
Hình 1: Nhấp vào một nút trên thẻ để mở hộp thoại.
Nhấp vào một nút trên thẻ để mở hộp thoại.
Hình 2: Đưa ra lệnh dấu gạch chéo để mở hộp thoại.

Hộp thoại giúp người dùng tương tác bằng cách cho phép người dùng nhập thông tin bằng các tiện ích, như các trường nhập văn bản. Khi thu thập nhiều thông tin từ người dùng, các ứng dụng trong Chat có thể mở hộp thoại tuần tự.

Một hộp thoại có nhiều tiện ích khác nhau.
Hình 3: Hộp thoại mở nhắc người dùng thêm người liên hệ.
Một hộp thoại có nhiều tiện ích khác nhau.
Hình 4: Hộp thoại thứ hai nhắc người dùng cung cấp thêm thông tin.

Khi hoàn tất, ứng dụng Chat sẽ nhận được các giá trị mà người dùng đã nhập trong hộp thoại ở dạng JSON. Thông báo cho người dùng rằng hành động tương tác của họ đã thành công bằng cách trả lời bằng tin nhắn văn bản hoặc thẻ.

Mở hộp thoại

Ứng dụng Chat có thể mở hộp thoại để phản hồi người dùng:

Khi người dùng yêu cầu hộp thoại, ứng dụng Chat của bạn sẽ nhận được một Google Chat Event, trong đó:

  • isDialogEventtrue.
  • DialogEventType chỉ định xem người dùng đang mở hộp thoại (REQUEST_DIALOG), nhấp vào một nút trong hộp thoại (SUBMIT_DIALOG) hay huỷ hộp thoại (CANCEL_DIALOG).

Ví dụ: khi người dùng mở hộp thoại, ứng dụng Chat sẽ nhận được một Event như sau từ Google 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)
  }
}

Ứng dụng Chat có thể mở hộp thoại bằng cách trả về một ActionResponse của "type": "DIALOG" kèm theo DialogAction, trong đó có thông tin 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 về lượt nhấp vào nút trên thẻ

Khi người dùng nhấp vào một nút trên thẻ, ứng dụng của bạn sẽ nhận được Event, trong đó:

Để mở hộp thoại, hãy chỉ định:

Trong ví dụ này, ứng dụng Chat phản hồi MESSAGE Event bằng một 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.
  var 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") {
      res.openDialog(event);
};

/**
 * Opens and starts a dialog that allows users to 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

/**
 * 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, ứng dụng sẽ nhận được Event, trong đó:

Để mở hộp thoại, hãy trả lời bằng:

Trong ví dụ này, ứng dụng Chat phản hồi lệnh gạch chéo /createContact bằng cách 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.
  var 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
        res.openDialog(event);
    }
  }
};

/**
 * Opens and starts a dialog that allows users to 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

/**
 * 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'
                            }
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    }
  }

Kết nối nhiều giao diện thẻ với nhau

Khi người dùng tương tác với nhiều thẻ, bạn có thể mở thẻ mới từ cùng hộp thoại bằng cách trả về một hộp thoại khác.

Khi người dùng nhấp vào một nút trong hộp thoại, ứng dụng sẽ nhận được một Event, trong đó:

Do hộp thoại đã mở nên bạn đừng chỉ định onClick.action.interaction như khi mở hộp thoại từ thẻ trong cuộc trò chuyện. Thay vào đó, chỉ trả về onClick.action.function làm tên của một hàm mở ra hộp thoại.

Trong ví dụ này, ứng dụng Chat phản hồi CARD_CLICKED Event từ một nút hộp thoại bằng cách mở một hộp thoại khác:

Node.js

// Respond to button clicks on attached cards
if(event.type === "CARD_CLICKED") {

  // Open the first dialog.
  if (event.common.invokedFunction == "openDialog") {
    res.openDialog(event);
  }

  // Open the second dialog.
  if (event.common.invokedFunction == "openSequentialDialog") {
    res.openSequentialDialog(event);
  }
}

/**
* Opens and starts a dialog that allows users to 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 allows users to 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

/**
 * 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 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 allows users to 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 allows users to 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 allows users to 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'
                  }
                ]
              }
            ]
          }
        }
      }
    }
  }

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 đó sẽ nhận được Event trong đó:

Dữ liệu mà người dùng nhập vào hộp thoại hiện có trên Event dưới dạng Event.common.formInputs, một bản đồ mà các khóa là mã chuỗi được gán cho mỗi tiện ích hộp thoại và các giá trị đại diện cho hoạt động đầu vào của người dùng cho mỗi tiện ích. Mỗi đối tượng hiển thị một loại dữ liệu đầu vào riêng. Ví dụ: Event.common.formInputs.stringInputs biểu thị dữ liệu đầu vào của chuỗi.

Khi người dùng gửi hộp thoại, ứng dụng Chat của bạn sẽ nhận được một Event như trong Google 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 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 của bạn có thể truy cập giá trị đầu tiên do người dùng nhập tại 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 sẽ phản hồi bằng cách xác nhận đã nhận hoặc trả về lỗi, cả hai đều được thực hiện bằng cách trả về một ActionResponse:

  • Để xác nhận đã nhận được thành công, hãy phản hồi bằng một ActionResponse"actionStatus": "OK".
  • Để trả về lỗi, hãy phản hồi bằng một ActionResponse"actionStatus": "ERROR MESSAGE".

Ví dụ sau đây kiểm tra sự hiện diện của giá trị "name". Nếu không có thông tin này, ứng dụng sẽ trả về lỗi. Nếu xuất hiện, ứng dụng sẽ 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.
  if (event.common.formInputs.contactName.stringInputs.value[0] == "") {
    return {
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": {
            "statusCode": "OK", 
            "userFacingMessage": "Don't forget to name your new contact!"
        }
      }
    };

  // Otherwise the app indicates that it received
  // form data from the dialog. Any value other than "OK"
  // gets returned as an error. "OK" is interpreted as
  // code 200, and the dialog closes.
  } else {
    res.json({
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "OK"
        }
      }
    });
  }
}

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.
  if (event.common.formInputs.contactName.stringInputs.value[0] == "") {
    return {
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "Don't forget to name your new contact!"
        }
      }
    };

  // Otherwise the app indicates that it received
  // form data from the dialog. Any value other than "OK"
  // gets returned as an error. "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('contactName'):
        if string_inputs := contact_name.get('stringInputs')
          if name := string_inputs.get('value'):
            return {
              'actionResponse': {
                'type': 'DIALOG',
                'dialogAction': {
                  'actionStatus': 'OK'
                }
              }
            }
          else:
            return {
              'actionResponse': {
                'type': 'DIALOG',
                'dialogAction': {
                  'actionStatus': 'Don't forget to name your new contact!'
                }
              }
            }

Trả lời hộp thoại có tin nhắn văn bản hoặc thẻ

Để phản hồi hộp thoại bằng tin nhắn văn bản đơn giản hoặc thẻ, hãy xác thực bằng tài khoản dịch vụ, sau đó gửi tin nhắn trả lời không đồng bộ bằng cách gọi spaces.messages.create sử dụng API Google Chat REST10}.

Ví dụ đầy đủ: Rolodex người liên hệ quản lý ứng dụng Chat

Trong ví dụ này, ứng dụng Chat mở 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.
  var 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
        res.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") {
      res.openDialog(event);
    }

    if (event.common.invokedFunction == "openSequentialDialog") {
      res.openSequentialDialog(event);
    }

    if (event.common.invokedFunction == "confirmDialogSuccess") {
      res.confirmDialogSuccess(event);
    }

  }

};

/**
 * Opens and starts a dialog that allows users to 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 allows users to 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.
  if (event.common.formInputs.contactName.stringInputs.value[0] == "") {
    return {
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": {
            "statusCode": "OK", 
            "userFacingMessage": "Don't forget to name your new contact!"
        }
      }
    };

  // Otherwise the app indicates that it received
  // form data from the dialog. Any value other than "OK"
  // gets returned as an error. "OK" is interpreted as
  // code 200, and the dialog closes.
  } else {
    res.json({
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "OK"
        }
      }
    });
  }
}

Apps Script

/**
 * Responds to a MESSAGE event in Google Chat.
 *
 * @param {Object} event the event object from Chat API.
 *
 * @return {object} open a Dialog in response to a slash command
 * or a card"s button click.
 */
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);
    }
  }

  // If the Chat app doesn"t detect a slash command, it responds
  // with a card that prompts the user to add a contact
  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": "openDialog",
                            "interaction": "OPEN_DIALOG"
                          }
                        }
                      }
                    ]
                  }
                }
              ]
            }
          ]
        }
      }]

    };
  }
}

/**
 * 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);
  }

  if (event.common.invokedFunction == "openSequentialDialog") {
    return openSequentialDialog(event);
  }

  if (event.common.invokedFunction == "receiveDialog") {
    return receiveDialog(event);
  }
}

/**
 * Opens and starts a dialog that allows users to 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": {
                                "function": "openSequentialDialog"
                              }
                            }
                          }
                        ]
                      }
                    }
                  ]
                }
              ]
            }
          }
        }
    }
  };
}

/**
 * Opens a second dialog that allows users to 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": {
                                "function": "receiveDialog",
                                "parameters": [
                                  {
                                    "key": "receiveDialog",
                                    "value": "receiveDialog"
                                  }
                                ]
                              }
                            }
                          }
                        ]
                      },
                      "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.
  if (event.common.formInputs.contactName.stringInputs.value[0] == "") {
    return {
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "Don't forget to name your new contact!"
        }
      }
    };

  // Otherwise the app indicates that it received
  // form data from the dialog. Any value other than "OK"
  // gets returned as an error. "OK" is interpreted as
  // code 200, and the dialog closes.
  } else {
    return {
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "OK"
        }
      }
    };
  }
}

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 allows users to 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!"
        }
      }
    }

Giới hạn và cân nhắc

Hãy lưu ý các điểm giới hạn và cân nhắc sau đây đối với hộp thoại:

  • Thẻ phiên bản 1 đã ngừng hoạt động nhưng không được hộp thoại hỗ trợ. Hãy chuyển sang sử dụng thẻ phiên bản 2.
  • Một số tiện ích và thuộc tính thẻ chưa được hỗ trợ và sẽ không hiển thị nếu bạn thêm các tiện ích và thuộc tính đó vào thẻ hộp thoại (nhưng chúng tôi đang nỗ lực để hỗ trợ chúng sớm). Để biết những tiện ích và thuộc tính nào chưa được hỗ trợ, hãy xem Thẻ trong tài liệu tham khảo về API REST của Chat. Nếu một tiện ích hoặc thuộc tính không được hỗ trợ thì nội dung mô tả sẽ bao gồm cụm từ "Không được các ứng dụng Chat hỗ trợ."
  • Hộp thoại không hỗ trợ những loại dữ liệu người dùng nhập vào sau đây (tuy nhiên chúng tôi đang nỗ lực để hỗ trợ các loại dữ liệu này):
  • Hệ thống không hỗ trợ đề xuất tự động hoàn thành do máy chủ tạo, nhưng nội dung đề xuất được trả về kèm theo phản hồi của hộp thoại thì có.
  • onChangeAction – một thuộc tính của một số tiện ích thẻ, chẳng hạn như SwitchControl, chỉ định Action để thực hiện khi tiện ích đó được thay đổi, chẳng hạn như lật công tắc – không được hỗ trợ.

Hộp thoại gỡ lỗi

Khi triển khai hộp thoại, bạn có thể cần gỡ lỗi ứng dụng Chat bằng cách đọc nhật ký của ứng dụng. Để đọc nhật ký, hãy truy cập vào Trình khám phá nhật ký trên Google Cloud Console.