本指南介绍了 Google Chat 应用如何通过在卡片式界面中构建表单输入来收集和处理用户信息。
Chat 应用会请求用户提供信息,以便在 Chat 内部或外部执行操作,包括通过以下方式:
- 配置设置。例如,允许用户自定义通知设置,或配置 Chat 应用并将其添加到一个或多个聊天室。
- 在其他 Google Workspace 应用中创建或更新信息。例如,让用户创建 Google 日历活动。
- 让用户可以访问和更新其他应用或 Web 服务中的资源。例如,Chat 应用可以帮助用户 直接在 Chat 聊天室中更新支持服务工单的状态
前提条件
HTTP
Apps 脚本
接收并响应用户互动的 Google Chat 应用。如需构建一个,请完成 Apps 脚本快速入门。
使用卡片构建表单
为了收集信息,Chat 应用会设计表单及其输入,并将其构建到卡片中。如需向用户显示卡片,Chat 应用可以使用以下 Chat 界面:
Chat 应用可以使用以下 widget 构建卡片:
向用户请求信息的表单输入 widget。(可选)您可以向表单输入 widget 添加验证,以确保用户正确输入和设置信息格式。Chat 应用可以使用以下表单输入 widget:
在以下示例中,卡片使用文本输入、日期时间选择器和选择输入来收集联系信息:
如需查看可用于收集信息的互动式 widget 的更多示例,请参阅设计互动式卡片或对话框。
添加下拉菜单
如需自定义选择项或让用户从动态数据源中选择单个项,Chat 应用可以使用下拉菜单,这是一种 SelectionInput widget。例如,以下卡片显示了一个下拉菜单,用户可以从中动态选择联系人列表:
您可以从以下数据源填充下拉菜单中的项:
- Google Workspace 数据,包括用户或 Chat 聊天室。
- 外部数据源,例如关系型数据库。
从 Google Workspace 数据源填充内容
如需从 Google Workspace 数据源(例如 Google Workspace 用户)填充内容,请在 DataSourceConfig 对象中指定 platformDataSource 字段。与其他选择输入类型不同,您需要省略 SelectionItem 对象,因为这些选择项是从 Google Workspace 动态获取的。
以下代码显示了 Google Workspace 用户的下拉菜单:
JSON
{
"sections": [
{
"header": "Section Header",
"widgets": [
{
"selectionInput": {
"name": "contacts",
"type": "DROPDOWN",
"label": "Select contact from organization",
"dataSourceConfigs": [
{
"platformDataSource": {
"commonDataSource": "USER"
},
"minCharactersTrigger": 1
}
]
}
}
]
}
]
}
从外部数据源填充内容
下拉菜单还可以填充来自第三方或外部数据源的内容。如需使用外部数据源,您需要在 DataSourceConfig 对象中指定 remoteDataSource 字段,该对象包含用于查询和返回数据源中内容的函数。
为了减少对外部数据源的请求,您可以在用户输入内容之前,在下拉菜单中显示建议的项。如需从外部数据源填充建议的内容,请指定静态 SelectionItem 对象。
以下代码展示了一个下拉菜单,该菜单会查询外部数据源并填充其中的项:
JSON
{
"sections": [
{
"header": "Section Header",
"widgets": [
{
"selectionInput": {
"name": "crm_leads",
"type": "DROPDOWN",
"label": "Select CRM Lead",
"dataSourceConfigs": [
{
"remoteDataSource": {
"function": "getCrmLeads"
},
"minCharactersTrigger": 2
}
],
"items": [
{
"text": "Suggested Lead 1",
"value": "lead-1"
}
]
}
}
]
}
]
}
如需查看展示如何返回建议内容的已完成示例,请参阅建议选择内容部分。
添加多选菜单
如需自定义选择项或让用户从动态数据源中选择内容,Chat 应用可以使用多选菜单,这是一种 SelectionInput widget。例如,以下卡片显示了一个多选菜单,用户可以从中动态选择联系人列表:
您可以通过以下数据源填充多选菜单的选项:
- Google Workspace 数据,包括用户或用户所属的 Chat 聊天室。该菜单仅填充来自同一 Google Workspace 组织的内容。
- 外部数据源,例如关系型数据库。例如,您可以使用多选菜单帮助用户从客户关系管理 (CRM) 系统中的潜在客户列表中进行选择。
从 Google Workspace 数据源填充内容
如需使用 Google Workspace 数据源,请在 SelectionInput widget 中指定 platformDataSource 字段。与其他选择输入类型不同,您需要省略 SelectionItem 对象,因为这些选择项是从 Google Workspace 动态获取的。
以下代码展示了一个包含 Google Workspace 用户的多选菜单。
为了填充用户,选择输入会将 commonDataSource 设置为 USER:
JSON
{
"selectionInput": {
"name": "contacts",
"type": "MULTI_SELECT",
"label": "Selected contacts",
"multiSelectMaxSelectedItems": 5,
"multiSelectMinQueryLength": 1,
"platformDataSource": {
"commonDataSource": "USER"
}
}
}
以下代码显示了 Chat 空间的多选菜单。为了填充聊天室,选择输入指定了 hostAppDataSource 字段。多选菜单还会将 defaultToCurrentSpace 设置为 true,这会使当前聊天室成为菜单中的默认选择:
JSON
{
"selectionInput": {
"name": "spaces",
"type": "MULTI_SELECT",
"label": "Selected contacts",
"multiSelectMaxSelectedItems": 3,
"multiSelectMinQueryLength": 1,
"platformDataSource": {
"hostAppDataSource": {
"chatDataSource": {
"spaceDataSource": {
"defaultToCurrentSpace": true
}
}
}
}
}
}
从外部数据源填充内容
多选菜单还可以从第三方或外部数据源填充内容。如需使用外部数据源,您需要在 SelectionInput widget 中指定 externalDataSource 字段,该字段包含用于查询和返回数据源中内容的函数。
为了减少对外部数据源的请求,您可以在用户在菜单中输入内容之前,添加显示在多选菜单中的建议项。例如,您可以为用户填充最近搜索过的联系人。如需从外部数据源填充建议的内容,请指定静态 SelectionItem 对象。
以下代码示例展示了一个多选菜单,该菜单会查询外部数据源中的内容并填充到菜单中:
Node.js
将 FUNCTION_URL 替换为查询外部数据源的 HTTP 端点。
Python
将 FUNCTION_URL 替换为查询外部数据源的 HTTP 端点。
Java
将 FUNCTION_URL 替换为查询外部数据源的 HTTP 端点。
Apps 脚本
此示例通过返回卡片 JSON 发送卡片消息。您还可以使用 Apps 脚本卡片服务。
如需查看展示如何返回建议内容的已完成示例,请参阅建议选择内容部分。
从互动微件接收数据
每当用户点击按钮时,系统都会触发其 Chat 应用操作,并提供有关互动的信息。在事件载荷的 commonEventObject 中,formInputs 对象包含用户输入的任何值。
您可以从对象 event.commonEventObject.formInputs.WIDGET_NAME 中检索值,其中 WIDGET_NAME 是您为 widget 指定的 name 字段。这些值会作为微件的特定数据类型返回。
下面显示了事件对象的一部分,其中用户为每个 widget 输入了值:
{
"commonEventObject": { "formInputs": {
"contactName": { "stringInputs": {
"value": ["Kai 0"]
}},
"contactBirthdate": { "dateInput": {
"msSinceEpoch": 1000425600000
}},
"contactType": { "stringInputs": {
"value": ["Personal"]
}}
}}
}
为了接收数据,您的 Chat 应用会处理事件对象,以获取用户在微件中输入的值。下表显示了如何获取给定表单输入 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 应用收到数据后,可以执行以下任一操作:
建议选择项
如果卡片包含多选菜单或从外部数据源填充内容的下拉菜单,Chat 应用可以根据用户在菜单中输入的内容返回建议的内容。例如,如果用户开始输入 Atl,而菜单中填充的是美国城市,则 Chat 应用可以在用户输入完毕之前自动建议 Atlanta。Chat 应用最多可以建议 100 项。
如需在选择输入中建议和动态填充内容,卡片上的 SelectionInput widget 必须指定一个查询外部数据源的函数。对于多选菜单,您需要指定 externalDataSource 字段。对于下拉菜单,您可以在 DataSourceConfig 对象中指定 remoteDataSource 字段。
您还可以配置用户在菜单返回建议之前输入的字符数。对于多选菜单,请设置 multiSelectMinQueryLength 字段。对于下拉菜单,请在 DataSourceConfig 中设置 min_characters_trigger 字段。
如需返回建议的商品,该函数必须执行以下操作:
- 处理事件对象,当用户在菜单中输入内容时,Chat 应用会收到该对象。
- 从事件对象中获取用户输入的值,该值在
event.commonEventObject.parameters["autocomplete_widget_query"]字段中表示。 - 使用用户输入值查询数据源,以获取一个或多个
SelectionItems建议给用户。 - 通过返回带有
modifyCard对象的RenderActions操作来返回建议的商品。
以下代码示例展示了 Chat 应用如何在卡片的多选菜单中动态建议选项。当用户在菜单中输入内容时,微件的 externalDataSource 字段中提供的函数或端点会查询外部数据源,并建议用户可以选择的项目。
Node.js
将 FUNCTION_URL 替换为查询外部数据源的 HTTP 端点。
Python
将 FUNCTION_URL 替换为查询外部数据源的 HTTP 端点。
Java
将 FUNCTION_URL 替换为查询外部数据源的 HTTP 端点。
Apps 脚本
此示例通过返回卡片 JSON 发送卡片消息。您还可以使用 Apps 脚本卡片服务。
将数据转移到另一张卡
用户通过卡片提交信息后,您可能需要返回其他卡片,以执行以下任一操作:
- 通过创建不同的部分,帮助用户填写较长的表单。
- 让用户预览并确认初始卡片中的信息,以便他们在提交之前检查自己的回答。
- 动态填充表单的其余部分。例如,为了提示用户创建预约,Chat 应用可以显示一个初始卡片,请求预约原因,然后根据预约类型填充另一个提供可用时间的卡片。
如需传输从初始卡片输入的数据,您可以使用 actionParameters 构建 button widget,其中包含 widget 的 name 和用户输入的值,如以下示例所示:
Node.js
将 FUNCTION_URL 替换为处理按钮点击的 HTTP 端点。
Python
将 FUNCTION_URL 替换为处理按钮点击的 HTTP 端点。
Java
将 FUNCTION_URL 替换为处理按钮点击的 HTTP 端点。
Apps 脚本
此示例通过返回卡片 JSON 发送卡片消息。您还可以使用 Apps 脚本卡片服务。
当用户点击该按钮时,您的 Chat 应用会收到一个事件对象,您可以从中接收数据。
回复表单提交
收到来自卡片消息或对话框的数据后,Chat 应用会通过确认收到或返回错误来做出响应。
在以下示例中,Chat 应用发送了一条短信,确认已成功收到从卡片消息提交的表单。
Node.js
Python
Java
Apps 脚本
此示例通过返回卡片 JSON 发送卡片消息。您还可以使用 Apps 脚本卡片服务。
如需处理和关闭对话框,您需要返回一个 RenderActions 对象,该对象用于指定您是要发送确认消息、更新原始消息或卡片,还是仅关闭对话框。如需了解相关步骤,请参阅关闭对话框。
问题排查
本部分介绍了在 Chat 中与对话框互动时,针对特定错误代码和运行时行为的问题排查步骤。
对话互动返回“调用插件时出现未指明的错误”
与对话框互动时,如果您看到错误日志中包含消息“Unspecified error invoking the add-on.”(调用插件时出现未指明的错误)和代码 13,通常表示发生了内部错误,或者 Chat 应用的 HTTP 端点未能处理请求或返回有效响应。
如需排查此错误,请执行以下操作:
- 检查 HTTP 端点的日志,看看是否有任何未处理的异常或崩溃。
- 验证您的端点是否会在 30 秒内响应请求。如果端点运行时间超过 30 秒,Chat 将无法处理响应,并且互动会失败。如需了解详情,请参阅速率限制和最佳实践。
- 确保您的端点返回有效响应。对于对话框提交,端点必须返回采用正确 JSON 格式的
RenderActions对象。如果响应格式不正确或不包含必填字段,对话框互动可能会失败。
当 Google Chat 应用或卡片返回错误时,Chat 界面会显示一条消息,提示“出了点问题”。 或“无法处理您的请求”。有时,Chat 界面不会显示任何出错提示,但 Chat 应用或卡片会产生意外结果;例如,卡片消息可能不会显示。
虽然 Chat 界面中可能不会显示出错提示,但如果为 Chat 应用启用了日志记录,则可以使用描述性出错提示和日志数据来帮助您修复错误。如需查看、调试和修复错误方面的帮助,请参阅排查和修复 Google Chat 错误。
相关主题
- 查看 Contact Manager 示例,这是一个 Chat 应用,会提示用户通过卡片消息和对话框填写联系表单。
- 打开互动式对话框
非插件的 Chat 扩展应用:读取用户在卡片上输入的表单数据
以下文档适用于非 Google Workspace 插件的 Chat 应用。如需迁移非插件的 Chat 扩展应用,请参阅将 Google Chat 扩展应用转换为 Google Workspace 插件。
使用卡片构建表单
如需查看非插件的 Chat 应用示例,该应用使用包含文本输入、日期时间选择器和选择输入的联系表单,请参阅以下代码:
Node.js
Python
Java
Apps 脚本
从互动微件接收数据
每当用户点击按钮时,非插件的 Chat 应用都会收到互动事件,具体取决于按钮的位置:
如果按钮位于消息或对话框中,则非插件的 Chat 应用会收到包含互动相关信息的
CARD_CLICKED互动事件。CARD_CLICKED互动事件的载荷包含一个common.formInputs对象 (event.common.formInputs),其中包含用户输入的任何值。您可以从对象
common.formInputs.WIDGET_NAME中检索值,其中 WIDGET_NAME 是您为 widget 指定的name字段。这些值会以微件的特定数据类型(表示为Inputs对象)返回。以下示例显示了
CARD_CLICKED互动事件的一部分,其中用户为每个 widget 输入了值:HTTP
{ "type": "CARD_CLICKED", "common": { "formInputs": { "contactName": { "stringInputs": { "value": ["Kai 0"] }}, "contactBirthdate": { "dateInput": { "msSinceEpoch": 1000425600000 }}, "contactType": { "stringInputs": { "value": ["Personal"] }} }} }Apps 脚本
{ "type": "CARD_CLICKED", "common": { "formInputs": { "contactName": { "": { "stringInputs": { "value": ["Kai 0"] }}}, "contactBirthdate": { "": { "dateInput": { "msSinceEpoch": 1000425600000 }}}, "contactType": { "": { "stringInputs": { "value": ["Personal"] }}} }} }如果按钮位于首页,则非插件的 Chat 应用会收到
SUBMIT_FORM互动事件。互动事件的载荷包含一个commonEventObject.formInputs对象 (event.commonEventObject.formInputs),其中包含用户输入的任何值。您可以从对象
commonEventObject.formInputs.WIDGET_NAME中检索值,其中 WIDGET_NAME 是您为 widget 指定的name字段。这些值会作为微件的特定数据类型(表示为Inputs对象)返回。以下示例显示了
SUBMIT_FORM互动事件的一部分,其中用户为每个 widget 输入了值:HTTP
{ "type": "SUBMIT_FORM", "commonEventObject": { "formInputs": { "contactName": { "stringInputs": { "value": ["Kai 0"] }}, "contactBirthdate": { "dateInput": { "msSinceEpoch": 1000425600000 }}, "contactType": { "stringInputs": { "value": ["Personal"] }} }} }Apps 脚本
{ "type": "SUBMIT_FORM", "commonEventObject": { "formInputs": { "contactName": { "": { "stringInputs": { "value": ["Kai 0"] }}}, "contactBirthdate": { "": { "dateInput": { "msSinceEpoch": 1000425600000 }}}, "contactType": { "": { "stringInputs": { "value": ["Personal"] }}} }} }
为了接收数据,非插件的 Chat 应用会处理互动事件,以获取用户输入到 widget 中的值。下表展示了如何获取给定表单输入 widget 的值。对于每个 widget,该表显示了 widget 接受的数据类型、值在互动事件中的存储位置以及示例值。
| 表单输入微件 | 输入数据类型 | 互动事件的输入值 | 示例值 |
|---|---|---|---|
textInput |
stringInputs |
event.common.formInputs.contactName.stringInputs.value[0] |
Kai O |
selectionInput |
stringInputs |
如需获取第一个或唯一的值,请使用 event.common.formInputs.contactType.stringInputs.value[0] |
Personal |
dateTimePicker 仅接受日期。 |
dateInput |
event.common.formInputs.contactBirthdate.dateInput.msSinceEpoch。 |
1000425600000 |
将数据转移到另一张卡
如需从非插件的 Chat 应用中的初始卡片传输数据输入,请使用包含 widget 的 name 和用户输入的值的 actionParameters 构建 button widget,如以下示例所示:
Node.js
Python
Java
Apps 脚本
当用户点击该按钮时,非插件的 Chat 应用会收到 CARD_CLICKED 互动事件,您可以从中接收数据。
回复表单提交
在以下示例中,非插件的 Chat 应用会发送一条短信,确认已成功收到从对话框或卡片消息提交的表单:
Node.js
Python
Java
Apps 脚本
如需在非插件的 Chat 应用中处理和关闭对话框,请返回一个 ActionResponse 对象,该对象指定您是要发送确认消息、更新原始消息或卡片,还是仅关闭对话框。如需了解相关步骤,请参阅关闭对话框。