如果您希望用户从多个选项中选择一个以便继续处理您的 Action,请使用可视化选择响应。您可以在提示中使用以下视觉选择响应类型:
- 列表
- 集合
- 藏馆浏览
在定义视觉选择响应时,请使用具有 RICH_RESPONSE
surface 功能的“候选”,以便 Google 助理仅在支持的设备上返回响应。在提示中,您只能对每个 content
对象使用一个富响应。
添加可视化选择响应
视觉选择响应在场景中使用槽位填充,以显示用户可以选择的选项并处理所选项。当用户选择某个列表项时,Google 助理会将选定项的值作为参数传递给您的网络钩子。然后,在实参值中,您会收到所选项的键。
您必须先定义一个类型,用来表示用户之后选择的响应,然后才能使用视觉选择响应。在 webhook 中,您可以使用要显示以供选择的内容替换相应类型。
如需在 Actions Builder 中为场景添加视觉选择响应,请按以下步骤操作:
- 在场景中,向槽填充部分添加一个槽。
- 为视觉选择响应选择之前定义的类型,并为其命名。您的网络钩子稍后会使用此槽名称来引用该类型。
- 勾选 Call your webhook 复选框,并提供 webhook 中要用于视觉选择响应的事件处理脚本的名称。
- 勾选 Send prompts 复选框。
- 在提示中,根据要返回的视觉选择响应提供相应的 JSON 或 YAML 内容。
- 在您的 webhook 中,按照处理所选内容中的步骤操作。
如需了解可用的提示属性和替换类型示例,请参阅下面的 list、collection 和 集合浏览部分。
处理所选内容
如果是可视化选择响应,您需要在网络钩子代码中处理用户的选择。当用户从视觉选择响应中选择内容时,Google 助理会使用该值填充槽。
在以下示例中,webhook 代码会接收所选选项并将其存储在变量中:
Node.js
app.handle('Option', conv => { // Note: 'prompt_option' is the name of the slot. const selectedOption = conv.session.params.prompt_option; conv.add(`You selected ${selectedOption}.`); });
JSON
{ "responseJson": { "session": { "id": "session_id", "params": { "prompt_option": "ITEM_1" } }, "prompt": { "override": false, "firstSimple": { "speech": "You selected ITEM_1.", "text": "You selected ITEM_1." } } } }
列表
列表可向用户显示包含多个项的垂直列表,并允许用户通过轻触或语音输入来选择一个项。当用户从列表中选择某个项时,Google 助理会生成包含列表项标题的用户查询(聊天气泡)。
列表非常适用于需要消除选项歧义的情况,或者用户需要在需要完整扫描的选项之间进行选择。例如,您需要和哪个“Peter”对话,Peter Jons 还是 Peter Hans?
列表必须包含最少 2 个列表项,最多包含 30 个列表项。最初显示的元素数量取决于用户的设备,常见的起始数量是 10 个项。
创建列表
创建列表时,您的提示仅包含用户可以选择的每项内容的键。在网络钩子中,您可以根据 Entry
类型定义与这些键对应的项。
定义为 Entry
对象的列表项具有以下显示特征:
- 标题
- 固定的字体和字号
- 最大长度:1 行(用省略号截断)
- 必须是唯一的(以支持语音选择)
- 说明(可选)
- 固定的字体和字号
- 最大长度:2 行(用省略号截断...)
- 图片(可选)
- 尺寸:48x48 像素
可视化选择响应要求您在 TYPE_REPLACE
模式下使用运行时类型按槽名称替换类型。在 webhook 事件处理脚本中,通过 name
属性中的槽名称(在添加选择响应中定义)引用要替换的类型。
类型被覆盖后,结果类型表示用户可以从 Google 助理显示的项中进行选择的列表。
属性
列表响应类型具有以下属性:
媒体资源 | 类型 | 要求 | 说明 |
---|---|---|---|
items |
ListItem 的数组 |
必需 | 表示列表中用户可选择的项。每个 ListItem 都包含一个键,该键会映射到列表项的引用类型的。 |
title |
string | 可选 | 列表的纯文本标题,仅限一行。如果未指定标题,卡片高度会收起。 |
subtitle |
string | 可选 | 列表的纯文本副标题。 |
示例代码
以下示例在 webhook 代码或 JSON webhookResponse 中定义提示内容。不过,您也可以在 Actions Builder 中定义提示内容(采用 YAML 或 JSON 格式)。
Node.js
const ASSISTANT_LOGO_IMAGE = new Image({ url: 'https://developers.google.com/assistant/assistant_96.png', alt: 'Google Assistant logo' }); app.handle('List', conv => { conv.add('This is a list.'); // Override type based on slot 'prompt_option' conv.session.typeOverrides = [{ name: 'prompt_option', mode: 'TYPE_REPLACE', synonym: { entries: [ { name: 'ITEM_1', synonyms: ['Item 1', 'First item'], display: { title: 'Item #1', description: 'Description of Item #1', image: ASSISTANT_LOGO_IMAGE, } }, { name: 'ITEM_2', synonyms: ['Item 2', 'Second item'], display: { title: 'Item #2', description: 'Description of Item #2', image: ASSISTANT_LOGO_IMAGE, } }, { name: 'ITEM_3', synonyms: ['Item 3', 'Third item'], display: { title: 'Item #3', description: 'Description of Item #3', image: ASSISTANT_LOGO_IMAGE, } }, { name: 'ITEM_4', synonyms: ['Item 4', 'Fourth item'], display: { title: 'Item #4', description: 'Description of Item #4', image: ASSISTANT_LOGO_IMAGE, } }, ] } }]; // Define prompt content using keys conv.add(new List({ title: 'List title', subtitle: 'List subtitle', items: [ { key: 'ITEM_1' }, { key: 'ITEM_2' }, { key: 'ITEM_3' }, { key: 'ITEM_4' } ], })); });
JSON
{ "responseJson": { "session": { "id": "session_id", "params": {}, "typeOverrides": [ { "name": "prompt_option", "synonym": { "entries": [ { "name": "ITEM_1", "synonyms": [ "Item 1", "First item" ], "display": { "title": "Item #1", "description": "Description of Item #1", "image": { "alt": "Google Assistant logo", "height": 0, "url": "https://developers.google.com/assistant/assistant_96.png", "width": 0 } } }, { "name": "ITEM_2", "synonyms": [ "Item 2", "Second item" ], "display": { "title": "Item #2", "description": "Description of Item #2", "image": { "alt": "Google Assistant logo", "height": 0, "url": "https://developers.google.com/assistant/assistant_96.png", "width": 0 } } }, { "name": "ITEM_3", "synonyms": [ "Item 3", "Third item" ], "display": { "title": "Item #3", "description": "Description of Item #3", "image": { "alt": "Google Assistant logo", "height": 0, "url": "https://developers.google.com/assistant/assistant_96.png", "width": 0 } } }, { "name": "ITEM_4", "synonyms": [ "Item 4", "Fourth item" ], "display": { "title": "Item #4", "description": "Description of Item #4", "image": { "alt": "Google Assistant logo", "height": 0, "url": "https://developers.google.com/assistant/assistant_96.png", "width": 0 } } } ] }, "typeOverrideMode": "TYPE_REPLACE" } ] }, "prompt": { "override": false, "content": { "list": { "items": [ { "key": "ITEM_1" }, { "key": "ITEM_2" }, { "key": "ITEM_3" }, { "key": "ITEM_4" } ], "subtitle": "List subtitle", "title": "List title" } }, "firstSimple": { "speech": "This is a list.", "text": "This is a list." } } } }
集合
集合可水平滚动,并允许用户通过轻触或语音输入选择一项。与列表相比,集合具有较大的图块,并支持更丰富的内容。构成集合的图块与带有图片的基本卡片类似。当用户从集合中选择某个项时,Google 助理会生成包含该项标题的用户查询(聊天气泡)。
在向用户显示各种选项时,最好使用集合,但无需对选项进行直接比较(与列表相比)。一般来说,首选列表而非集合,因为列表更便于视觉浏览和通过语音进行互动。
集合必须包含最少 2 个、最多 10 个图块。在支持显示的设备上,用户可以向左或向右滑动以滚动浏览集合中的卡片,然后再选择某个项。
创建集合
创建集合时,您的提示仅包含用户可以选择的每个项目的键。在 webhook 中,您可以根据 Entry
类型定义与这些键对应的项。
定义为 Entry
对象的集合项具有以下显示特征:
- 图片(可选)
- 强制图片尺寸为 128 dp 高 x 232 dp 宽
- 如果图片宽高比与图片边界框不匹配,则图片的两侧会居中放置
- 如果图片链接已损坏,则改用占位图片
- 标题(必填)
- 纯文本,不支持 Markdown。格式选项与基本卡片丰富响应相同
- 如果未指定标题,卡片高度会收起。
- 必须是唯一的(以支持语音选择)
- 说明(可选)
- 纯文本,不支持 Markdown。格式选项与基本卡片丰富响应相同
可视化选择响应要求您在 TYPE_REPLACE
模式下使用运行时类型按槽名称替换类型。在 webhook 事件处理脚本中,通过 name
属性中的槽名称(在添加选择响应中定义)引用要替换的类型。
类型被覆盖后,生成的类型表示用户可以从 Google 助理显示的项中选择的集合。
属性
集合响应类型具有以下属性:
媒体资源 | 类型 | 要求 | 说明 |
---|---|---|---|
items |
CollectionItem 的数组 |
必需 | 表示用户可以选择的集合中的项。每个 CollectionItem 都包含一个键,该键映射到集合项的引用类型的。 |
title |
string | 可选 | 集合的纯文本标题。标题在集合中必须是唯一的,才能支持语音选择。 |
subtitle |
string | 可选 | 合集的纯文本副标题。 |
image_fill |
ImageFill |
可选 | 当图片的宽高比与图片容器的宽高比不符时,要使用的卡片与图片容器之间的边框。 |
示例代码
以下示例定义了网络钩子代码或 JSON 网络钩子响应中的提示内容。不过,您也可以在 Actions Builder 中定义提示内容(采用 YAML 或 JSON 格式)。
Node.js
const ASSISTANT_LOGO_IMAGE = new Image({ url: 'https://developers.google.com/assistant/assistant_96.png', alt: 'Google Assistant logo' }); app.handle('Collection', conv => { conv.add("This is a collection."); // Override type based on slot 'prompt_option' conv.session.typeOverrides = [{ name: 'prompt_option', mode: 'TYPE_REPLACE', synonym: { entries: [ { name: 'ITEM_1', synonyms: ['Item 1', 'First item'], display: { title: 'Item #1', description: 'Description of Item #1', image: ASSISTANT_LOGO_IMAGE, } }, { name: 'ITEM_2', synonyms: ['Item 2', 'Second item'], display: { title: 'Item #2', description: 'Description of Item #2', image: ASSISTANT_LOGO_IMAGE, } }, { name: 'ITEM_3', synonyms: ['Item 3', 'Third item'], display: { title: 'Item #3', description: 'Description of Item #3', image: ASSISTANT_LOGO_IMAGE, } }, { name: 'ITEM_4', synonyms: ['Item 4', 'Fourth item'], display: { title: 'Item #4', description: 'Description of Item #4', image: ASSISTANT_LOGO_IMAGE, } }, ] } }]; // Define prompt content using keys conv.add(new Collection({ title: 'Collection Title', subtitle: 'Collection subtitle', items: [ { key: 'ITEM_1' }, { key: 'ITEM_2' }, { key: 'ITEM_3' }, { key: 'ITEM_4' } ], })); });
JSON
{ "responseJson": { "session": { "id": "ABwppHHz--uQEEy3CCOANyB0J58oF2Yw5JEX0oXwit3uxDlRwzbEIK3Bcz7hXteE6hWovrLX9Ahpqu8t-jYnQRFGpAUqSuYjZ70", "params": {}, "typeOverrides": [ { "name": "prompt_option", "synonym": { "entries": [ { "name": "ITEM_1", "synonyms": [ "Item 1", "First item" ], "display": { "title": "Item #1", "description": "Description of Item #1", "image": { "alt": "Google Assistant logo", "height": 0, "url": "https://developers.google.com/assistant/assistant_96.png", "width": 0 } } }, { "name": "ITEM_2", "synonyms": [ "Item 2", "Second item" ], "display": { "title": "Item #2", "description": "Description of Item #2", "image": { "alt": "Google Assistant logo", "height": 0, "url": "https://developers.google.com/assistant/assistant_96.png", "width": 0 } } }, { "name": "ITEM_3", "synonyms": [ "Item 3", "Third item" ], "display": { "title": "Item #3", "description": "Description of Item #3", "image": { "alt": "Google Assistant logo", "height": 0, "url": "https://developers.google.com/assistant/assistant_96.png", "width": 0 } } }, { "name": "ITEM_4", "synonyms": [ "Item 4", "Fourth item" ], "display": { "title": "Item #4", "description": "Description of Item #4", "image": { "alt": "Google Assistant logo", "height": 0, "url": "https://developers.google.com/assistant/assistant_96.png", "width": 0 } } } ] }, "typeOverrideMode": "TYPE_REPLACE" } ] }, "prompt": { "override": false, "content": { "collection": { "imageFill": "UNSPECIFIED", "items": [ { "key": "ITEM_1" }, { "key": "ITEM_2" }, { "key": "ITEM_3" }, { "key": "ITEM_4" } ], "subtitle": "Collection subtitle", "title": "Collection Title" } }, "firstSimple": { "speech": "This is a collection.", "text": "This is a collection." } } } }
藏馆浏览
与集合浏览类似,集合浏览也是一种富响应,允许用户滚动浏览选项卡片。集合浏览是专为网页内容设计的,可在网络浏览器(如果所有功能块均已启用 AMP,则在 AMP 浏览器)中打开所选功能块。
集合浏览响应包含最少 2 个、最多 10 个图块。在支持显示的设备上,用户可以向上或向下滑动以滚动浏览卡片,然后再选择项目。
创建集合浏览
创建集合浏览时,请考虑用户与此提示的互动情况。每个集合浏览 item
都会打开其定义的网址,因此应向用户提供有用的详细信息。
集合浏览项具有以下显示特征:
- 图片(可选)
- 图片被强制设置为 128 dp 高 x 232 dp 宽。
- 如果图片宽高比与图片边界框不匹配,则图片的两侧或顶部和底部会居中显示条形。条形的颜色由集合浏览
ImageFill
属性确定。 - 如果图片链接已损坏,系统会使用占位图片来代替它。
- 标题(必填)
- 纯文本,不支持 Markdown。使用与基本卡片富响应相同的格式。
- 如果未指定标题,卡片高度会收起。
- 说明(可选)
- 纯文本,不支持 Markdown。使用与基本卡片富响应相同的格式。
- 页脚(可选)
- 纯文本;不支持 Markdown。
属性
集合浏览响应类型具有以下属性:
媒体资源 | 类型 | 要求 | 说明 |
---|---|---|---|
item |
对象 | 必需 | 表示用户可以选择的集合中的项。 |
image_fill |
ImageFill |
可选 | 当图片的宽高比与图片容器的宽高比不一致时,要使用的卡片和图片容器之间的边框。 |
集合浏览 item
具有以下属性:
媒体资源 | 类型 | 要求 | 说明 |
---|---|---|---|
title |
string | 必需 | 合集项的纯文本标题。 |
description |
string | 可选 | 合集项的说明。 |
footer |
string | 可选 | 合集项的页脚文本,显示在说明下方。 |
image |
Image |
可选 | 为合集项显示的图片。 |
openUriAction |
OpenUrl |
必需 | 要在集合项被选中时打开的 URI。 |
示例代码
以下示例定义了网络钩子代码或 JSON 网络钩子响应中的提示内容。不过,您也可以在 Actions Builder 中定义提示内容(采用 YAML 或 JSON 格式)。
YAML
candidates: - first_simple: variants: - speech: This is a collection browse. content: collection_browse: items: - title: Item #1 description: Description of Item #1 footer: Footer of Item #1 image: url: 'https://developers.google.com/assistant/assistant_96.png' open_uri_action: url: 'https://www.example.com' - title: Item #2 description: Description of Item #2 footer: Footer of Item #2 image: url: 'https://developers.google.com/assistant/assistant_96.png' open_uri_action: url: 'https://www.example.com' image_fill: WHITE
JSON
{ "candidates": [ { "firstSimple": { "speech": "This is a collection browse.", "text": "This is a collection browse." }, "content": { "collectionBrowse": { "items": [ { "title": "Item #1", "description": "Description of Item #1", "footer": "Footer of Item #1", "image": { "url": "https://developers.google.com/assistant/assistant_96.png" }, "openUriAction": { "url": "https://www.example.com" } }, { "title": "Item #2", "description": "Description of Item #2", "footer": "Footer of Item #2", "image": { "url": "https://developers.google.com/assistant/assistant_96.png" }, "openUriAction": { "url": "https://www.example.com" } } ], "imageFill": "WHITE" } } } ] }
Node.js
// Collection Browse app.handle('collectionBrowse', (conv) => { conv.add('This is a collection browse.'); conv.add(new CollectionBrowse({ 'imageFill': 'WHITE', 'items': [ { 'title': 'Item #1', 'description': 'Description of Item #1', 'footer': 'Footer of Item #1', 'image': { 'url': 'https://developers.google.com/assistant/assistant_96.png' }, 'openUriAction': { 'url': 'https://www.example.com' } }, { 'title': 'Item #2', 'description': 'Description of Item #2', 'footer': 'Footer of Item #2', 'image': { 'url': 'https://developers.google.com/assistant/assistant_96.png' }, 'openUriAction': { 'url': 'https://www.example.com' } } ] })); });
JSON
{ "responseJson": { "session": { "id": "session_id", "params": {}, "languageCode": "" }, "prompt": { "override": false, "content": { "collectionBrowse": { "imageFill": "WHITE", "items": [ { "title": "Item #1", "description": "Description of Item #1", "footer": "Footer of Item #1", "image": { "url": "https://developers.google.com/assistant/assistant_96.png" }, "openUriAction": { "url": "https://www.example.com" } }, { "title": "Item #2", "description": "Description of Item #2", "footer": "Footer of Item #2", "image": { "url": "https://developers.google.com/assistant/assistant_96.png" }, "openUriAction": { "url": "https://www.example.com" } } ] } }, "firstSimple": { "speech": "This is a collection browse.", "text": "This is a collection browse." } } } }