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

Trang này mô tả cách ứng dụng Chat có thể mở hộp thoại để trả lời người dùng.

Hộp thoại là giao diện dựa trên thẻ và cửa sổ mở trong một phòng Chat hoặc tin nhắn. Hộp thoại và chỉ người dùng đã mở nội dung đó mới nhìn thấy nội dung đó.

Các ứng dụng trong Chat có thể dùng hộp thoại để yêu cầu và thu thập thông tin từ Người dùng Chat, bao gồm cả biểu mẫu nhiều bước. Để biết thêm chi tiết về cách tạo thông tin đầu vào cho biểu mẫu, hãy xem bài viết Thu thập và xử lý thông tin từ người dùng.

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

Node.js

  • Một ứng dụng Google Chat đã bật các tính năng tương tác. Để tạo một tương tác bằng ứng dụng Chat bằng dịch vụ HTTP, hãy hoàn thành phần bắt đầu nhanh này.

Python

  • Một ứng dụng Google Chat đã bật các tính năng tương tác. Để tạo một tương tác bằng ứng dụng Chat bằng dịch vụ HTTP, hãy hoàn thành phần bắt đầu nhanh này.

Apps Script

  • Một ứng dụng Google Chat đã bật các tính năng tương tác. Để tạo một ứng dụng Chat tương tác trong Apps Script, hãy hoàn thành phần bắt đầu nhanh này.

Mở hộp thoại

Một hộp thoại hiển thị nhiều tiện ích.
Hình 1: Hộp thoại thu thập thông tin liên hệ.

Phần này giải thích cách phản hồi và thiết lập hộp thoại theo các bước sau:

  1. Kích hoạt yêu cầu hộp thoại từ tương tác của người dùng.
  2. Xử lý yêu cầu bằng cách quay lại và mở một hộp thoại.
  3. Sau khi người dùng gửi thông tin, hãy xử lý nội dung gửi bằng cách đóng hoặc trả lại một hộp thoại khác.

Kích hoạt yêu cầu hộp thoại

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

Để trả lời người dùng bằng hộp thoại, ứng dụng Chat phải tạo một tương tác kích hoạt yêu cầu hộp thoại, chẳng hạn như sau:

  • Phản hồi lệnh dấu gạch chéo. Để kích hoạt yêu cầu từ lệnh dấu gạch chéo, bạn phải chọn hộp đánh dấu Mở hộp thoại khi định cấu hình lệnh.
  • Phản hồi khi người dùng nhấp vào nút trong tin nhắn, dưới dạng một phần của thẻ hoặc ở cuối thư. Để kích hoạt từ một nút trong thông báo, bạn định cấu hình của nút onClick bằng cách đặt interaction thành OPEN_DIALOG.
  • Phản hồi khi người dùng nhấp vào nút trên trang chủ của ứng dụng Chat. Để tìm hiểu cách mở hộp thoại trên trang chủ, hãy xem Tạo trang chủ cho ứng dụng Google Chat.
Nút kích hoạt hộp thoại
Hình 2: Một ứng dụng trong Chat gửi thông báo nhắc người dùng sử dụng lệnh dấu gạch chéo /addContact.
Thông báo cũng có nút mà người dùng có thể nhấp vào để kích hoạt lệnh.

Tệp JSON sau đây cho biết cách kích hoạt một yêu cầu hộp thoại từ một nút trong một thông báo trên thẻ. Để mở hộp thoại, button.interaction trường được đặt thành OPEN_DIALOG:

{
  "buttonList": { "buttons": [{
    "text": "BUTTON_TEXT",
    "onClick": { "action": {
      "function": "FUNCTION_NAME",
      "interaction": "OPEN_DIALOG"
    }}
  }]}
}

Trong đó BUTTON_TEXT là văn bản xuất hiện trong nút và FUNCTION_NAME là hàm chạy để mở giá trị ban đầu .

Mở hộp thoại ban đầu

Khi người dùng kích hoạt một yêu cầu qua hộp thoại, ứng dụng Chat của bạn sẽ nhận được một sự kiện tương tác, được biểu thị dưới dạng Nhập event vào API Chat. Nếu hoạt động tương tác này kích hoạt một yêu cầu hộp thoại, thì Trường dialogEventType được đặt thành REQUEST_DIALOG.

Để mở hộp thoại, ứng dụng Chat có thể phản hồi bằng cách trả về một actionResponse với type được đặt thành DIALOGMessage . Để chỉ định nội dung của hộp thoại, bạn hãy thêm vào đối tượng:

  • actionResponse với type được đặt thành DIALOG.
  • dialogAction . Trường body chứa các thành phần giao diện người dùng để hiển thị trong thẻ, bao gồm một hoặc nhiều sections tiện ích. Để thu thập thông tin từ người dùng, bạn có thể chỉ định tiện ích nhập biểu mẫu và tiện ích nút. Để tìm hiểu thêm về cách thiết kế thông tin đầu vào cho biểu mẫu, hãy xem Thu thập và xử lý thông tin từ người dùng.

Tệp JSON sau đây cho biết cách thức ứng dụng Chat trả về giá trị một phản hồi mở ra một hộp thoại:

{ "actionResponse": {
  "type": "DIALOG",
  "dialogAction": { "dialog": { "body": { "sections": [{
    "widgets": [{
      WIDGETS,
      { "buttonList": { "buttons": [{
        "text": "BUTTON_TEXT",
        "onClick": {
          "action": {"function": "FUNCTION_NAME"}
        }
      }]}}
    }]
  }]}}}
}}

Trong đó BUTTON_TEXT là văn bản xuất hiện trong nút (chẳng hạn như Next hoặc Submit), WIDGETS đại diện cho một hoặc nhiều tiện ích nhập biểu mẫuFUNCTION_NAME là hàm sẽ chạy khi người dùng nhấp vào một nút.

Xử lý việc gửi hộp thoại

Khi người dùng nhấp vào nút gửi hộp thoại, Số lượt truy cập mà ứng dụng Chat nhận được lượt tương tác CARD_CLICKED sự kiện mà dialogEventTypeSUBMIT_DIALOG.

Ứng dụng Chat của bạn phải xử lý sự kiện tương tác bằng cách thực hiện một trong những thao tác sau:

Không bắt buộc: Trả lại hộp thoại khác

Sau khi người dùng gửi hộp thoại ban đầu, các ứng dụng trong Chat có thể trả về một hoặc nhiều hộp thoại bổ sung để giúp người dùng xem xét thông tin trước khi gửi, hoàn thành biểu mẫu nhiều bước hoặc điền nội dung biểu mẫu một cách linh động.

Để tải bất kỳ dữ liệu nào mà người dùng nhập vào từ hộp thoại ban đầu, bạn phải thêm vào nút mở hộp thoại tiếp theo hoặc truyền giá trị CARD_CLICKED sự kiện tương tác từ hộp thoại ban đầu. Để biết thông tin chi tiết, hãy xem Chuyển dữ liệu sang một thẻ khác.

Trong ví dụ này, ứng dụng Chat mở một hộp thoại sẽ trả về hộp thoại thứ hai trước khi gửi. Để tải dữ liệu đầu vào, Ứng dụng Chat vượt qua sự kiện tương tác CARD_CLICKED làm tham số cho hàm mở hộp thoại tiếp theo:

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 === "openNextDialog") {
    openNextDialog(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({ "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      { "buttonList": { "buttons": [{
        "text": "Next",
        "onClick": { "action": {
          "function": "openNextDialog"
        }}
      }]}}
    ]}]}}}
  }});
};

/**
* 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 openNextDialog(event) {
  res.json({ "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      {
        "horizontalAlignment": "END",
        "buttonList": { "buttons": [{
          "text": "Submit",
          "onClick": { "action": {
            "function": "submitDialog"
          }}
        }]}
      }
    ]}]}}}
  }});
}

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_next_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 { "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      { "buttonList": { "buttons": [{
        "text": "Next",
        "onClick": { "action": {
          "function": "open_next_dialog"
        }}
      }]}}
    ]}]}}}
  }}

def open_next_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 { "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      {
        "horizontalAlignment": "END",
        "buttonList": { "buttons": [{
          "text": "Submit",
          "onClick": { "action": {
            "function": "submit_dialog"
          }}
        }]}
      }
    ]}]}}}
  }}

Apps Script

Ví dụ này gửi thông báo thẻ bằng cách quay lại JSON thẻ. Bạn cũng có thể sử dụng Dịch vụ thẻ Apps Script.

/**
* Responds to a CARD_CLICKED event in Google Chat.
*
* @param {Object} event the event object from Google Chat
*/
function onCardClick(event) {

  // When a user clicks a card, the Chat app checks to see which function to run.
  if (event.common.invokedFunction === "openDialog") {
    return openDialog(event);
  }

  if (event.common.invokedFunction === "openNextDialog") {
    return openNextDialog(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 { "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      { "buttonList": { "buttons": [{
        "text": "Next",
        "onClick": { "action": {
          "function": "openNextDialog"
        }}
      }]}}
    ]}]}}}
  }};
}

/**
* 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 openNextDialog(event) {
  return { "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      {
        "horizontalAlignment": "END",
        "buttonList": { "buttons": [{
          "text": "Submit",
          "onClick": { "action": {
            "function": "submitDialog"
          }}
        }]}
      }
    ]}]}}}
  }};
}

Trong đó WIDGETS đại diện cho một hoặc nhiều tiện ích nhập biểu mẫu.

Đóng hộp thoại

Khi người dùng nhấp vào một nút trên hộp thoại, Ứng dụng Chat nhận được một sự kiện tương tác với các thông tin sau:

Các phần sau đây giải thích cách xác thực dữ liệu mà người dùng nhập vào và đóng hộp thoại.

Xác thực dữ liệu nhập của người dùng rồi đóng hộp thoại

Để xử lý dữ liệu mà người dùng nhập, ứng dụng Chat sử dụng event.common.formInputs . Để tìm hiểu thêm về cách truy xuất giá trị từ tiện ích nhập, hãy xem Thu thập và xử lý thông tin từ người dùng.

Nếu người dùng bỏ qua trường bắt buộc hoặc nhập giá trị không chính xác, Ứng dụng Chat có thể phản hồi kèm theo lỗi bằng cách trả về một ActionResponse"actionStatus": "ERROR MESSAGE".

Ví dụ sau đây kiểm tra để đảm bảo rằng người dùng nhập một giá trị cho một tiện ích chấp nhận các chuỗi (stringInputs), chẳng hạn như tiện ích textInput. Nếu không có, Ứng dụng Chat trả về lỗi. Nếu có, ứng dụng Chat xác nhận việc gửi hộp thoại 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 submitDialog(event) {

  // Checks to make sure the user entered a value
  // in a dialog. If no 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": "ERROR_MESSAGE"
        }
      }
    });

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

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': 'ERROR_MESSAGE'
                }
              }
            }

Apps Script

Ví dụ này gửi thông báo thẻ bằng cách quay lại JSON thẻ. Bạn cũng có thể sử dụng Dịch vụ thẻ Apps Script.

/**
* Checks for a form input error, the absence of
* a "name" value, and returns an error if absent.
* Otherwise, confirms successful receipt of a dialog.
*
* Confirms successful receipt of a dialog.
*
* @param {Object} event the event object from Chat API.
*
* @return {object} open a Dialog in Google Chat.
*/
function submitDialog(event) {

  // Checks to make sure the user entered a value
  // in a dialog. If no 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": "ERROR_MESSAGE"
        }
      }
    };

    // 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"
        }
      }
    };
  }
}

Trong ví dụ này, WIDGET_NAME đại diện cho trường name của tiện ích (chẳng hạn như contactName) và ERROR_MESSAGE biểu thị nội dung thông báo lỗi (chẳng hạn như Don't forget to name your contact). Để biết thông tin chi tiết về cách xử lý dữ liệu đầu vào từ các tiện ích, hãy xem Nhận dữ liệu từ các tiện ích tương tác.

Không bắt buộc: Gửi thư xác nhận

Khi đóng hộp thoại, bạn cũng có thể gửi thư mới hoặc cập nhật danh sách hiện tại.

Để gửi tin nhắn mới, hãy trả lại ActionResponse với type được đặt thành NEW_MESSAGE. Ví dụ: để đóng hộp thoại và gửi tin nhắn văn bản, hãy trả về các thông tin sau:

  {
    "actionResponse": {
      "type": "NEW_MESSAGE",
    },
    "text": "Your information has been submitted."
  }

Để cập nhật thông báo, hãy trả về đối tượng actionResponse chứa phương thức thông báo đã cập nhật và đặt type thành một trong các giá trị sau:

Khắc phục sự cố

Khi một ứng dụng Google Chat hoặc card trả về một lỗi, thì phương thức Giao diện Chat hiển thị một thông báo với nội dung "Đã xảy ra lỗi". hoặc "Không thể xử lý yêu cầu của bạn". Đôi khi, giao diện người dùng của Chat không hiện thông báo lỗi nào ngoài ứng dụng Chat hoặc thẻ tạo ra kết quả không mong muốn; ví dụ: thông báo thẻ có thể không xuất hiện.

Mặc dù thông báo lỗi có thể không xuất hiện trong giao diện người dùng Chat, thông báo lỗi mô tả và dữ liệu nhật ký luôn có sẵn để giúp bạn sửa lỗi khi tính năng ghi nhật ký lỗi cho các ứng dụng trong Chat được bật. Để được trợ giúp xem, gỡ lỗi và sửa lỗi, hãy xem Khắc phục lỗi và khắc phục lỗi của Google Chat.