收集和处理 Google Chat 用户的信息

本指南介绍了 Google Chat 应用如何通过在基于卡片的界面中构建表单输入项来收集和处理用户信息。

在 Google Chat 中,插件会以 Google Chat 应用的形式向用户显示。如需了解详情,请参阅扩展 Google Chat 概览

一个包含各种不同 widget 的对话框。
图 1:打开对话框以收集联系信息的 Chat 应用。

Chat 应用会向用户请求信息,以便在 Chat 中或之外执行操作,包括通过以下方式:

  • 配置设置。例如,让用户自定义通知设置,或配置并将 Chat 应用添加到一个或多个聊天室。
  • 在其他 Google Workspace 应用中创建或更新信息。例如,允许用户创建 Google 日历活动。
  • 允许用户访问和更新其他应用或 Web 服务中的资源。例如,Chat 应用可以帮助用户直接在 Chat 聊天室中更新支持服务工单的状态。

前提条件

Node.js

可在 Google Chat 中使用的 Google Workspace 插件。如需构建一个,请完成 HTTP 快速入门

Apps 脚本

可在 Google Chat 中使用的 Google Workspace 插件。如需构建一个,请完成 Apps 脚本快速入门

使用卡片构建表单

为了收集信息,Chat 应用会设计表单及其输入内容,并将其构建为卡片。如需向用户显示卡片,Chat 应用可以使用以下 Chat 界面:

  • 包含一个或多个卡片的聊天消息。
  • 对话框:即从消息和首页在新窗口中打开的卡片。

Chat 应用可以使用以下微件构建卡片:

  • 用于向用户请求信息的表单输入 widget。(可选)您可以为表单输入 widget 添加验证,以确保用户正确输入和设置信息格式。聊天应用可以使用以下表单输入微件:

    • 文本输入 (textInput),用于输入自由格式文本或建议文本。
    • 选择输入 (selectionInput) 是可选择的界面元素,例如复选框、单选按钮和下拉菜单。选择输入 widget 还可以从静态或动态数据源填充项。例如,用户可以从他们所属的 Chat 聊天室列表中进行选择。
  • 一个按钮 widget,以便用户提交在卡片中输入的值。用户点击该按钮后,Chat 应用便可以处理收到的信息

在以下示例中,卡片使用文本输入框、日期时间选择器和选择输入框来收集联系信息:

如需查看可用于收集信息的互动式 widget 的更多示例,请参阅 Google Chat API 文档中的设计互动式卡片或对话框

接收来自互动 widget 的数据

每当用户点击某个按钮时,系统都会触发其 Chat 应用操作,并附带有关互动的信息。在事件载荷的 commonEventObject 中,formInputs 对象包含用户输入的任何值。

您可以从对象 commonEventObject.formInputs.WIDGET_NAME 检索值,其中 WIDGET_NAME 是您为该 widget 指定的 name 字段。这些值会以特定数据类型返回给 widget。

以下是事件对象的一部分,其中用户为每个 widget 输入了值:

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

如需接收数据,您的 Chat 应用会处理事件对象,以获取用户输入到 widget 中的值。下表展示了如何获取给定表单输入 widget 的值。对于每个 widget,该表会显示 widget 接受的数据类型、值存储在事件对象中的位置,以及示例值。

表单输入微件 输入数据的类型 输入事件对象中的值 示例值
textInput stringInputs event.commonEventObject.formInputs.contactName.stringInputs.value[0] Kai O
selectionInput stringInputs 如需获取第一个或唯一值,请使用 event.commonEventObject.formInputs.contactType.stringInputs.value[0] Personal
仅接受日期的 dateTimePicker dateInput event.commonEventObject.formInputs.contactBirthdate.dateInput.msSinceEpoch 1000425600000

将数据转移到其他卡

用户提交卡片信息后,您可能需要返回其他卡片才能执行以下任一操作:

  • 通过创建不同的部分,帮助用户填写较长的表单。
  • 让用户预览并确认初始卡片中的信息,以便他们在提交前检查自己的回答。
  • 动态填充表单的其余部分。例如,为了提示用户创建预约,Chat 应用可以显示一个初始卡片来请求预约原因,然后填充另一张卡片,根据预约类型提供空闲时间。

如需从初始卡片传输数据输入,您可以使用包含微件的 name 和用户输入的值的 actionParameters 构建 button 微件,如以下示例所示:

{
  "buttonList": { "buttons": [{
    "text": "Submit",
    "onClick": { "action": {
      "function": "submitForm",
      "parameters": [
        {
          "key": "WIDGET_NAME",
          "value": "USER_INPUT_VALUE"
        },
        // Can specify multiple parameters
      ]
    }}
  }]}
}

其中,WIDGET_NAME 是 widget 的 nameUSER_INPUT_VALUE 是用户输入的内容。例如,对于用于收集用户姓名的文本输入,微件名称为 contactName,示例值为 Kai O

当用户点击该按钮时,您的 Chat 应用会收到一个事件对象,您可以从中接收数据

回复表单提交内容

从卡片消息或对话框收到数据后,Chat 应用会通过确认收到或返回错误来响应。

在以下示例中,Chat 应用发送一条短信,确认已成功收到通过卡片消息提交的表单。

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;
  const chatMessage = chatEvent.messagePayload.message;

  // Handle MESSAGE events
  if(chatEvent.messagePayload) {
    return res.send(handleMessage(chatMessage, chatEvent.user));
  // Handle CARD_CLICKED events
  } else if(chatEvent.buttonClickedPayload) {
    switch(req.body.commonEventObject.parameters.actionName) {
        case "openDialog":
            return res.send(openDialog());
        case "openNextCard":
            return res.send(openNextCard(req.body));
        case "submitForm":
            return res.send(submitForm(req.body));
    }
  }
};

/**
 * Submits information from a dialog or card message.
 *
 * @param {Object} event the interactive event with form inputs.
 * @return {Object} a message response that posts a private message.
 */
function submitForm(event) {
  const chatUser = event.chat.user;
  const contactName = event.commonEventObject.parameters["contactName"];

  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    privateMessageViewer: chatUser,
    text: "✅ " + contactName + " has been added to your contacts."
  }}}}};
}

Apps 脚本

/**
 * Sends private text message that confirms submission.
 *
 * @param {Object} event the interactive event with form inputs.
 * @return {Object} a message response that posts a private message.
 */
function submitForm(event) {
  const chatUser = event.chat.user;
  const contactName = event.commonEventObject.parameters["contactName"];

  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    privateMessageViewer: chatUser,
    text: "✅ " + contactName + " has been added to your contacts."
  }}}}};
}

如需处理和关闭对话框,您需要返回一个 RenderActions 对象,用于指定您是要发送确认消息、更新原始消息或卡片,还是只关闭对话框。如需了解相关步骤,请参阅关闭对话框

问题排查

当 Google Chat 应用或卡片返回错误时,Chat 界面会显示“出了点问题”消息。或“无法处理您的请求”。有时,Chat 界面不会显示任何错误消息,但 Chat 应用或卡片会产生意外结果;例如,卡片消息可能不会显示。

虽然 Chat 界面中可能不会显示错误消息,但当 Chat 应用的错误日志记录功能处于开启状态时,描述性错误消息和日志数据可帮助您修正错误。如需有关查看、调试和修复错误的帮助,请参阅排查和修复 Google Chat 错误