Thu thập và xử lý thông tin của người dùng Google Chat

Hướng dẫn này mô tả cách các ứng dụng Google Chat có thể thu thập và xử lý thông tin từ người dùng bằng cách tạo dữ liệu đầu vào biểu mẫu trong giao diện dựa trên thẻ.

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ẫu mở một hộp thoại để thu thập thông tin liên hệ.

Các ứng dụng Chat yêu cầu người dùng cung cấp thông tin để thực hiện các hành động trong hoặc ngoài Chat, bao gồm cả những cách sau:

  • Định cấu hình chế độ cài đặt. Ví dụ: cho phép người dùng tuỳ chỉnh chế độ cài đặt thông báo hoặc định cấu hình và thêm ứng dụng Chat vào một hoặc nhiều không gian.
  • Tạo hoặc cập nhật thông tin trong các ứng dụng khác của Google Workspace. Ví dụ: cho phép người dùng tạo một sự kiện trên Lịch Google.
  • Cho phép người dùng truy cập và cập nhật tài nguyên trong các ứng dụng hoặc dịch vụ web khác. Ví dụ: một ứng dụng Chat có thể giúp người dùng cập nhật trạng thái của phiếu yêu cầu hỗ trợ ngay trong không gian trên Chat.

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

Node.js

Một ứng dụng Google Chat nhận và phản hồi sự kiện tương tác. Để tạo một ứng dụng Chat tương tác bằng dịch vụ HTTP, hãy hoàn tất hướng dẫn bắt đầu nhanh này.

Python

Một ứng dụng Google Chat nhận và phản hồi sự kiện tương tác. Để tạo một ứng dụng Chat tương tác bằng dịch vụ HTTP, hãy hoàn tất hướng dẫn bắt đầu nhanh này.

Java

Một ứng dụng Google Chat nhận và phản hồi sự kiện tương tác. Để tạo một ứng dụng Chat tương tác bằng dịch vụ HTTP, hãy hoàn tất hướng dẫn bắt đầu nhanh này.

Apps Script

Một ứng dụng Google Chat nhận và phản hồi sự kiện tương tác. Để tạo một ứng dụng Chat có tính tương tác trong Apps Script, hãy hoàn thành hướng dẫn bắt đầu nhanh này.

Tạo biểu mẫu bằng thẻ

Để thu thập thông tin, các ứng dụng Chat thiết kế biểu mẫu và dữ liệu đầu vào, đồng thời tạo chúng thành thẻ. Để hiển thị thẻ cho người dùng, các ứng dụng Chat có thể sử dụng các giao diện Chat sau:

  • Tin nhắn có chứa một hoặc nhiều thẻ.
  • Trang chủ, là thẻ xuất hiện trong thẻ Trang chủ trong tin nhắn trực tiếp với ứng dụng Chat.
  • Hộp thoại là những thẻ mở ra trong một cửa sổ mới từ tin nhắn và trang chủ.

Các ứng dụng trò chuyện có thể tạo thẻ bằng các tiện ích sau:

  • Các tiện ích đầu vào biểu mẫu yêu cầu người dùng cung cấp thông tin. Bạn có thể thêm xác thực vào các tiện ích nhập biểu mẫu (không bắt buộc) để đảm bảo người dùng nhập và định dạng thông tin một cách chính xác. Các ứng dụng trò chuyện có thể sử dụng những tiện ích đầu vào biểu mẫu sau đây:

    • Đầu vào văn bản (textInput) cho văn bản tự do hoặc văn bản được đề xuất.
    • Đầu vào lựa chọn (selectionInput) là những phần tử có thể chọn trên giao diện người dùng, chẳng hạn như hộp đánh dấu, nút chọn và trình đơn thả xuống. Các tiện ích đầu vào lựa chọn cũng có thể điền các mục từ nguồn dữ liệu tĩnh hoặc động. Ví dụ: người dùng có thể chọn trong danh sách các phòng Chat mà họ là thành viên.
    • Bộ chọn ngày giờ (dateTimePicker) cho các mục ngày và giờ.
  • Một tiện ích nút để người dùng có thể gửi các giá trị mà họ đã nhập vào thẻ. Sau khi người dùng nhấp vào nút này, ứng dụng Chat có thể xử lý thông tin mà ứng dụng nhận được.

Trong ví dụ sau, một thẻ thu thập thông tin liên hệ bằng cách sử dụng một mục nhập văn bản, bộ chọn ngày giờ và mục nhập lựa chọn:

Để biết ví dụ về một ứng dụng Chat sử dụng biểu mẫu liên hệ này, hãy xem mã sau:

Node.js

node/contact-form-app/index.js
/**
 * The section of the contact card that contains the form input widgets. Used in a dialog and card message.
 * To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
 */
const CONTACT_FORM_WIDGETS = [
  {
    "textInput": {
      "name": "contactName",
      "label": "First and last name",
      "type": "SINGLE_LINE"
    }
  },
  {
    "dateTimePicker": {
      "name": "contactBirthdate",
      "label": "Birthdate",
      "type": "DATE_ONLY"
    }
  },
  {
    "selectionInput": {
      "name": "contactType",
      "label": "Contact type",
      "type": "RADIO_BUTTON",
      "items": [
        {
          "text": "Work",
          "value": "Work",
          "selected": false
        },
        {
          "text": "Personal",
          "value": "Personal",
          "selected": false
        }
      ]
    }
  }
];

Python

python/contact-form-app/main.py
# The section of the contact card that contains the form input widgets. Used in a dialog and card message.
# To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
CONTACT_FORM_WIDGETS = [
  {
    "textInput": {
      "name": "contactName",
      "label": "First and last name",
      "type": "SINGLE_LINE"
    }
  },
  {
    "dateTimePicker": {
      "name": "contactBirthdate",
      "label": "Birthdate",
      "type": "DATE_ONLY"
    }
  },
  {
    "selectionInput": {
      "name": "contactType",
      "label": "Contact type",
      "type": "RADIO_BUTTON",
      "items": [
        {
          "text": "Work",
          "value": "Work",
          "selected": False
        },
        {
          "text": "Personal",
          "value": "Personal",
          "selected": False
        }
      ]
    }
  }
]

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
// The section of the contact card that contains the form input widgets. Used in a dialog and card message.
// To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
final static private List<GoogleAppsCardV1Widget> CONTACT_FORM_WIDGETS = List.of(
  new GoogleAppsCardV1Widget().setTextInput(new GoogleAppsCardV1TextInput()
    .setName("contactName")
    .setLabel("First and last name")
    .setType("SINGLE_LINE")),
  new GoogleAppsCardV1Widget().setDateTimePicker(new GoogleAppsCardV1DateTimePicker()
    .setName("contactBirthdate")
    .setLabel("Birthdate")
    .setType("DATE_ONLY")),
  new GoogleAppsCardV1Widget().setSelectionInput(new GoogleAppsCardV1SelectionInput()
    .setName("contactType")
    .setLabel("Contact type")
    .setType("RADIO_BUTTON")
    .setItems(List.of(
      new GoogleAppsCardV1SelectionItem()
        .setText("Work")
        .setValue("Work")
        .setSelected(false),
      new GoogleAppsCardV1SelectionItem()
        .setText("Personal")
        .setValue("Personal")
        .setSelected(false)))));

Apps Script

apps-script/contact-form-app/contactForm.gs
/**
 * The section of the contact card that contains the form input widgets. Used in a dialog and card message.
 * To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
 */
const CONTACT_FORM_WIDGETS = [
  {
    "textInput": {
      "name": "contactName",
      "label": "First and last name",
      "type": "SINGLE_LINE"
    }
  },
  {
    "dateTimePicker": {
      "name": "contactBirthdate",
      "label": "Birthdate",
      "type": "DATE_ONLY"
    }
  },
  {
    "selectionInput": {
      "name": "contactType",
      "label": "Contact type",
      "type": "RADIO_BUTTON",
      "items": [
        {
          "text": "Work",
          "value": "Work",
          "selected": false
        },
        {
          "text": "Personal",
          "value": "Personal",
          "selected": false
        }
      ]
    }
  }
];

Để biết thêm ví dụ về các tiện ích tương tác mà bạn có thể dùng để thu thập thông tin, hãy xem phần Thiết kế thẻ hoặc hộp thoại tương tác.

Nhận dữ liệu từ các tiện ích tương tác

Bất cứ khi nào người dùng nhấp vào một nút, các ứng dụng Chat sẽ nhận được một sự kiện tương tác tuỳ thuộc vào vị trí của nút:

  • Nếu nút nằm trong một tin nhắn hoặc hộp thoại, thì Các ứng dụng Chat sẽ nhận được một sự kiện tương tác CARD_CLICKED chứa thông tin về lượt tương tác đó. Tải trọng của các sự kiện tương tác CARD_CLICKED chứa một đối tượng common.formInputs có mọi giá trị mà người dùng nhập.

    Bạn có thể truy xuất các giá trị từ đối tượng common.formInputs.WIDGET_NAME, trong đó WIDGET_NAME là trường name mà bạn đã chỉ định cho tiện ích. Các giá trị được trả về dưới dạng một loại dữ liệu cụ thể cho tiện ích (được biểu thị dưới dạng một đối tượng Inputs).

    Sau đây là một phần của sự kiện tương tác CARD_CLICKED, trong đó người dùng đã nhập giá trị cho từng tiện ích:

    HTTP

    {
      "type": "CARD_CLICKED",
      "common": { "formInputs": {
        "contactName": { "stringInputs": {
          "value": ["Kai 0"]
        }},
        "contactBirthdate": { "dateInput": {
          "msSinceEpoch": 1000425600000
        }},
        "contactType": { "stringInputs": {
          "value": ["Personal"]
        }}
      }}
    }
    

    Apps Script

    {
      "type": "CARD_CLICKED",
      "common": { "formInputs": {
        "contactName": { "": { "stringInputs": {
          "value": ["Kai 0"]
        }}},
        "contactBirthdate": { "": { "dateInput": {
          "msSinceEpoch": 1000425600000
        }}},
          "contactType": { "": { "stringInputs": {
          "value": ["Personal"]
        }}}
      }}
    }
    
  • Nếu nút này nằm trên trang chủ, thì các ứng dụng Chat sẽ nhận được sự kiện tương tác SUBMIT_FORM. Tải trọng của sự kiện tương tác chứa một đối tượng commonEventObject.formInputs có mọi giá trị mà người dùng nhập.

    Bạn có thể truy xuất các giá trị từ đối tượng commonEventObject.formInputs.WIDGET_NAME, trong đó WIDGET_NAME là trường name mà bạn đã chỉ định cho tiện ích. Các giá trị được trả về dưới dạng một loại dữ liệu cụ thể cho tiện ích (được biểu thị dưới dạng một đối tượng Inputs).

    Sau đây là một phần của sự kiện tương tác SUBMIT_FORM, trong đó người dùng đã nhập giá trị cho từng tiện ích:

    HTTP

    {
      "type": "SUBMIT_FORM",
      "commonEventObject": { "formInputs": {
        "contactName": { "stringInputs": {
          "value": ["Kai 0"]
        }},
        "contactBirthdate": { "dateInput": {
          "msSinceEpoch": 1000425600000
        }},
        "contactType": { "stringInputs": {
          "value": ["Personal"]
        }}
      }}
    }
    

    Apps Script

    {
      "type": "SUBMIT_FORM",
      "commonEventObject": { "formInputs": {
        "contactName": { "": { "stringInputs": {
          "value": ["Kai 0"]
        }}},
        "contactBirthdate": { "": { "dateInput": {
          "msSinceEpoch": 1000425600000
        }}},
          "contactType": { "": { "stringInputs": {
          "value": ["Personal"]
        }}}
      }}
    }
    

Để nhận dữ liệu, ứng dụng Chat của bạn sẽ xử lý sự kiện tương tác để nhận các giá trị mà người dùng nhập vào các tiện ích. Bảng sau đây cho biết cách lấy giá trị cho một tiện ích đầu vào biểu mẫu nhất định. Đối với mỗi tiện ích, bảng này cho biết kiểu dữ liệu mà tiện ích chấp nhận, nơi giá trị được lưu trữ trong sự kiện tương tác và giá trị mẫu.

Tiện ích đầu vào của biểu mẫu Loại dữ liệu đầu vào Giá trị đầu vào từ sự kiện tương tác Giá trị mẫu
textInput stringInputs event.common.formInputs.contactName.stringInputs.value[0] Kai O
selectionInput stringInputs Để lấy giá trị đầu tiên hoặc duy nhất, hãy dùng event.common.formInputs.contactType.stringInputs.value[0] Personal
dateTimePicker chỉ chấp nhận ngày. dateInput event.common.formInputs.contactBirthdate.dateInput.msSinceEpoch. 1000425600000

Chuyển dữ liệu sang thẻ khác

Sau khi người dùng gửi thông tin từ một thẻ, bạn có thể cần trả về các thẻ bổ sung để thực hiện bất kỳ thao tác nào sau đây:

  • Giúp người dùng hoàn tất các biểu mẫu dài hơn bằng cách tạo các phần riêng biệt.
  • Cho phép người dùng xem trước và xác nhận thông tin từ thẻ ban đầu để họ có thể xem lại câu trả lời trước khi gửi.
  • Điền sẵn các phần còn lại của biểu mẫu một cách linh hoạt. Ví dụ: để nhắc người dùng tạo cuộc hẹn, một ứng dụng Chat có thể hiển thị thẻ ban đầu yêu cầu lý do của cuộc hẹn, sau đó điền sẵn thông tin vào một thẻ khác cung cấp thời gian có thể hẹn dựa trên loại cuộc hẹn.

Để chuyển dữ liệu đầu vào từ thẻ ban đầu, bạn có thể tạo tiện ích button bằng actionParameters chứa name của tiện ích và giá trị mà người dùng nhập, như minh hoạ trong ví dụ sau:

Node.js

node/contact-form-app/index.js
buttonList: { buttons: [{
  text: "Submit",
  onClick: { action: {
    function: "submitForm",
    parameters: [{
      key: "contactName", value: name }, {
      key: "contactBirthdate", value: birthdate }, {
      key: "contactType", value: type
    }]
  }}
}]}

Python

python/contact-form-app/main.py
'buttonList': { 'buttons': [{
  'text': "Submit",
  'onClick': { 'action': {
    'function': "submitForm",
    'parameters': [{
      'key': "contactName", 'value': name }, {
      'key': "contactBirthdate", 'value': birthdate }, {
      'key': "contactType", 'value': type
    }]
  }}
}]}

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
new GoogleAppsCardV1Widget().setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(new GoogleAppsCardV1Button()
  .setText("Submit")
  .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
    .setFunction("submitForm")
    .setParameters(List.of(
      new GoogleAppsCardV1ActionParameter().setKey("contactName").setValue(name),
      new GoogleAppsCardV1ActionParameter().setKey("contactBirthdate").setValue(birthdate),
      new GoogleAppsCardV1ActionParameter().setKey("contactType").setValue(type))))))))));

Apps Script

apps-script/contact-form-app/main.gs
buttonList: { buttons: [{
  text: "Submit",
  onClick: { action: {
    function: "submitForm",
    parameters: [{
      key: "contactName", value: name }, {
      key: "contactBirthdate", value: birthdate }, {
      key: "contactType", value: type
    }]
  }}
}]}

Khi người dùng nhấp vào nút này, ứng dụng Chat của bạn sẽ nhận được một sự kiện tương tác CARD_CLICKED mà từ đó bạn có thể nhận dữ liệu.

Trả lời nội dung đã gửi trong biểu mẫu

Sau khi nhận được dữ liệu từ một thông báo hoặc hộp thoại trên thẻ, ứng dụng Chat sẽ phản hồi bằng cách xác nhận đã nhận được hoặc trả về lỗi.

Trong ví dụ sau, một ứng dụng trò chuyện sẽ gửi tin nhắn văn bản để xác nhận rằng ứng dụng đã nhận được biểu mẫu được gửi từ một thông báo hộp thoại hoặc thẻ.

Node.js

node/contact-form-app/index.js
const contactName = event.common.parameters["contactName"];
// Checks to make sure the user entered a contact name.
// If no name value detected, returns an error message.
const errorMessage = "Don't forget to name your new contact!";
if (!contactName && event.dialogEventType === "SUBMIT_DIALOG") {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { actionStatus: {
      statusCode: "INVALID_ARGUMENT",
      userFacingMessage: errorMessage
    }}
  }};
}

Python

python/contact-form-app/main.py
contact_name = event.get('common').get('parameters')["contactName"]
# Checks to make sure the user entered a contact name.
# If no name value detected, returns an error message.
error_message = "Don't forget to name your new contact!"
if contact_name == "" and "SUBMIT_DIALOG" == event.get('dialogEventType'):
  return { 'actionResponse': {
    'type': "DIALOG",
    'dialogAction': { 'actionStatus': {
      'statusCode': "INVALID_ARGUMENT",
      'userFacingMessage': error_message
    }}
  }}

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
String contactName = event.at("/common/parameters/contactName").asText();
// Checks to make sure the user entered a contact name.
// If no name value detected, returns an error message.
String errorMessage = "Don't forget to name your new contact!";
if (contactName.isEmpty() && event.at("/dialogEventType") != null && "SUBMIT_DIALOG".equals(event.at("/dialogEventType").asText())) {
  return new Message().setActionResponse(new ActionResponse()
    .setType("DIALOG")
    .setDialogAction(new DialogAction().setActionStatus(new ActionStatus()
      .setStatusCode("INVALID_ARGUMENT")
      .setUserFacingMessage(errorMessage))));
}

Apps Script

apps-script/contact-form-app/main.gs
const contactName = event.common.parameters["contactName"];
// Checks to make sure the user entered a contact name.
// If no name value detected, returns an error message.
const errorMessage = "Don't forget to name your new contact!";
if (!contactName && event.dialogEventType === "SUBMIT_DIALOG") {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { actionStatus: {
      statusCode: "INVALID_ARGUMENT",
      userFacingMessage: errorMessage
    }}
  }};
}

Để xử lý và đóng một hộp thoại, bạn sẽ trả về một đối tượng ActionResponse chỉ định xem bạn có muốn gửi một thông báo xác nhận, cập nhật thông báo hoặc thẻ ban đầu hay chỉ đóng hộp thoại. Để biết các bước, hãy xem phần Đóng hộp thoại.

Khắc phục sự cố

Khi một ứ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ị bất kỳ thông báo lỗi nào, nhưng ứng dụng hoặc thẻ Chat 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 xuất hiện trong giao diện người dùng Chat, nhưng bạn có thể sử dụng 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 lỗi trong Google Chat.