视觉选择响应

如果您希望用户从多个选项中选择一个以便继续处理您的 Action,请使用可视化选择响应。您可以在提示中使用以下视觉选择响应类型:

  • 列表
  • 集合
  • 藏馆浏览

在定义视觉选择响应时,请使用具有 RICH_RESPONSE surface 功能的“候选”,以便 Google 助理仅在支持的设备上返回响应。在提示中,您只能对每个 content 对象使用一个富响应。

添加可视化选择响应

视觉选择响应在场景中使用槽位填充,以显示用户可以选择的选项并处理所选项。当用户选择某个列表项时,Google 助理会将选定项的值作为参数传递给您的网络钩子。然后,在实参值中,您会收到所选项的键。

您必须先定义一个类型,用来表示用户之后选择的响应,然后才能使用视觉选择响应。在 webhook 中,您可以使用要显示以供选择的内容替换相应类型。

如需在 Actions Builder 中为场景添加视觉选择响应,请按以下步骤操作:

  1. 在场景中,向槽填充部分添加一个槽。
  2. 为视觉选择响应选择之前定义的类型,并为其命名。您的网络钩子稍后会使用此槽名称来引用该类型。
  3. 勾选 Call your webhook 复选框,并提供 webhook 中要用于视觉选择响应的事件处理脚本的名称。
  4. 勾选 Send prompts 复选框。
  5. 在提示中,根据要返回的视觉选择响应提供相应的 JSON 或 YAML 内容。
  6. 在您的 webhook 中,按照处理所选内容中的步骤操作。

如需了解可用的提示属性和替换类型示例,请参阅下面的 listcollection集合浏览部分。

处理所选内容

如果是可视化选择响应,您需要在网络钩子代码中处理用户的选择。当用户从视觉选择响应中选择内容时,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。

属性

集合浏览响应类型具有以下属性:

媒体资源 类型 要求 说明
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."
      }
    }
  }
}