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.

Un diálogo con una variedad de widgets diferentes.
Figura 1: Una app de chat de muestra 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:

  • Define 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 y actualicen los recursos de 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

Una app de Google Chat habilitada para funciones interactivas. Para crear una app de Chat interactiva con un servicio HTTP, completa esta guía de inicio rápido.

Python

Una app de Google Chat habilitada para funciones interactivas. Si quieres crear una app de chat interactiva con un servicio HTTP, completa esta guía de inicio rápido.

Java

Una app de Google Chat habilitada para funciones interactivas Si quieres crear una app de chat interactiva con un servicio HTTP, completa esta guía de inicio rápido.

Apps Script

Una app de Google Chat habilitada para funciones interactivas Para crear una app de Chat interactiva en Apps Script, completa esta guía de inicio rápido.

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 que contienen una o más tarjetas
  • Páginas principales: Es una tarjeta que aparece en la pestaña Página principal en los mensajes directos de la app de Chat.
  • Diálogos, que son tarjetas que se abren en una ventana nueva desde mensajes y páginas principales.

Las apps de Chat pueden compilar 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 elementos de fuentes de datos estáticas o dinámicas. Por ejemplo, los usuarios pueden seleccionar de una lista de espacios de Chat de los que son miembros.
    • 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 mediante una entrada de texto, un selector de fecha y hora, y un widget de entrada de selección:

Node.js

node/contact-form-app/index.js
/**
 * The section of the contact card that contains the form input widgets. Used in a dialog and card message.
 * To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
 */
const CONTACT_FORM_WIDGETS = [
  {
    "textInput": {
      "name": "contactName",
      "label": "First and last name",
      "type": "SINGLE_LINE"
    }
  },
  {
    "dateTimePicker": {
      "name": "contactBirthdate",
      "label": "Birthdate",
      "type": "DATE_ONLY"
    }
  },
  {
    "selectionInput": {
      "name": "contactType",
      "label": "Contact type",
      "type": "RADIO_BUTTON",
      "items": [
        {
          "text": "Work",
          "value": "Work",
          "selected": false
        },
        {
          "text": "Personal",
          "value": "Personal",
          "selected": false
        }
      ]
    }
  }
];

Python

python/contact-form-app/main.py
# The section of the contact card that contains the form input widgets. Used in a dialog and card message.
# To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
CONTACT_FORM_WIDGETS = [
  {
    "textInput": {
      "name": "contactName",
      "label": "First and last name",
      "type": "SINGLE_LINE"
    }
  },
  {
    "dateTimePicker": {
      "name": "contactBirthdate",
      "label": "Birthdate",
      "type": "DATE_ONLY"
    }
  },
  {
    "selectionInput": {
      "name": "contactType",
      "label": "Contact type",
      "type": "RADIO_BUTTON",
      "items": [
        {
          "text": "Work",
          "value": "Work",
          "selected": False
        },
        {
          "text": "Personal",
          "value": "Personal",
          "selected": False
        }
      ]
    }
  }
]

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
// The section of the contact card that contains the form input widgets. Used in a dialog and card message.
// To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
final static private List<GoogleAppsCardV1Widget> CONTACT_FORM_WIDGETS = List.of(
  new GoogleAppsCardV1Widget().setTextInput(new GoogleAppsCardV1TextInput()
    .setName("contactName")
    .setLabel("First and last name")
    .setType("SINGLE_LINE")),
  new GoogleAppsCardV1Widget().setDateTimePicker(new GoogleAppsCardV1DateTimePicker()
    .setName("contactBirthdate")
    .setLabel("Birthdate")
    .setType("DATE_ONLY")),
  new GoogleAppsCardV1Widget().setSelectionInput(new GoogleAppsCardV1SelectionInput()
    .setName("contactType")
    .setLabel("Contact type")
    .setType("RADIO_BUTTON")
    .setItems(List.of(
      new GoogleAppsCardV1SelectionItem()
        .setText("Work")
        .setValue("Work")
        .setSelected(false),
      new GoogleAppsCardV1SelectionItem()
        .setText("Personal")
        .setValue("Personal")
        .setSelected(false)))));

Apps Script

apps-script/contact-form-app/contactForm.gs
/**
 * The section of the contact card that contains the form input widgets. Used in a dialog and card message.
 * To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
 */
const CONTACT_FORM_WIDGETS = [
  {
    "textInput": {
      "name": "contactName",
      "label": "First and last name",
      "type": "SINGLE_LINE"
    }
  },
  {
    "dateTimePicker": {
      "name": "contactBirthdate",
      "label": "Birthdate",
      "type": "DATE_ONLY"
    }
  },
  {
    "selectionInput": {
      "name": "contactType",
      "label": "Contact type",
      "type": "RADIO_BUTTON",
      "items": [
        {
          "text": "Work",
          "value": "Work",
          "selected": false
        },
        {
          "text": "Personal",
          "value": "Personal",
          "selected": false
        }
      ]
    }
  }
];

Para ver más ejemplos de widgets interactivos que puedes usar para recopilar información, consulta Cómo diseñar una tarjeta o un diálogo interactivo.

Cómo recibir datos de widgets interactivos

Cuando los usuarios hacen clic en un botón, las apps de Chat reciben un evento de interacción CARD_CLICKED que contiene información sobre la interacción. La carga útil de los eventos de interacción CARD_CLICKED contiene un objeto common.formInputs con los valores que ingresa el usuario.

Puedes recuperar los valores del objeto common.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 (representado como un objeto Inputs).

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

HTTP

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

Apps Script

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

Para recibir los datos, tu app de Chat controla el evento de interacción 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, en qué lugar se almacena el valor en el evento de interacción y un valor de ejemplo.

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

Cómo transferir datos a otra tarjeta

Después de que un usuario envía información desde una tarjeta, es posible que debas devolver 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.
  • Propagar 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 desde 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:

Node.js

node/contact-form-app/index.js
buttonList: { buttons: [{
  text: "Submit",
  onClick: { action: {
    function: "submitForm",
    parameters: [{
      key: "contactName", value: name }, {
      key: "contactBirthdate", value: birthdate }, {
      key: "contactType", value: type
    }]
  }}
}]}

Python

python/contact-form-app/main.py
'buttonList': { 'buttons': [{
  'text': "Submit",
  'onClick': { 'action': {
    'function': "submitForm",
    'parameters': [{
      'key': "contactName", 'value': name }, {
      'key': "contactBirthdate", 'value': birthdate }, {
      'key': "contactType", 'value': type
    }]
  }}
}]}

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
new GoogleAppsCardV1Widget().setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(new GoogleAppsCardV1Button()
  .setText("Submit")
  .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
    .setFunction("submitForm")
    .setParameters(List.of(
      new GoogleAppsCardV1ActionParameter().setKey("contactName").setValue(name),
      new GoogleAppsCardV1ActionParameter().setKey("contactBirthdate").setValue(birthdate),
      new GoogleAppsCardV1ActionParameter().setKey("contactType").setValue(type))))))))));

Apps Script

apps-script/contact-form-app/main.gs
buttonList: { buttons: [{
  text: "Submit",
  onClick: { action: {
    function: "submitForm",
    parameters: [{
      key: "contactName", value: name }, {
      key: "contactBirthdate", value: birthdate }, {
      key: "contactType", value: type
    }]
  }}
}]}

Cuando un usuario hace clic en el botón, la app de Chat recibe un evento de interacción CARD_CLICKED 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 diálogo o tarjeta.

Node.js

node/contact-form-app/index.js
const contactName = event.common.parameters["contactName"];
// Checks to make sure the user entered a contact name.
// If no name value detected, returns an error message.
if (!contactName) {
  const errorMessage = "Don't forget to name your new contact!";
  if (event.dialogEventType === "SUBMIT_DIALOG") {
    return { actionResponse: {
      type: "DIALOG",
      dialogAction: { actionStatus: {
        statusCode: "INVALID_ARGUMENT",
        userFacingMessage: errorMessage
      }}
    }};
  } else {
    return {
      privateMessageViewer: event.user,
      text: errorMessage
    };
  }
}

Python

python/contact-form-app/main.py
contact_name = event.get('common').get('parameters')["contactName"]
# Checks to make sure the user entered a contact name.
# If no name value detected, returns an error message.
if contact_name == "":
  error_message = "Don't forget to name your new contact!"
  if "SUBMIT_DIALOG" == event.get('dialogEventType'):
    return { 'actionResponse': {
      'type': "DIALOG",
      'dialogAction': { 'actionStatus': {
        'statusCode': "INVALID_ARGUMENT",
        'userFacingMessage': error_message
      }}
    }}
  else:
    return {
      'privateMessageViewer': event.get('user'),
      'text': error_message
    }

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
String contactName = event.at("/common/parameters/contactName").asText();
// Checks to make sure the user entered a contact name.
// If no name value detected, returns an error message.
if (contactName.isEmpty()) {
  String errorMessage = "Don't forget to name your new contact!";
  if (event.at("/dialogEventType") != null && "SUBMIT_DIALOG".equals(event.at("/dialogEventType").asText())) {
    return new Message().setActionResponse(new ActionResponse()
      .setType("DIALOG")
      .setDialogAction(new DialogAction().setActionStatus(new ActionStatus()
        .setStatusCode("INVALID_ARGUMENT")
        .setUserFacingMessage(errorMessage))));
  } else {
    return new Message()
      .setPrivateMessageViewer(new User().setName(event.at("/user/name").asText()))
      .setText(errorMessage);
  }
}

Apps Script

apps-script/contact-form-app/main.gs
const contactName = event.common.parameters["contactName"];
// Checks to make sure the user entered a contact name.
// If no name value detected, returns an error message.
if (!contactName) {
  const errorMessage = "Don't forget to name your new contact!";
  if (event.dialogEventType === "SUBMIT_DIALOG") {
    return { actionResponse: {
      type: "DIALOG",
      dialogAction: { actionStatus: {
        statusCode: "INVALID_ARGUMENT",
        userFacingMessage: errorMessage
      }}
    }};
  } else {
    return {
      privateMessageViewer: event.user,
      text: errorMessage
    };
  }
}

Para procesar y cerrar un diálogo, devuelves un objeto ActionResponse 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 o una tarjeta de Google Chat muestran un error, la interfaz de Chat muestra el mensaje “Se produjo un error”. o "No se pudo procesar la 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, puede que no aparezca un mensaje de tarjeta.

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