外觀選項的回覆

如果您希望使用者從多個選項中選取,請使用視覺化的選取回應,以便使用者繼續執行動作。您可以在提示中使用下列視覺選取回應類型:

  • 清單
  • 集合
  • 系列作品瀏覽

定義視覺選取回應時,請使用具有 RICH_RESPONSE 介面功能的「候選」,讓 Google 助理只在支援的裝置上傳回回應。在提示中,每個 content 物件只能使用一個複合式回應。

新增視覺選取回應

視覺選擇回應會在場景中使用運算單元填充功能,藉此呈現使用者可以選取和處理所選項目的選項。使用者選取項目時,Google 助理會將所選項目的值以引數形式傳遞至 Webhook。然後,引數值中您會收到所選項目的鍵。

您必須定義「類型」來表示使用者稍後選取的回應,才能使用視覺化的選取回應。在 Webhook 中,您可以將類型覆寫為可供選取的內容顯示。

如要在動作建構工具中為場景新增視覺化選取回應,請按照下列步驟操作:

  1. 在場景中,新增運算單元至「Slot fill」(運算單元) 部分。
  2. 為視覺選取回應選取先前定義的類型,並為該回應命名。您的 Webhook 稍後會使用這個運算單元名稱來參照類型。
  3. 勾選「Call your Webhook」方塊,然後在 Webhook 中提供您要用於視覺選取回應的事件處理常式名稱。
  4. 勾選「傳送提示」方塊。
  5. 在提示中,根據要傳回的視覺選取回應,提供適當的 JSON 或 YAML 內容。
  6. 在 Webhook 中,按照「處理所選項目」中的步驟進行。

請參閱下方的「清單」、「集合」和「集合瀏覽」一節,瞭解可用的提示屬性及覆寫類型的範例。

處理選取的項目

視覺選取回應需要您處理使用者在 Webhook 程式碼中選擇的項目。當使用者從視覺選擇回應中選取內容時,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 Jons 或 Peter Hans 對哪個「Peter」說話?

清單至少必須包含 2 個清單項目,最多包含 30 個清單項目。一開始顯示的元素數量視使用者的裝置而定,常見的起始數量為 10 個項目。

建立名單

建立清單時,提示只會包含使用者可選取的每個項目的鍵。在 Webhook 中,您可以根據 Entry 類型定義與這些鍵相對應的項目。

定義為 Entry 物件的清單項目具有下列顯示特性:

  • 標題
    • 固定字型與字型大小
    • 長度上限:1 行 (以刪節號截斷...)
    • 必須不重複 (支援語音選取功能)
  • 說明 (選填)
    • 固定字型與字型大小
    • 長度上限:2 行 (以刪節號截斷...)
  • 圖片 (選填)
    • 大小:48x48 像素

視覺化選取回應會要求您使用 TYPE_REPLACE 模式的執行階段類型,按照運算單元名稱覆寫類型。在您的 Webhook 事件處理常式中,參照 name 屬性中的運算單元名稱 (如新增選取回應所定義) 覆寫類型。

覆寫類型後,結果類型代表使用者可在該 Google 助理畫面中選擇的項目清單。

屬性

清單回應類型包含下列屬性:

屬性 類型 必要性 說明
items ListItem 的陣列 需要 代表使用者可選取清單中的項目。每個 ListItem 都包含一個鍵,可對應至清單項目參照的類型。
title 字串 選用 清單的純文字標題,僅限單行。如果沒有指定標題,資訊卡高度會收合。
subtitle 字串 選用 清單的純文字子標題。

程式碼範例

下列範例定義 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 字串 選用 集合的純文字標題。集合中的標題不得重複,才能支援語音選取功能。
subtitle 字串 選用 集合的純文字子標題。
image_fill ImageFill 選用 資訊卡和圖片容器之間的邊框,用於圖片的顯示比例與圖片容器的顯示比例不符時。

程式碼範例

下列範例定義 Webhook 程式碼或 JSON Webhook 回應中的提示內容。不過,您也可以改為在 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 字串 需要 集合項目的純文字標題。
description 字串 選用 集合項目的說明。
footer 字串 選用 產品素材資源集合項目的頁尾文字,顯示在說明下方。
image Image 選用 顯示集合項目的圖片。
openUriAction OpenUrl 需要 選取集合項目時要開啟的 URI。

程式碼範例

下列範例定義 Webhook 程式碼或 JSON Webhook 回應中的提示內容。不過,您也可以改為在 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."
      }
    }
  }
}