Respuestas de selección visual

Usa una respuesta de selección visual si quieres que el usuario seleccione una entre varias opciones para continuar con tu acción. Puedes usar los siguientes tipos de respuesta de selección visual como parte de una instrucción:

  • Ir a la lista
  • Colección
  • Exploración de colecciones

Cuando definas una respuesta de selección visual, usa un candidato con la capacidad de superficie RICH_RESPONSE para que Asistente de Google solo muestre la respuesta en dispositivos compatibles. Solo puedes usar una respuesta enriquecida por objeto content en un mensaje.

Cómo agregar una respuesta de selección visual

En las respuestas de selección visual, se usa el relleno de espacios para presentar opciones que un usuario puede seleccionar y controlar un elemento seleccionado. Cuando los usuarios seleccionan un elemento, Asistente pasa el valor del elemento seleccionado a tu webhook como argumento. Luego, en el valor del argumento, recibes la clave del elemento seleccionado.

Antes de poder usar una respuesta de selección visual, debes definir un tipo que represente la respuesta que un usuario selecciona más adelante. En tu webhook, anulas ese tipo con el contenido que deseas mostrar para la selección.

Para agregar una respuesta de selección visual a una escena en Actions Builder, sigue estos pasos:

  1. En la escena, agrega una ranura a la sección Slot fill.
  2. Selecciona un tipo definido previamente para tu respuesta de selección visual y asígnale un nombre. Tu webhook usa este nombre de ranura para hacer referencia al tipo más adelante.
  3. Marca la casilla Llama a tu webhook y proporciona el nombre del controlador del evento en tu webhook que deseas usar para la respuesta de selección visual.
  4. Marca la casilla Send prompts.
  5. En el mensaje, proporciona el contenido JSON o YAML adecuado según la respuesta de selección visual que deseas mostrar.
  6. En tu webhook, sigue los pasos que se indican en Cómo manejar los elementos seleccionados.

Consulta las secciones de lista, colección y exploración de colecciones a continuación para conocer las propiedades disponibles del mensaje y los ejemplos de cómo anular tipos.

Controla los elementos seleccionados

Las respuestas de selección visual requieren que controles la selección de un usuario en tu código de webhook. Cuando el usuario selecciona algo de una respuesta de selección visual, Asistente de Google llena el espacio con ese valor.

En el siguiente ejemplo, el código de webhook recibe y almacena la opción seleccionada en una 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."
      }
    }
  }
}

Ir a la lista

Ejemplo de una respuesta de selección de lista en un dispositivo móvil

Una lista presenta a los usuarios una lista vertical de varios elementos y les permite seleccionar uno mediante entrada táctil o de voz. Cuando un usuario selecciona un elemento de la lista, Asistente genera una consulta del usuario (burbuja de chat) que contiene el título del elemento de la lista.

Las listas son útiles cuando es importante desambiguar opciones o cuando el usuario debe elegir entre opciones que se deben analizar por completo. Por ejemplo, ¿con qué “Peter” necesitas hablar, Peter Jons o Peter Hans?

Las listas deben contener un mínimo de 2 y un máximo de 30 elementos. La cantidad de elementos que se muestran inicialmente depende del dispositivo del usuario, y el número de inicio común es de 10 elementos.

Cómo crear una lista

Cuando creas una lista, tu mensaje solo contiene claves para cada elemento que un usuario puede seleccionar. En tu webhook, defines los elementos que corresponden a esas claves según el tipo Entry.

Los elementos de lista definidos como objetos Entry tienen las siguientes características de visualización:

  • Título
    • Fuente y tamaño de fuente fijos
    • Longitud máxima: 1 línea (truncada con puntos suspensivos...)
    • Debe ser único (para admitir la selección de voz)
  • Descripción (opcional)
    • Fuente y tamaño de fuente fijos
    • Longitud máxima: 2 líneas (truncadas con puntos suspensivos...)
  • Imagen (opcional)
    • Tamaño: 48 x 48 px

Las respuestas de selección visual requieren que anules un tipo por su nombre de ranura mediante un tipo de entorno de ejecución en el modo TYPE_REPLACE. En el controlador de eventos de webhook, haz referencia al tipo que se anulará por su nombre de ranura (definido en Agrega respuestas de selección) en la propiedad name.

Una vez que se reemplaza un tipo, el tipo resultante representa la lista de elementos que el usuario puede elegir de las pantallas de Asistente.

Propiedades

El tipo de respuesta de lista tiene las siguientes propiedades:

Propiedad Tipo Requisito Descripción
items array de ListItem Obligatorias Representa un elemento de la lista que los usuarios pueden seleccionar. Cada ListItem contiene una clave que se asigna a un tipo al que se hace referencia para el elemento de lista.
title cadena Opcional Título con texto sin formato de la lista, restringido a una sola línea. Si no se especifica un título, la altura de la tarjeta se contrae.
subtitle cadena Opcional Subtítulo de texto sin formato de la lista.

Código de muestra

En las siguientes muestras, se define el contenido del mensaje en el código de webhook o en la webhookResponse de JSON. Sin embargo, también puedes definir el contenido del mensaje en Actions Builder (como YAML o 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."
     }
   }
 }
}

Colección

Una colección se desplaza horizontalmente y permite a los usuarios seleccionar un elemento mediante entrada táctil o de voz. En comparación con las listas, las colecciones tienen mosaicos grandes y permiten un contenido más completo. Las tarjetas que conforman una colección son similares a la tarjeta básica con imagen. Cuando los usuarios seleccionan un elemento de una colección, Asistente genera una consulta (burbuja de chat) que contiene el título del elemento.

Las colecciones son buenas cuando se presentan varias opciones al usuario, pero no se requiere una comparación directa entre ellas (en comparación con las listas). En general, es preferible usar listas antes que las colecciones, ya que es más fácil escanearlas visualmente y, además, interactuar con ellas por voz.

Las colecciones deben contener un mínimo de 2 y un máximo de 10. En dispositivos con pantallas, los usuarios pueden deslizar el dedo hacia la izquierda o la derecha para desplazarse por las tarjetas de una colección antes de seleccionar un elemento.

Cómo crear una colección

Cuando creas una colección, el mensaje solo contiene claves para cada elemento que el usuario puede seleccionar. En tu webhook, defines los elementos que corresponden a esas claves según el tipo Entry.

Los elementos de colección definidos como objetos Entry tienen las siguientes características de visualización:

  • Imagen (opcional)
    • La imagen debe tener 128 dp de alto x 232 dp de ancho
    • Si la relación de aspecto de la imagen no coincide con el cuadro de límite de la imagen, se centrará con barras a ambos lados.
    • Si el vínculo de una imagen se rompe, se usa una imagen de marcador de posición en su lugar.
  • Título (obligatorio)
    • Texto sin formato; Markdown no es compatible. Las mismas opciones de formato que la respuesta enriquecida de tarjeta básica
    • La altura de la tarjeta se contrae si no se especifica un título.
    • Debe ser único (para admitir la selección de voz)
  • Descripción (opcional)
    • Texto sin formato; Markdown no es compatible. Las mismas opciones de formato que la respuesta enriquecida de tarjeta básica

Las respuestas de selección visual requieren que anules un tipo por su nombre de ranura mediante un tipo de entorno de ejecución en el modo TYPE_REPLACE. En el controlador de eventos de webhook, haz referencia al tipo que se anulará por su nombre de ranura (definido en Agrega respuestas de selección) en la propiedad name.

Después de reemplazar un tipo, el tipo resultante representa la colección de elementos que el usuario puede elegir de las pantallas de Asistente.

Propiedades

El tipo de respuesta de colección tiene las siguientes propiedades:

Propiedad Tipo Requisito Descripción
items array de CollectionItem Obligatorias Representa un elemento de la colección que los usuarios pueden seleccionar. Cada CollectionItem contiene una clave que se asigna a un tipo al que se hace referencia para el elemento de colección.
title cadena Opcional Título de la colección con texto sin formato. Los títulos deben ser únicos en una colección para admitir la selección de voz.
subtitle cadena Opcional Subtítulo de texto sin formato de la colección.
image_fill ImageFill Opcional Borde entre la tarjeta y el contenedor de imagen que se usará cuando la relación de aspecto de la imagen no coincida con la del contenedor.

Código de muestra

En las siguientes muestras, se define el contenido del mensaje en el código de webhook o en la respuesta de webhook de JSON. Sin embargo, también puedes definir el contenido del mensaje en Actions Builder (como YAML o 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."
      }
    }
  }
}

Exploración de colecciones

Al igual que una colección, la navegación de colecciones es una respuesta enriquecida que permite a los usuarios desplazarse por las tarjetas de opciones. La exploración de colecciones está diseñada específicamente para contenido web y abre el mosaico seleccionado en un navegador web (o un navegador de AMP si todas las tarjetas son compatibles con AMP).

Las respuestas de la exploración de colecciones contienen un mínimo de 2 y un máximo de 10 mosaicos. En dispositivos con pantallas, los usuarios pueden deslizar el dedo hacia arriba o hacia abajo para desplazarse por las tarjetas antes de seleccionar un elemento.

Cómo crear una exploración de colecciones

Cuando crees un navegador de colecciones, ten en cuenta cómo interactuarán los usuarios con este mensaje. Cada navegación de colección item abre su URL definida, por lo que debes proporcionar detalles útiles al usuario.

Los elementos de navegación de colecciones tienen las siguientes características de visualización:

  • Imagen (opcional)
    • La imagen se fuerza a 128 dp de alto x 232 dp de ancho.
    • Si la relación de aspecto de la imagen no coincide con el cuadro de límite de la imagen, esta se centrará con barras laterales o en la parte inferior y superior. El color de las barras lo determina la propiedad ImageFill de la navegación de colecciones.
    • Si el vínculo de una imagen se rompe, se usa una imagen de marcador de posición.
  • Título (obligatorio)
  • Descripción (opcional)
  • Pie de página (opcional)
    • Texto sin formato; Markdown no es compatible.

Propiedades

El tipo de respuesta de exploración de colecciones tiene las siguientes propiedades:

Propiedad Tipo Requisito Descripción
item objeto Obligatorias Representa un elemento de la colección que los usuarios pueden seleccionar.
image_fill ImageFill Opcional Borde entre la tarjeta y el contenedor de la imagen que se usará cuando la relación de aspecto de la imagen no coincida con la del contenedor.

La exploración de colecciones item tiene las siguientes propiedades:

Propiedad Tipo Requisito Descripción
title cadena Obligatorias Título con texto sin formato del elemento de la colección.
description cadena Opcional Es la descripción del elemento de la colección.
footer cadena Opcional Es el texto del pie de página del elemento de la colección, que aparece debajo de la descripción.
image Image Opcional Se muestra la imagen del elemento de la colección.
openUriAction OpenUrl Obligatorias Es el URI que se debe abrir cuando se selecciona el elemento de la colección.

Código de muestra

En las siguientes muestras, se define el contenido del mensaje en el código de webhook o en la respuesta de webhook de JSON. Sin embargo, también puedes definir el contenido del mensaje en Actions Builder (como YAML o 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."
      }
    }
  }
}