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

Trang này mô tả cách ứng dụng Google Chat có thể mở hộp thoại để hiển thị giao diện người dùng (UI) và phản hồi người dùng.

Trong Google Chat, các tiện ích bổ sung sẽ xuất hiện với người dùng dưới dạng ứng dụng Google Chat. Để tìm hiểu thêm, hãy xem bài viết Tổng quan về việc mở rộng Google Chat.

Hộp thoại là giao diện dạng cửa sổ, dựa trên thẻ mở ra từ một không gian hoặc tin nhắn trên Chat. Hộp thoại và nội dung của hộp thoại chỉ hiển thị với người dùng đã mở hộp thoại đó.

Ứng dụng Chat có thể sử 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 thông tin chi tiết về cách tạo dữ liệu đầu vào của biểu mẫu, hãy xem phần 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 tiện ích bổ sung của Google Workspace mở rộng Google Chat. Để tạo một ứng dụng, hãy hoàn tất phần Bắt đầu nhanh về HTTP.

Apps Script

Một tiện ích bổ sung của Google Workspace mở rộng Google Chat. Để tạo một ứng dụng, hãy hoàn tất phần Bắt đầu nhanh với Apps Script.

Mở hộp thoại

Một hộp thoại có nhiều tiện ích khác nhau.
Hình 1: Một ứng dụng Chat mở 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 bằng cách làm như sau:

  1. Kích hoạt yêu cầu hộp thoại từ một lượt tương tác của người dùng.
  2. Xử lý yêu cầu bằng cách trả về và mở một hộp thoại.
  3. Sau khi người dùng gửi thông tin, hãy xử lý thông tin đã gửi bằng cách đóng hộp thoại hoặc trả về 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 để phản hồi một lượt tương tác của người dùng, chẳng hạn như lệnh dấu gạch chéo hoặc lượt nhấp vào nút từ một tin nhắn trong thẻ.

Để phản hồi người dùng bằng một hộp thoại, ứng dụng Chat phải tạo một hoạt động 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ừ một lệnh gạch chéo, bạn phải đánh dấu vào hộp đánh dấu Mở hộp thoại khi thiết lập lệnh.
  • Phản hồi một lượt nhấp vào nút trong thông báo, dưới dạng một phần của thẻ hoặc ở cuối thông báo. Để kích hoạt yêu cầu từ một nút trong thông báo, bạn hãy định cấu hình hành động onClick của nút đó bằng cách đặt interaction thành OPEN_DIALOG.
Nút kích hoạt hộp thoại
Hình 2: Ứng dụng Chat gửi một thông báo nhắc người dùng sử dụng lệnh gạch chéo /addContact.
Thông báo này cũng bao gồm một nút mà người dùng có thể nhấp vào để kích hoạt lệnh.

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

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

Trong đó BUTTON_TEXT là văn bản hiển thị trong nút và ACTION_FUNCTION là hàm chạy để mở hộp thoại ban đầu.

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

Khi người dùng kích hoạt một yêu cầu hộp thoại, ứng dụng Chat của bạn sẽ nhận được một đối tượng sự kiện có tải trọng chỉ định đối tượng dialogEventTypeREQUEST_DIALOG.

Để mở hộp thoại, ứng dụng Chat có thể phản hồi yêu cầu bằng cách trả về đối tượng RenderActionspushCard điều hướng để hiển thị thẻ. Thẻ phải chứa mọi thành phần giao diện người dùng (UI), bao gồm một hoặc nhiều sections[] của tiện ích. Để thu thập thông tin từ người dùng, bạn có thể chỉ định các tiện ích nhập dữ liệu vào biểu mẫu và một tiện ích nút. Để tìm hiểu thêm về cách thiết kế phần nhập thông tin trên biểu mẫu, hãy xem phần Thu thập và xử lý thông tin từ người dùng.

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

{
  "action": { "navigations": [{ "pushCard": { "sections": [{ "widgets": [{
    WIDGETS,
    { "buttonList": { "buttons": [{
      "text": "BUTTON_TEXT",
      "onClick": {
        "action": { "function": "ACTION_FUNCTION" }
      }
    }]}}
  }]}]}}]}
}

Trong đó, BUTTON_TEXT là văn bản hiển thị 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 dữ liệu dạngACTION_FUNCTIONhàm gọi lại của thao tác 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, ứng dụng Chat sẽ nhận được một đối tượng sự kiện có đối tượng ButtonClickedPayload. Trong tải trọng, dialogEventType được đặt thành SUBMIT_DIALOG.

Ứng dụng Chat của bạn phải xử lý đối tượng sự kiện bằng cách làm theo một trong những cách sau:

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

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

Để xử lý dữ liệu mà người dùng nhập, ứng dụng Chat sẽ xử lý dữ liệu trong đối tượng commonEventObject.formInputs của sự kiện. Để tìm hiểu thêm về cách truy xuất giá trị từ các tiện ích đầu vào, hãy xem phần Thu thập và xử lý thông tin từ người dùng.

Để theo dõi mọi dữ liệu mà người dùng nhập từ hộp thoại ban đầu, bạn phải thêm các tham số vào nút mở hộp thoại tiếp theo. Để biết thông tin chi tiết, hãy xem phần Chuyển dữ liệu sang thẻ khác.

Trong ví dụ này, ứng dụng Chat sẽ mở một hộp thoại ban đầu dẫn đến hộp thoại thứ hai để xác nhận trước khi gửi:

Node.js

/**
 * Google Cloud Function that handles all Google Workspace Add On events for
 * the contact manager app.
 *
 * @param {Object} req Request sent from Google Chat space
 * @param {Object} res Response to send back
 */
exports.contactManager = function contactManager(req, res) {
  const chatEvent = req.body.chat;
  // Handle MESSAGE events
  if(chatEvent.messagePayload) {
    return res.send(handleMessage(req.body));
  // Handle button clicks
  } else if(chatEvent.buttonClickedPayload) {
    switch(req.body.commonEventObject.parameters.actionName) {
        case "openInitialDialog":
            return res.send(openInitialDialog(req.body));
        case "openConfirmationDialog":
            return res.send(openConfirmationDialog(req.body));
        case "submitDialog":
            return res.send(submitDialog(req.body));
    }
  }
};

/**
 * Responds to a message in Google Chat.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} response that handles dialogs.
 */
function handleMessage(event) {
  // Reply with a message that contains a button to open the initial dialog
  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    text: "To add a contact, use the `ADD CONTACT` button below.",
    accessoryWidgets: [{ buttonList: { buttons: [{
      text: "ADD CONTACT",
      onClick: { action: {
        // Use runtime environment variable set with self URL
        function: process.env.BASE_URL,
        parameters: [{ key: "actionName", value: "openInitialDialog" }],
        interaction: "OPEN_DIALOG"
      }}
    }]}}]
  }}}}};
}

/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} open the dialog.
 */
function openInitialDialog(event) {
  return { action: { navigations: [{ pushCard: { sections: [{ widgets: [{
    textInput: {
      name: "contactName",
      label: "First and last name",
      type: "SINGLE_LINE"
    }},
    WIDGETS, {
    buttonList: { buttons: [{
      text: "NEXT",
      onClick: { action: {
        // Use runtime environment variable set with self URL
        function: process.env.BASE_URL,
        parameters: [{ key: "actionName", value: "openConfirmationDialog" }]
      }}
    }]}}
  ]}]}}]}};
}

/**
 * Opens the second step of the dialog that lets users confirm details.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} update the dialog.
 */
function openConfirmationDialog(event) {
  // Retrieve the form input values
  const name = event.commonEventObject.formInputs["contactName"].stringInputs.value[0];
  return { action: { navigations: [{ pushCard: { sections: [{ widgets: [{
    // Display the input values for confirmation
    textParagraph: { text: "<b>Name:</b> " + name }},
    WIDGETS, {
    buttonList: { buttons: [{
      text: "SUBMIT",
      onClick: { action: {
        // Use runtime environment variable set with self URL
        function: process.env.BASE_URL,
        parameters: [{
          key: "actionName", value: "submitDialog" }, {
          // Pass input values as parameters for last dialog step (submission)
          key: "contactName", value: name
        }]
      }}
    }]}}]
  }]}}]}};
}

Apps Script

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

/**
 * Responds to a message in Google Chat.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} response that handles dialogs.
 */
function onMessage(event) {
  // Reply with a message that contains a button to open the initial dialog
  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    text: "To add a contact, use the `ADD CONTACT` button below.",
    accessoryWidgets: [{ buttonList: { buttons: [{
      text: "ADD CONTACT",
      onClick: { action: {
        function: "openInitialDialog",
        interaction: "OPEN_DIALOG"
      }}
    }]}}]
  }}}}};
}

/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} open the dialog.
 */
function openInitialDialog(event) {
  return { action: { navigations: [{ pushCard: { sections: [{ widgets: [{
    textInput: {
      name: "contactName",
      label: "First and last name",
      type: "SINGLE_LINE"
    }},
    WIDGETS, {
    buttonList: { buttons: [{
      text: "NEXT",
      onClick: { action: { function : "openConfirmationDialog" }}
    }]}}
  ]}]}}]}};
}

/**
 * Opens the second step of the dialog that lets users confirm details.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} update the dialog.
 */
function openConfirmationDialog(event) {
  // Retrieve the form input values
  const name = event.commonEventObject.formInputs["contactName"].stringInputs.value[0];
  return { action: { navigations: [{ pushCard: { sections: [{ widgets: [{
    // Display the input values for confirmation
    textParagraph: { text: "<b>Name:</b> " + name }},
    WIDGETS, {
    buttonList: { buttons: [{
      text: "SUBMIT",
      onClick: { action: {
        function: "submitDialog",
        // Pass input values as parameters for last dialog step (submission)
        parameters: [{ key: "contactName", value: name }]
      }}
    }]}}]
  }]}}]}};
}

Trong đó WIDGETS đại diện cho mọi tiện ích nhập dữ liệu dạng biểu mẫu khác.

Đóng hộp thoại

Khi người dùng nhấp vào nút gửi trên hộp thoại, ứng dụng Chat sẽ thực thi hành động liên kết và cung cấp đối tượng sự kiện với buttonClickedPayload được đặt thành như sau:

  • isDialogEventtrue.
  • dialogEventTypeSUBMIT_DIALOG.

Ứng dụng Chat sẽ trả về một đối tượng RenderActions với EndNavigation được đặt thành CLOSE_DIALOG.

Không bắt buộc: Hiển thị thông báo

Khi đóng hộp thoại, bạn cũng có thể hiển thị thông báo văn bản.

Để hiển thị thông báo, hãy trả về đối tượng RenderActions đã đặt trường notification.

Ví dụ sau đây kiểm tra để đảm bảo các tham số hợp lệ và đóng hộp thoại bằng thông báo văn bản tuỳ thuộc vào kết quả:

Node.js

/**
 * Handles submission and closes the dialog.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} close the dialog with a status in text notification.
 */
function submitDialog(event) {
  // Validate the parameters.
  if (!event.commonEventObject.parameters["contactName"]) {
    return { action: {
      navigations: [{ endNavigation: "CLOSE_DIALOG"}],
      notification: { text: "Failure, the contact name was missing!" }
    }};
  }

  return { action: {
    navigations: [{ endNavigation: "CLOSE_DIALOG"}],
    notification: { text: "Success, the contact was added!" }
  }};
}

Apps Script

/**
 * Handles submission and closes the dialog.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} close the dialog with a status in text notification.
 */
function submitDialog(event) {
  // Validate the parameters.
  if (!event.commonEventObject.parameters["contactName"]) {
    return { action: {
      navigations: [{ endNavigation: "CLOSE_DIALOG"}],
      notification: { text: "Failure, the contact name was missing!" }
    }};
  }

  return { action: {
    navigations: [{ endNavigation: "CLOSE_DIALOG"}],
    notification: { text: "Success, the contact was added!" }
  }};
}

Để biết thông tin chi tiết về cách truyền tham số giữa các hộp thoại, hãy xem phần Chuyển dữ liệu sang thẻ khác.

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

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

Để gửi một tin nhắn mới, hãy trả về một đối tượng DataActions có trường CreateMessageAction được đặt bằng tin nhắn mới. Ví dụ: để đóng hộp thoại và gửi tin nhắn văn bản, hãy trả về nội dung sau:

{ "hostAppDataAction": { "chatDataAction": { "createMessageAction": { "message": {
  "text": "Your information has been submitted."
}}}}}

Để cập nhật thông báo sau khi người dùng gửi hộp thoại, hãy trả về một đối tượng DataActions chứa một trong các thao tác sau:

Khắc phục sự cố

Khi ứng dụng Google Chat hoặc thẻ trả về lỗi, giao diện Chat sẽ hiển thị thông báo "Đã 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 Chat không hiển thị thông báo lỗi nào, nhưng ứng dụng Chat hoặc thẻ lại 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 hiển thị trong giao diện người dùng Chat, nhưng bạn có thể xem thông báo lỗi mô tả và dữ liệu nhật ký để khắc phục lỗi khi bật tính năng ghi nhật ký lỗi cho ứng dụng Chat. Để được trợ giúp xem, gỡ lỗi và khắc phục lỗi, hãy xem bài viết Khắc phục và khắc phục lỗi Google Chat.