視覚的選択レスポンス

ビジュアル選択レスポンスは、アクションを続行するためにユーザーに複数の選択肢から 1 つを選んでもらいたい場合に使用します。プロンプトの一部として、次の画像選択レスポンス タイプを使用できます。

  • リスト
  • コレクション
  • コレクションの閲覧

ビジュアル選択レスポンスを定義する場合は、RICH_RESPONSE サーフェス機能を備えた候補を使用して、Google アシスタントがサポートされているデバイスでのみレスポンスを返すようにします。リッチ レスポンスは、プロンプト内の content オブジェクトごとに 1 つだけ使用できます。

ビジュアル選択レスポンスの追加

視覚的な選択レスポンスは、ユーザーが選択できるオプションを表示することと、選択されたアイテムを処理するために、シーンのスロットフィルを使用します。ユーザーがアイテムを選択すると、アシスタントは、選択されたアイテム値を引数として Webhook に渡します。次に、引数値で、選択したアイテムのキーを受け取ります。

視覚的選択レスポンスを使用する前に、ユーザーが後で選択するレスポンスを表すタイプを定義する必要があります。Webhook で、そのタイプを選択用に表示するコンテンツでオーバーライドします。

Actions Builder でシーンに視覚的な選択レスポンスを追加する手順は次のとおりです。

  1. シーンの [スロットフィル] セクションにスロットを追加します。
  2. ビジュアル選択レスポンスに以前に定義したタイプを選択し、名前を付けます。Webhook は、このスロット名を使用してタイプを後で参照します。
  3. [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."
      }
    }
  }
}

リスト

モバイル デバイスにおけるリスト選択のレスポンスの例

リストには、複数のアイテムが縦に並んだリストが表示されます。ユーザーは、タップまたは音声入力でアイテムを 1 つ選択できます。ユーザーがリストからアイテムを選択すると、アシスタントはリストアイテムのタイトルを含むユーザークエリ(チャットふきだし)を生成します。

リストは、オプションの曖昧さを取り除くことが重要な場合や、ユーザーがオプション全体をスキャンする必要がある場合に役立ちます。たとえば、Peter Jons と Peter Hans のどちらに話しかける必要がありますか?

リストには、2 個以上 30 個以下のリスト項目を含める必要があります。最初に表示される要素の数はユーザーのデバイスによって異なり、一般的な開始数は 10 アイテムです。

リストの作成

リストを作成する場合、プロンプトにはユーザーが選択できる各アイテムのキーのみが含まれます。Webhook では、Entry タイプに基づいて、これらのキーに対応する項目を定義します。

Entry オブジェクトとして定義されたリストアイテムには、次の表示特性があります。

  • タイトル
    • フォントとフォントサイズは固定です。
    • 最大長は 1 行です。切り捨てられた場合は省略記号(…)が付きます。
    • 重複していない必要があります(音声による選択をサポートするため)。
  • 説明(省略可)
    • フォントとフォントサイズは固定です。
    • 最大長は 2 行です。切り捨てられた場合は省略記号(…)が付きます。
  • 画像(省略可)
    • サイズ: 48x48 ピクセル

視覚的選択レスポンスでは、TYPE_REPLACE モードでランタイム タイプを使用し、スロット名でタイプをオーバーライドする必要があります。Webhook イベント ハンドラで、name プロパティのスロット名(選択レスポンスの追加で定義)でオーバーライドするタイプを参照します。

上書きされたタイプは、ユーザーがアシスタントで表示する項目のリストを表します。

プロパティ

リスト レスポンス タイプには次のプロパティがあります。

プロパティ 種類 必須 / 任意 説明
items ListItem の配列 必須 ユーザーが選択できるリスト内のアイテムを表します。各 ListItem には、リストアイテムの参照型にマッピングされるキーが含まれています。
title string 任意 リストの書式なしテキストのタイトル。1 行に限定されます。タイトルが指定されていない場合は、カードの高さが折りたたまれます。
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."
     }
   }
 }
}

コレクション

コレクションは横方向にスクロールし、ユーザーはタップまたは音声入力でアイテムを 1 つ選択できます。リストと比較すると、コレクションはタイルが大きく、より豊富なコンテンツを利用できます。コレクションを構成するタイルは、画像付きの基本的なカードに似ています。ユーザーがコレクションからアイテムを選択すると、アシスタントはアイテムのタイトルを含むユーザークエリ(チャットふきだし)を生成します。

コレクションは、さまざまなオプションがユーザーに表示される場合に適していますが、(リストではなく)それらのオプションを直接比較する必要がない場合です。通常は、コレクションよりもリストを使用することをおすすめします。リストのほうが視覚的にスキャンしやすく、音声で操作できるためです。

コレクションには 2 ~ 10 個のタイルが含まれている必要があります。ディスプレイ対応デバイスでは、ユーザーは左右にスワイプしてコレクション内のカードをスクロールしてからアイテムを選択できます。

コレクションの作成

コレクションを作成する場合、プロンプトにはユーザーが選択できる各アイテムのキーのみが含まれます。Webhook では、Entry タイプに基づいてこれらのキーに対応するアイテムを定義します。

Entry オブジェクトとして定義されたコレクション アイテムには、次のような表示特性があります。

  • 画像(省略可)
    • 画像は高さが 128 dp、幅が 232 dp として表示されます。
    • 画像のアスペクト比が画像の境界ボックスと異なる場合は、画像の上下または左右にバーが表示されます。
    • 画像リンクが壊れている場合は、代わりにプレースホルダ画像が使用されます。
  • タイトル(必須)
    • 書式なしテキスト。マークダウンはサポートされていません。基本的なカード リッチ レスポンスと同じフォーマット オプションです。
    • タイトルが指定されていない場合、カードの高さは折りたたまれます。
    • 重複していない必要があります(音声による選択をサポートするため)。
  • 説明(省略可)
    • 書式なしテキスト。マークダウンはサポートされていません。基本的なカード リッチ レスポンスと同じフォーマット オプションです。

視覚的選択レスポンスでは、TYPE_REPLACE モードでランタイム タイプを使用し、スロット名でタイプをオーバーライドする必要があります。Webhook イベント ハンドラで、name プロパティのスロット名(選択レスポンスの追加で定義)でオーバーライドするタイプを参照します。

型が上書きされると、結果として得られる型は、ユーザーがアシスタントで表示する項目のコレクションを表します。

プロパティ

コレクションのレスポンス タイプには次のプロパティがあります。

プロパティ 種類 必須 / 任意 説明
items CollectionItem の配列 必須 ユーザーが選択できるコレクション内のアイテムを表します。各 CollectionItem には、コレクション アイテムの参照型にマッピングされるキーが含まれています。
title string 任意 書式なしテキスト形式のコレクションのタイトル。音声選択をサポートするには、コレクション内でタイトルが一意である必要があります。
subtitle string 任意 コレクションの書式なしテキストのサブタイトル。
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 を参照すると定義済みの URL が開くので、ユーザーに役立つ詳細情報を提供できます。

コレクションの閲覧アイテムには次の表示特性があります。

  • 画像(省略可)
    • 画像は高さ 128 dp x 幅 232 dp に強制表示されます。
    • 画像のアスペクト比が画像の境界ボックスと一致しない場合、画像は中央に配置され、上下にバーが付きます。バーの色は、コレクションの閲覧 ImageFill プロパティによって決まります。
    • 商品画像リンクが機能しない場合は、代わりにプレースホルダ画像が使用されます。
  • タイトル(必須)
    • 書式なしテキスト。マークダウンはサポートされていません。基本的なカード リッチ レスポンスと同じ形式が使用されます。
    • タイトルが定義されていない場合、カードの高さは折りたたまれます。
  • 説明(省略可)
  • フッター(省略可)
    • 書式なしテキスト。マークダウンはサポートされていません。

プロパティ

コレクションの閲覧レスポンス タイプには次のプロパティがあります。

プロパティ 種類 必須 / 任意 説明
item オブジェクト 必須 ユーザーが選択できるコレクション内のアイテムを表します。
image_fill ImageFill 任意 画像のアスペクト比が画像コンテナのアスペクト比と一致しない場合に使用される、カードと画像コンテナの間の枠線。

コレクション閲覧 item には次のプロパティがあります。

プロパティ 種類 必須 / 任意 説明
title string 必須 コレクション アイテムの書式なしテキストのタイトル。
description string 任意 コレクション アイテムの説明。
footer string 任意 説明の下に表示されるコレクション アイテムのフッター テキスト。
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."
      }
    }
  }
}