Réponses de sélection visuelle

Utilisez une réponse de sélection visuelle si vous souhaitez que l'utilisateur sélectionne une option parmi plusieurs options pour poursuivre votre action. Vous pouvez utiliser les types de réponse de sélection visuelle suivants dans une invite:

  • Liste
  • Collection
  • Parcourir les collections

Lorsque vous définissez une réponse de sélection visuelle, utilisez un candidat avec la fonctionnalité de surface RICH_RESPONSE afin que l'Assistant Google ne renvoie la réponse que sur les appareils compatibles. Vous ne pouvez utiliser qu'une seule réponse enrichie par objet content dans une requête.

Ajouter une réponse de sélection visuelle

Les réponses de sélection visuelle utilisent le remplissage d'emplacements dans une scène pour présenter les options qu'un utilisateur peut sélectionner et pour gérer un élément sélectionné. Lorsque les utilisateurs sélectionnent un élément, l'Assistant transmet la valeur de l'élément sélectionné à votre webhook en tant qu'argument. Ensuite, dans la valeur de l'argument, vous recevez la clé de l'élément sélectionné.

Avant de pouvoir utiliser une réponse de sélection visuelle, vous devez définir un type qui représente la réponse qu'un utilisateur sélectionnera par la suite. Dans votre webhook, remplacez ce type par le contenu que vous souhaitez afficher.

Pour ajouter une réponse de sélection visuelle à une scène dans Actions Builder, procédez comme suit:

  1. Dans la scène, ajoutez une fente à la section Remplissage d'emplacements.
  2. Sélectionnez un type précédemment défini pour votre réponse de sélection visuelle et attribuez-lui un nom. Votre webhook utilisera ce nom d'emplacement pour référencer le type ultérieurement.
  3. Cochez la case Call your webhook (Appeler votre webhook) et indiquez le nom du gestionnaire d'événements de votre webhook que vous souhaitez utiliser pour la réponse de sélection visuelle.
  4. Cochez l'option Send invites (Envoyer des invites).
  5. Dans l'invite, fournissez le contenu JSON ou YAML approprié en fonction de la réponse de sélection visuelle que vous souhaitez renvoyer.
  6. Dans votre webhook, suivez les étapes décrites dans Gérer les éléments sélectionnés.

Consultez les sections Liste, Collecte et Parcourir les collections ci-dessous pour connaître les propriétés de requête disponibles et obtenir des exemples de remplacement des types.

Traiter les éléments sélectionnés

Les réponses de sélection visuelle nécessitent que vous gériez la sélection d'un utilisateur dans le code de votre webhook. Lorsque l'utilisateur sélectionne un élément dans une réponse de sélection visuelle, l'Assistant Google remplit l'emplacement avec cette valeur.

Dans l'exemple suivant, le code de webhook reçoit et stocke l'option sélectionnée dans une variable:

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."
      }
    }
  }
}

Liste

Exemple de réponse de sélection de liste sur un appareil mobile

Une liste présente aux utilisateurs une liste verticale de plusieurs éléments et leur permet d'en sélectionner un par commande tactile ou vocale. Lorsqu'un utilisateur sélectionne un élément dans la liste, l'Assistant génère une requête utilisateur (bulle de chat) contenant le titre de cet élément.

Les listes sont utiles lorsqu'il est important de faire la distinction entre différentes options ou lorsque l'utilisateur doit choisir entre les options à analyser dans leur intégralité. Par exemple, à quel "Pierre" devez-vous parler, Peter Jons ou Peter Hans ?

Les listes doivent contenir entre 2 et 30 éléments. Le nombre d'éléments affichés initialement dépend de l'appareil de l'utilisateur. Le nombre de départ est de 10 éléments.

Créer une liste

Lorsque vous créez une liste, votre invite ne contient que des clés pour chaque élément qu'un utilisateur peut sélectionner. Dans votre webhook, vous définissez les éléments qui correspondent à ces clés en fonction du type Entry.

Les éléments de liste définis en tant qu'objets Entry présentent les caractéristiques d'affichage suivantes:

  • Titre
    • Police et taille de police fixes
    • Longueur maximale: 1 ligne (tronquée par des points de suspension, etc.)
    • Obligatoire pour être unique (pour permettre la sélection vocale)
  • Description (facultatif)
    • Police et taille de police fixes
    • Longueur maximale: 2 lignes (tronquées par des points de suspension, etc.)
  • Image (facultatif)
    • Taille: 48 x 48 px

Les réponses de sélection visuelle vous obligent à remplacer un type par son nom d'emplacement à l'aide d'un type d'exécution en mode TYPE_REPLACE. Dans votre gestionnaire d'événements de webhook, référencez le type à remplacer par son nom d'emplacement (défini dans la section Ajouter des réponses de sélection) dans la propriété name.

Une fois qu'un type est écrasé, le type obtenu représente la liste des éléments que l'utilisateur peut choisir sur les écrans de l'Assistant.

Propriétés

Le type de réponse "Liste" possède les propriétés suivantes:

Propriété Type Obligatoire ? Description
items tableau de ListItem Obligatoire Représente un élément de la liste que les utilisateurs peuvent sélectionner. Chaque ListItem contient une clé mappée à un type référencé pour l'élément de liste.
title chaîne Facultatif Titre en texte brut de la liste, limité à une seule ligne. Si aucun titre n'est spécifié, la hauteur de la fiche est réduite.
subtitle chaîne Facultatif Sous-titre en texte brut de la liste.

Exemple de code

Les exemples suivants définissent le contenu de l'invite dans le code de webhook ou dans la réponse JSON webhookResponse. Toutefois, vous pouvez également définir le contenu de la requête dans Actions Builder (au format YAML ou 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."
     }
   }
 }
}

Collection

Une collection défile horizontalement et permet aux utilisateurs de sélectionner un élément par commande tactile ou vocale. Par rapport aux listes, les collections comportent de grandes tuiles et permettent d'enrichir le contenu. Les tuiles qui composent une collection sont semblables à la fiche de base avec image. Lorsque les utilisateurs sélectionnent un élément dans une collection, l'Assistant génère une requête utilisateur (bulle de chat) contenant le titre de l'élément.

Les collections sont utiles lorsque diverses options sont présentées à l'utilisateur, mais qu'aucune comparaison directe n'est requise entre elles (par rapport aux listes). En général, privilégiez les listes aux collections, car les listes sont plus faciles à analyser visuellement et à interagir par commande vocale.

Les collections doivent contenir entre 2 et 10 vignettes. Sur les appareils compatibles d'affichage, les utilisateurs peuvent balayer l'écran vers la gauche ou vers la droite pour faire défiler les cartes d'une collection avant de sélectionner un élément.

Créer une collection

Lorsque vous créez une collection, votre invite ne contient que des clés pour chaque élément qu'un utilisateur peut sélectionner. Dans votre webhook, vous définissez les éléments qui correspondent à ces clés en fonction du type Entry.

Les éléments de collection définis en tant qu'objets Entry présentent les caractéristiques d'affichage suivantes:

  • Image (facultatif)
    • La hauteur de l'image est de 128 dp x 232 dp de large.
    • Si le format de l'image ne correspond pas au cadre de délimitation de l'image, l'image est centrée avec des barres de chaque côté.
    • Si un lien image ne fonctionne pas, un espace réservé est utilisé à la place.
  • Titre (obligatoire)
    • Le format texte brut, Markdown n'est pas pris en charge. Mêmes options de mise en forme que la réponse enrichie de la fiche de base
    • La hauteur de la fiche est réduite si aucun titre n'est spécifié.
    • Obligatoire pour être unique (pour permettre la sélection vocale)
  • Description (facultatif)
    • Le format texte brut, Markdown n'est pas pris en charge. Mêmes options de mise en forme que la réponse enrichie de la fiche de base

Les réponses de sélection visuelle vous obligent à remplacer un type par son nom d'emplacement à l'aide d'un type d'exécution en mode TYPE_REPLACE. Dans votre gestionnaire d'événements de webhook, référencez le type à remplacer par son nom d'emplacement (défini dans la section Ajouter des réponses de sélection) dans la propriété name.

Une fois qu'un type est écrasé, le type obtenu représente la collection d'éléments que l'utilisateur peut choisir sur ces écrans de l'Assistant.

Propriétés

Le type de réponse de collection possède les propriétés suivantes:

Propriété Type Obligatoire ? Description
items tableau de CollectionItem Obligatoire Représente un élément de la collection que les utilisateurs peuvent sélectionner. Chaque CollectionItem contient une clé mappée à un type référencé pour l'élément de collection.
title chaîne Facultatif Titre en texte brut de la collection. Pour permettre la sélection vocale, les titres doivent être uniques dans une collection.
subtitle chaîne Facultatif Sous-titre en texte brut de la collection.
image_fill ImageFill Facultatif Bordure entre la carte et le conteneur d'image à utiliser lorsque le format de l'image ne correspond pas à celui du conteneur d'image.

Exemple de code

Les exemples suivants définissent le contenu de l'invite dans le code de webhook ou dans la réponse du webhook JSON. Toutefois, vous pouvez également définir le contenu de la requête dans Actions Builder (au format YAML ou 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."
      }
    }
  }
}

Parcourir les collections

Comme pour une collection, la navigation de collection est une réponse enrichie qui permet aux utilisateurs de faire défiler les fiches d'options. La navigation dans les collections est conçue spécifiquement pour le contenu Web et ouvre la carte sélectionnée dans un navigateur Web (ou dans un navigateur AMP si toutes les tuiles sont compatibles avec AMP).

Les réponses lors de la navigation dans les collections contiennent entre 2 et 10 vignettes. Sur les appareils compatibles d'affichage, les utilisateurs peuvent balayer l'écran vers le haut ou vers le bas pour faire défiler les cartes avant de sélectionner un élément.

Créer une navigation de collection

Lorsque vous créez une navigation dans une collection, tenez compte de la manière dont les utilisateurs vont interagir avec cette invite. Chaque item de navigation de collections ouvre son URL définie. Vous devez donc fournir des informations utiles à l'utilisateur.

Les éléments de navigation dans les collections présentent les caractéristiques d'affichage suivantes:

  • Image (facultatif)
    • La hauteur de l'image est de 128 dp x 232 dp de large.
    • Si le format de l'image ne correspond pas au cadre de délimitation de l'image, celle-ci est centrée sur les côtés avec des barres, ou en haut et en bas. La couleur des barres est déterminée par la propriété ImageFill de navigation des collections.
    • Si un lien image ne fonctionne pas, un espace réservé est utilisé à la place.
  • Titre (obligatoire)
    • Le format texte brut, Markdown n'est pas pris en charge. Le même format que celui de la réponse enrichie de fiche de base est utilisé.
    • La hauteur de la fiche est réduite si aucun titre n'est défini.
  • Description (facultatif)
  • Pied de page (facultatif)
    • Texte brut ; Markdown n'est pas pris en charge.

Propriétés

Le type de réponse "Parcourir les collections" présente les propriétés suivantes:

Propriété Type Obligatoire ? Description
item objet Obligatoire Représente un élément de la collection que les utilisateurs peuvent sélectionner.
image_fill ImageFill Facultatif Bordure entre la carte et le conteneur d'image à utiliser lorsque le format de l'image ne correspond pas à celui du conteneur de l'image.

L'outil de navigation de collections item possède les propriétés suivantes:

Propriété Type Obligatoire ? Description
title chaîne Obligatoire Titre en texte brut de l'élément de la collection.
description chaîne Facultatif Description de l'élément de la collection.
footer chaîne Facultatif Texte de pied de page de l'article de collection affiché sous la description.
image Image Facultatif Image affichée pour l'élément de collection.
openUriAction OpenUrl Obligatoire URI à ouvrir lorsque l'élément de collection est sélectionné.

Exemple de code

Les exemples suivants définissent le contenu de l'invite dans le code de webhook ou dans la réponse du webhook JSON. Toutefois, vous pouvez également définir le contenu de la requête dans Actions Builder (au format YAML ou 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."
      }
    }
  }
}