Recopila y procesa información de los usuarios de Google Chat

En esta guía, se describe cómo las apps de Google Chat pueden recopilar y procesar información de los usuarios mediante la compilación de entradas de formularios en interfaces basadas en tarjetas.

En Google Chat, los complementos aparecen para los usuarios como apps de Google Chat. Para obtener más información, consulta la descripción general de la extensión de Google Chat.

Un diálogo con una variedad de widgets diferentes.
Figura 1: Una app de chat que abre un diálogo para recopilar información de contacto.

Las apps de chat solicitan información a los usuarios para realizar acciones dentro o fuera de Chat, como las siguientes:

  • Configura la configuración. Por ejemplo, para permitir que los usuarios personalicen la configuración de notificaciones o configuren y agreguen la app de Chat a uno o más espacios.
  • Crear o actualizar información en otras aplicaciones de Google Workspace Por ejemplo, permite que los usuarios creen un evento de Calendario de Google.
  • Permite que los usuarios accedan a recursos y los actualicen en otras apps o servicios web. Por ejemplo, una app de Chat puede ayudar a los usuarios a actualizar el estado de un ticket de asistencia directamente desde un espacio de Chat.

Requisitos previos

Node.js

Un complemento de Google Workspace que funcione en Google Chat. Para compilar uno, completa la guía de inicio rápido de HTTP.

Apps Script

Un complemento de Google Workspace que funcione en Google Chat. Para compilar una, completa la guía de inicio rápido de Apps Script.

Crea formularios con tarjetas

Para recopilar información, las apps de Chat diseñan formularios y sus entradas, y los compilan en tarjetas. Para mostrar tarjetas a los usuarios, las apps de Chat pueden usar las siguientes interfaces de Chat:

  • Mensajes de chat que contienen una o más tarjetas.
  • Diálogos, que son tarjetas que se abren en una ventana nueva desde los mensajes y las páginas principales.

Las apps de Chat pueden compilar las tarjetas con los siguientes widgets:

  • Widgets de entrada de formularios que solicitan información a los usuarios De manera opcional, puedes añadir validación a los widgets de entrada de formularios para asegurarte de que los usuarios ingresen y formen la información correctamente. Las apps de chat pueden usar los siguientes widgets de entrada de formulario:

    • Entradas de texto (textInput) para texto de formato libre o sugerido.
    • Las entradas de selección (selectionInput) son elementos de la IU seleccionables, como casillas de verificación, botones de selección y menús desplegables. Los widgets de entrada de selección también pueden propagar y sugerir elementos de los datos de Google Workspace (como un espacio de chat) o una fuente de datos dinámica. Para obtener más información, consulta la siguiente sección Cómo agregar un menú de selección múltiple.

    • Selectores de fecha y hora (dateTimePicker) para entradas de fecha y hora.

  • Un widget de botón para que los usuarios puedan enviar los valores que ingresaron en la tarjeta. Después de que un usuario hace clic en el botón, la app de Chat puede procesar la información que recibe.

En el siguiente ejemplo, una tarjeta recopila información de contacto con una entrada de texto, un selector de fecha y hora, y una entrada de selección:

Para ver más ejemplos de widgets interactivos que puedes usar para recopilar información, consulta Diseña una tarjeta o un diálogo interactivo en la documentación de la API de Google Chat.

Cómo agregar un menú de selección múltiple

Para personalizar los elementos de selección o permitir que los usuarios seleccionen elementos de una fuente de datos dinámica, las apps de Chat pueden usar menús de selección múltiple, que son un tipo de widget SelectionInput. Por ejemplo, la siguiente tarjeta muestra un menú de selección múltiple en el que los usuarios pueden seleccionar de forma dinámica una lista de contactos:

Puedes propagar elementos para un menú de selección múltiple desde las siguientes fuentes de datos:

  • Datos de Google Workspace, que incluyen a los usuarios o los espacios de Chat de los que el usuario es miembro El menú solo propaga elementos de la misma organización de Google Workspace.
  • Fuentes de datos externas, como una base de datos relacional Por ejemplo, puedes usar menús de selección múltiple para ayudar a un usuario a elegir entre una lista de clientes potenciales de ventas de un sistema de administración de relaciones con clientes (CRM).

Cómo propagar elementos de una fuente de datos de Google Workspace

Para usar las fuentes de datos de Google Workspace, especifica el campo platformDataSource en el widget SelectionInput. A diferencia de otros tipos de entradas de selección, debes omitir los objetos SelectionItem, ya que estos elementos de selección se obtienen de forma dinámica de Google Workspace.

En el siguiente código, se muestra un menú de selección múltiple de usuarios de Google Workspace. Para propagar los usuarios, la entrada de selección establece commonDataSource en USER:

JSON

{
  "selectionInput": {
    "name": "contacts",
    "type": "MULTI_SELECT",
    "label": "Selected contacts",
    "multiSelectMaxSelectedItems": 5,
    "multiSelectMinQueryLength": 1,
    "platformDataSource": {
      "commonDataSource": "USER"
    }
  }
}

En el siguiente código, se muestra un menú de selección múltiple de espacios de Chat. Para propagar espacios, la entrada de selección especifica el campo hostAppDataSource. El menú de selección múltiple también establece defaultToCurrentSpace en true, lo que hace que el espacio actual sea la selección predeterminada en el menú:

JSON

{
  "selectionInput": {
    "name": "spaces",
    "type": "MULTI_SELECT",
    "label": "Selected contacts",
    "multiSelectMaxSelectedItems": 3,
    "multiSelectMinQueryLength": 1,
    "platformDataSource": {
      "hostAppDataSource": {
        "chatDataSource": {
          "spaceDataSource": {
            "defaultToCurrentSpace": true
          }
        }
      }
    }
  }
}

Cómo propagar elementos de una fuente de datos externa

Los menús de selección múltiple también pueden propagar elementos de una fuente de datos externa o de terceros. Para usar una fuente de datos externa, especificas el campo externalDataSource en el widget SelectionInput que contiene la función que consulta y muestra elementos de la fuente de datos.

Para reducir las solicitudes a una fuente de datos externa, puedes incluir elementos sugeridos que aparecen en el menú de selección múltiple antes de que los usuarios escriban en el menú. Por ejemplo, puedes propagar los contactos buscados recientemente del usuario. Para propagar los elementos sugeridos desde una fuente de datos externa, especifica objetos SelectionItem estáticos.

En el siguiente código, se muestra un menú de selección múltiple que consulta y propaga elementos desde una fuente de datos externa:

JSON

{
  "selectionInput": {
    "name": "contacts",
    "type": "MULTI_SELECT",
    "label": "Selected contacts",
    "multiSelectMaxSelectedItems": 3,
    "multiSelectMinQueryLength": 1,
    "externalDataSource": { "function": "FUNCTION" },
    // Suggested items loaded by default.
    // The list is static here but it could be dynamic.
    "items": [FUNCTION]
  }
}

Reemplaza FUNCTION por la URL HTTP o el nombre de la función de Apps Script que consulta la base de datos externa. Para ver un ejemplo completo que muestra cómo mostrar elementos sugeridos, consulta la sección Cómo sugerir elementos de selección múltiple.

Cómo recibir datos de widgets interactivos

Cada vez que los usuarios hacen clic en un botón, se activa su acción de apps de chat con información sobre la interacción. En el elemento commonEventObject de la carga útil del evento, el objeto formInputs contiene todos los valores que ingresa el usuario.

Puedes recuperar los valores del objeto commonEventObject.formInputs.WIDGET_NAME, en el que WIDGET_NAME es el campo name que especificaste para el widget. Los valores se muestran como un tipo de datos específico para el widget.

A continuación, se muestra una parte de un objeto de evento en la que un usuario ingresó valores para cada widget:

{
  "commonEventObject": { "formInputs": {
    "contactName": { "stringInputs": {
      "value": ["Kai 0"]
    }},
    "contactBirthdate": { "dateInput": {
      "msSinceEpoch": 1000425600000
    }},
    "contactType": { "stringInputs": {
      "value": ["Personal"]
    }}
  }}
}

Para recibir los datos, tu app de chat controla el objeto de evento para obtener los valores que los usuarios ingresan en los widgets. En la siguiente tabla, se muestra cómo obtener el valor de un widget de entrada de formulario determinado. Para cada widget, la tabla muestra el tipo de datos que acepta, dónde se almacena el valor en el objeto del evento y un valor de ejemplo.

Widget de entrada de formulario Tipo de datos de entrada Valor de entrada del objeto del evento Valor de ejemplo
textInput stringInputs event.commonEventObject.formInputs.contactName.stringInputs.value[0] Kai O
selectionInput stringInputs Para obtener el primer valor o el único, event.commonEventObject.formInputs.contactType.stringInputs.value[0] Personal
dateTimePicker que solo acepta fechas. dateInput event.commonEventObject.formInputs.contactBirthdate.dateInput.msSinceEpoch. 1000425600000

Después de que la app de Chat recibe datos, puede realizar cualquiera de las siguientes acciones:

  • En el caso de las tarjetas que contienen un menú de selección múltiple, propaga o sugiere elementos según lo que el usuario escriba en el menú.
  • Transfiere los datos a otra tarjeta para que el usuario pueda revisar su información o continuar con la siguiente sección del formulario.
  • Responde al usuario para confirmar que completó correctamente el formulario.

Cómo sugerir elementos de selección múltiple

Si una tarjeta contiene un menú de selección múltiple que propaga elementos de una fuente de datos externa, la app de Chat puede mostrar elementos sugeridos según lo que los usuarios escriben en el menú. Por ejemplo, si un usuario comienza a escribir Atl para un menú que propaga ciudades de Estados Unidos, tu app de chat puede sugerir automáticamente Atlanta antes de que el usuario termine de escribir. La app de Chat puede sugerir hasta 100 elementos.

Para sugerir y propagar elementos de forma dinámica en un menú de selección múltiple, el widget SelectionInput de la tarjeta debe especificar una función que consulte la fuente de datos externa. Para mostrar elementos sugeridos, la función debe hacer lo siguiente:

  1. Controla un objeto de evento, que la app de Chat recibe cuando los usuarios escriben en el menú.
  2. Desde el objeto del evento, obtén el valor que escribe el usuario, que se representa en el campo event.commonEventObject.parameters["autocomplete_widget_query"].
  3. Consulta la fuente de datos con el valor de entrada del usuario para obtener uno o más SelectionItems que se le sugerirán al usuario.
  4. Para mostrar elementos sugeridos, muestra la acción RenderActions con un objeto modifyCard.

En la siguiente muestra de código, se muestra cómo una app de chat sugiere de forma dinámica elementos en el menú de selección múltiple de una tarjeta. Cuando un usuario escribe en el menú, la función o el extremo proporcionado en el campo externalDataSource del widget consulta una fuente de datos externa y sugiere elementos que el usuario puede seleccionar.

Node.js

/**
 * Google Cloud Function that responds to events sent from a
 * Google Chat space.
 *
 * @param {Object} req Request sent from Google Chat space
 * @param {Object} res Response to send back
 */
exports.selectionInput = function selectionInput(req, res) {
  if (req.method === 'GET' || !req.body.chat) {
    return res.send('Hello! This function is meant to be used ' +
        'in a Google Chat Space.');
  }
  // Stores the Google Chat event
  const chatEvent = req.body.chat;

  // Handle user interaction with multiselect.
  if(chatEvent.widgetUpdatedPayload) {
    return res.send(queryContacts(req.body));
  }
  // Replies with a card that contains the multiselect menu.
  return res.send({ hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    cardsV2: [{
      cardId: "contactSelector",
      card: { sections:[{ widgets: [{
        selectionInput: {
          name: "contacts",
          type: "MULTI_SELECT",
          label: "Selected contacts",
          multiSelectMaxSelectedItems: 3,
          multiSelectMinQueryLength: 1,
          externalDataSource: { function: "FUNCTION_URL" },
          // Suggested items loaded by default.
          // The list is static here but it could be dynamic.
          items: [getSuggestedContact("3")]
        }
      }]}]}
    }]
  }}}}});
};

/**
* Get contact suggestions based on text typed by users.
*
* @param {Object} event the event object that contains the user's query
* @return {Object} suggestions
*/
function queryContacts(event) {
  const query = event.commonEventObject.parameters["autocomplete_widget_query"];
  return { action: { modifyOperations: [{ updateWidget: { selectionInputWidgetSuggestions: { suggestions: [
    // The list is static here but it could be dynamic.
    getSuggestedContact("1"), getSuggestedContact("2"), getSuggestedContact("3"), getSuggestedContact("4"), getSuggestedContact("5")
  // Only return items based on the query from the user.
  ].filter(e => !query || e.text.includes(query)) }}}]}};
}

/**
 * Generate a suggested contact given an ID.
 *
 * @param {String} id The ID of the contact to return.
 * @return {Object} The contact formatted as a selection item in the menu.
 */
function getSuggestedContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}

Reemplaza FUNCTION_URL por el extremo HTTP que consulta la fuente de datos externa.

Apps Script

/**
* Responds to a Message trigger in Google Chat.
*
* @param {Object} event the event object from Google Chat
* @return {Object} Response from the Chat app.
*/
function onMessage(event) {
  // Replies with a card that contains the multiselect menu.
  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    cardsV2: [{
      cardId: "contactSelector",
      card: { sections:[{ widgets: [{
        selectionInput: {
          name: "contacts",
          type: "MULTI_SELECT",
          label: "Selected contacts",
          multiSelectMaxSelectedItems: 3,
          multiSelectMinQueryLength: 1,
          externalDataSource: { function: "queryContacts" },
          // Suggested items loaded by default.
          // The list is static here but it could be dynamic.
          items: [getSuggestedContact"3")]
        }
      }]}]}
    }]
  }}}}};
}

/**
* Get contact suggestions based on text typed by users.
*
* @param {Object} event the interactive event.
* @return {Object} suggestions
*/
function queryContacts(event) {
  const query = event.commonEventObject.parameters["autocomplete_widget_query"];
  return { action: { modifyOperations: [{ updateWidget: { selectionInputWidgetSuggestions: { suggestions: [
    // The list is static here but it could be dynamic.
    getSuggestedContact("1"), getSuggestedContact("2"), getSuggestedContact("3"), getSuggestedContact("4"), getSuggestedContact("5")
  // Only return items based on the query from the user.
  ].filter(e => !query || e.text.includes(query)) }}}]}};
}

/**
* Generate a suggested contact given an ID.
*
* @param {String} id The ID of the contact to return.
* @return {Object} The contact formatted as a selection item in the menu.
*/
function getSuggestedContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}

Cómo transferir datos a otra tarjeta

Después de que un usuario envía información de una tarjeta, es posible que debas mostrarle tarjetas adicionales para realizar alguna de las siguientes acciones:

  • Crea secciones distintas para ayudar a los usuarios a completar formularios más largos.
  • Permite que los usuarios obtengan una vista previa y confirmen la información de la tarjeta inicial para que puedan revisar sus respuestas antes de enviarlas.
  • Completar de forma dinámica las partes restantes del formulario Por ejemplo, para solicitar a los usuarios que creen una cita, una app de Chat podría mostrar una tarjeta inicial que solicite el motivo de la cita y, luego, propagar otra tarjeta que proporcione los horarios disponibles según el tipo de cita.

Para transferir la entrada de datos de la tarjeta inicial, puedes compilar el widget button con actionParameters que contiene el name del widget y el valor que ingresa el usuario, como se muestra en el siguiente ejemplo:

{
  "buttonList": { "buttons": [{
    "text": "Submit",
    "onClick": { "action": {
      "function": "submitForm",
      "parameters": [
        {
          "key": "WIDGET_NAME",
          "value": "USER_INPUT_VALUE"
        },
        // Can specify multiple parameters
      ]
    }}
  }]}
}

En el que WIDGET_NAME es el name del widget y USER_INPUT_VALUE es lo que ingresa el usuario. Por ejemplo, para una entrada de texto que recopila el nombre de una persona, el nombre del widget es contactName y un valor de ejemplo es Kai O.

Cuando un usuario hace clic en el botón, tu app de Chat recibe un objeto de evento desde el que puedes recibir datos.

Cómo responder un envío de formulario

Después de recibir los datos de un mensaje o diálogo de la tarjeta, la app de Chat responde confirmando el recibo o mostrando un error.

En el siguiente ejemplo, una app de chat envía un mensaje de texto para confirmar que recibió correctamente un formulario enviado desde un mensaje de tarjeta.

Node.js

/**
 * Google Cloud Function that handles all Google Workspace Add On events for
 * the contact manager app.
 *
 * @param {Object} req Request sent from Google Chat space
 * @param {Object} res Response to send back
 */
exports.contactManager = function contactManager(req, res) {
  const chatEvent = req.body.chat;
  const chatMessage = chatEvent.messagePayload.message;

  // Handle message payloads in the event object
  if(chatEvent.messagePayload) {
    return res.send(handleMessage(chatMessage, chatEvent.user));
  // Handle button clicks on the card
  } else if(chatEvent.buttonClickedPayload) {
    switch(req.body.commonEventObject.parameters.actionName) {
        case "openDialog":
            return res.send(openDialog());
        case "openNextCard":
            return res.send(openNextCard(req.body));
        case "submitForm":
            return res.send(submitForm(req.body));
    }
  }
};

/**
 * Submits information from a dialog or card message.
 *
 * @param {Object} event the interactive event with form inputs.
 * @return {Object} a message response that posts a private message.
 */
function submitForm(event) {
  const chatUser = event.chat.user;
  const contactName = event.commonEventObject.parameters["contactName"];

  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    privateMessageViewer: chatUser,
    text: "✅ " + contactName + " has been added to your contacts."
  }}}}};
}

Apps Script

/**
 * Sends private text message that confirms submission.
 *
 * @param {Object} event the interactive event with form inputs.
 * @return {Object} a message response that posts a private message.
 */
function submitForm(event) {
  const chatUser = event.chat.user;
  const contactName = event.commonEventObject.parameters["contactName"];

  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    privateMessageViewer: chatUser,
    text: "✅ " + contactName + " has been added to your contacts."
  }}}}};
}

Para procesar y cerrar un diálogo, devuelves un objeto RenderActions que especifica si deseas enviar un mensaje de confirmación, actualizar el mensaje o la tarjeta originales, o simplemente cerrar el diálogo. Para conocer los pasos, consulta Cómo cerrar un diálogo.

Solucionar problemas

Cuando una app de Google Chat o una tarjeta muestran un error, la interfaz de Chat muestra un mensaje que dice "Se produjo un error". o "No se puede procesar tu solicitud". A veces, la IU de Chat no muestra ningún mensaje de error, pero la app o la tarjeta de Chat producen un resultado inesperado. Por ejemplo, es posible que no aparezca un mensaje de la tarjeta.

Aunque es posible que no se muestre un mensaje de error en la IU de Chat, los mensajes de error descriptivos y los datos de registro están disponibles para ayudarte a corregir errores cuando se activa el registro de errores de las apps de Chat. Si necesitas ayuda para ver, depurar y corregir errores, consulta Cómo solucionar problemas y corregir errores de Google Chat.