Abrir diálogos interactivos

En esta página, se describe cómo una app de Google Chat puede abrir diálogos para mostrar interfaces de usuario (IU) y responder a los usuarios.

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.

Los diálogos son interfaces con ventanas y basadas en tarjetas que se abren desde un espacio o mensaje de Chat. El diálogo y su contenido solo son visibles para el usuario que lo abrió.

Las apps de chat pueden usar diálogos para solicitar y recopilar información de los usuarios de Chat, incluidos los formularios de varios pasos. Para obtener más detalles sobre la creación de entradas de formularios, consulta Cómo recopilar y procesar información de los usuarios.

Requisitos previos

Node.js

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

Apps Script

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

Cómo abrir un diálogo

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.

En esta sección, se explica cómo responder y configurar un diálogo de la siguiente manera:

  1. Activa la solicitud de diálogo a partir de una interacción del usuario.
  2. Para controlar la solicitud, muestra un diálogo y devuélvelo.
  3. Después de que los usuarios envíen información, cierra el diálogo o muestra otro para procesar el envío.

Cómo activar una solicitud de diálogo

Una app de chat solo puede abrir diálogos para responder a una interacción del usuario, como un comando de barra o un clic en un botón de un mensaje en una tarjeta.

Para responder a los usuarios con un diálogo, una app de Chat debe compilar una interacción que active la solicitud de diálogo, como la siguiente:

  • Responde a un comando de barra. Para activar la solicitud desde un comando de barra, debes marcar la casilla de verificación Abre un diálogo cuando configures el comando.
  • Responde a un clic en un botón en un mensaje, ya sea como parte de una tarjeta o en la parte inferior del mensaje. Para activar la solicitud desde un botón en un mensaje, configura la acción onClick del botón estableciendo su interaction en OPEN_DIALOG.
Botón que activa un diálogo
Figura 2: Una app de Chat envía un mensaje que les solicita a los usuarios que usen el comando de barra /addContact.
El mensaje también incluye un botón en el que los usuarios pueden hacer clic para activar el comando.

En el siguiente JSON, se muestra cómo activar una solicitud de diálogo desde un botón en un mensaje de tarjeta. Para abrir el diálogo, configura el campo onClick.action.interaction del botón como OPEN_DIALOG:

{
  "buttonList": { "buttons": [{
    "text": "BUTTON_TEXT",
    "onClick": { "action": {
      "function": "ACTION_FUNCTION",
      "interaction": "OPEN_DIALOG"
    }}
  }]}
}

Donde BUTTON_TEXT es el texto que se muestra en el botón y ACTION_FUNCTION es la función que se ejecuta para abrir el diálogo inicial.

Abre el diálogo inicial

Cuando un usuario activa una solicitud de diálogo, tu app de chat recibe un objeto de evento con una carga útil que especifica que un objeto dialogEventType es REQUEST_DIALOG.

Para abrir un diálogo, tu app de Chat puede responder a la solicitud devolviendo un objeto RenderActions con el elemento de navegación pushCard para mostrar una tarjeta. La tarjeta debe contener cualquier elemento de interfaz de usuario (IU), incluido uno o más sections[] de widgets. Para recopilar información de los usuarios, puedes especificar widgets de entrada de formularios y un widget de botón. Para obtener más información sobre el diseño de entradas de formularios, consulta Cómo recopilar y procesar información de los usuarios.

En el siguiente JSON, se muestra cómo una app de Chat muestra una respuesta que abre un diálogo:

{
  "action": { "navigations": [{ "pushCard": { "sections": [{ "widgets": [{
    WIDGETS,
    { "buttonList": { "buttons": [{
      "text": "BUTTON_TEXT",
      "onClick": {
        "action": { "function": "ACTION_FUNCTION" }
      }
    }]}}
  }]}]}}]}
}

En la que BUTTON_TEXT es el texto que se muestra en el botón (como Next o Submit), WIDGETS representa uno o más widgets de entrada de formulario y ACTION_FUNCTION es la función de devolución de llamada de la acción que se ejecuta cuando los usuarios hacen clic en un botón.

Controla el envío del diálogo

Cuando los usuarios hacen clic en un botón que envía un diálogo, tu app de chat recibe un objeto de evento con un objeto ButtonClickedPayload. En la carga útil, dialogEventType se establece en SUBMIT_DIALOG.

Tu app de Chat debe controlar el objeto del evento haciendo una de las siguientes acciones:

Opcional: Muestra otro diálogo

Después de que los usuarios envían el diálogo inicial, las apps de Chat pueden mostrar uno o más diálogos adicionales para ayudarlos a revisar la información antes de enviarla, completar formularios de varios pasos o propagar el contenido de los formularios de forma dinámica.

Para procesar los datos que ingresan los usuarios, la app de Chat controla los datos en el objeto commonEventObject.formInputs del evento. Para obtener más información sobre cómo recuperar valores de widgets de entrada, consulta Cómo recopilar y procesar información de los usuarios.

Para hacer un seguimiento de los datos que los usuarios ingresan desde el diálogo inicial, debes agregar parámetros al botón que abre el siguiente diálogo. Para obtener más información, consulta Cómo transferir datos a otra tarjeta.

En este ejemplo, una app de Chat abre un diálogo inicial que lleva a un segundo diálogo para confirmar antes de enviar:

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;
  // Handle MESSAGE events
  if(chatEvent.messagePayload) {
    return res.send(handleMessage(req.body));
  // Handle button clicks
  } else if(chatEvent.buttonClickedPayload) {
    switch(req.body.commonEventObject.parameters.actionName) {
        case "openInitialDialog":
            return res.send(openInitialDialog(req.body));
        case "openConfirmationDialog":
            return res.send(openConfirmationDialog(req.body));
        case "submitDialog":
            return res.send(submitDialog(req.body));
    }
  }
};

/**
 * Responds to a message in Google Chat.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} response that handles dialogs.
 */
function handleMessage(event) {
  // Reply with a message that contains a button to open the initial dialog
  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    text: "To add a contact, use the `ADD CONTACT` button below.",
    accessoryWidgets: [{ buttonList: { buttons: [{
      text: "ADD CONTACT",
      onClick: { action: {
        // Use runtime environment variable set with self URL
        function: process.env.BASE_URL,
        parameters: [{ key: "actionName", value: "openInitialDialog" }],
        interaction: "OPEN_DIALOG"
      }}
    }]}}]
  }}}}};
}

/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} open the dialog.
 */
function openInitialDialog(event) {
  return { action: { navigations: [{ pushCard: { sections: [{ widgets: [{
    textInput: {
      name: "contactName",
      label: "First and last name",
      type: "SINGLE_LINE"
    }},
    WIDGETS, {
    buttonList: { buttons: [{
      text: "NEXT",
      onClick: { action: {
        // Use runtime environment variable set with self URL
        function: process.env.BASE_URL,
        parameters: [{ key: "actionName", value: "openConfirmationDialog" }]
      }}
    }]}}
  ]}]}}]}};
}

/**
 * Opens the second step of the dialog that lets users confirm details.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} update the dialog.
 */
function openConfirmationDialog(event) {
  // Retrieve the form input values
  const name = event.commonEventObject.formInputs["contactName"].stringInputs.value[0];
  return { action: { navigations: [{ pushCard: { sections: [{ widgets: [{
    // Display the input values for confirmation
    textParagraph: { text: "<b>Name:</b> " + name }},
    WIDGETS, {
    buttonList: { buttons: [{
      text: "SUBMIT",
      onClick: { action: {
        // Use runtime environment variable set with self URL
        function: process.env.BASE_URL,
        parameters: [{
          key: "actionName", value: "submitDialog" }, {
          // Pass input values as parameters for last dialog step (submission)
          key: "contactName", value: name
        }]
      }}
    }]}}]
  }]}}]}};
}

Apps Script

En este ejemplo, se muestra un mensaje de tarjeta mediante la devolución de JSON de la tarjeta. También puedes usar el servicio de tarjetas de Apps Script.

/**
 * Responds to a message in Google Chat.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} response that handles dialogs.
 */
function onMessage(event) {
  // Reply with a message that contains a button to open the initial dialog
  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    text: "To add a contact, use the `ADD CONTACT` button below.",
    accessoryWidgets: [{ buttonList: { buttons: [{
      text: "ADD CONTACT",
      onClick: { action: {
        function: "openInitialDialog",
        interaction: "OPEN_DIALOG"
      }}
    }]}}]
  }}}}};
}

/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} open the dialog.
 */
function openInitialDialog(event) {
  return { action: { navigations: [{ pushCard: { sections: [{ widgets: [{
    textInput: {
      name: "contactName",
      label: "First and last name",
      type: "SINGLE_LINE"
    }},
    WIDGETS, {
    buttonList: { buttons: [{
      text: "NEXT",
      onClick: { action: { function : "openConfirmationDialog" }}
    }]}}
  ]}]}}]}};
}

/**
 * Opens the second step of the dialog that lets users confirm details.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} update the dialog.
 */
function openConfirmationDialog(event) {
  // Retrieve the form input values
  const name = event.commonEventObject.formInputs["contactName"].stringInputs.value[0];
  return { action: { navigations: [{ pushCard: { sections: [{ widgets: [{
    // Display the input values for confirmation
    textParagraph: { text: "<b>Name:</b> " + name }},
    WIDGETS, {
    buttonList: { buttons: [{
      text: "SUBMIT",
      onClick: { action: {
        function: "submitDialog",
        // Pass input values as parameters for last dialog step (submission)
        parameters: [{ key: "contactName", value: name }]
      }}
    }]}}]
  }]}}]}};
}

Donde WIDGETS representa cualquier otro widget de entrada de formulario.

Cerrar el diálogo

Cuando los usuarios hacen clic en un botón de envío en un diálogo, tu app de chat ejecuta su acción asociada y proporciona al objeto del evento buttonClickedPayload configurado de la siguiente manera:

  • isDialogEvent es true.
  • dialogEventType es SUBMIT_DIALOG.

La app de Chat debe mostrar un objeto RenderActions con EndNavigation establecido en CLOSE_DIALOG.

Opcional: Cómo mostrar una notificación

Cuando cierres el diálogo, también puedes mostrar una notificación de texto.

Para mostrar una notificación, muestra el objeto RenderActions con el campo notification configurado.

En el siguiente ejemplo, se verifica que los parámetros sean válidos y se cierra el diálogo con una notificación de texto según el resultado:

Node.js

/**
 * Handles submission and closes the dialog.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} close the dialog with a status in text notification.
 */
function submitDialog(event) {
  // Validate the parameters.
  if (!event.commonEventObject.parameters["contactName"]) {
    return { action: {
      navigations: [{ endNavigation: "CLOSE_DIALOG"}],
      notification: { text: "Failure, the contact name was missing!" }
    }};
  }

  return { action: {
    navigations: [{ endNavigation: "CLOSE_DIALOG"}],
    notification: { text: "Success, the contact was added!" }
  }};
}

Apps Script

/**
 * Handles submission and closes the dialog.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} close the dialog with a status in text notification.
 */
function submitDialog(event) {
  // Validate the parameters.
  if (!event.commonEventObject.parameters["contactName"]) {
    return { action: {
      navigations: [{ endNavigation: "CLOSE_DIALOG"}],
      notification: { text: "Failure, the contact name was missing!" }
    }};
  }

  return { action: {
    navigations: [{ endNavigation: "CLOSE_DIALOG"}],
    notification: { text: "Success, the contact was added!" }
  }};
}

Para obtener más información sobre cómo pasar parámetros entre diálogos, consulta Cómo transferir datos a otra tarjeta.

Opcional: Envía un mensaje de confirmación

Cuando cierres el diálogo, también podrás enviar un mensaje nuevo o actualizar uno existente.

Para enviar un mensaje nuevo, muestra un objeto DataActions con el campo CreateMessageAction configurado con el mensaje nuevo. Por ejemplo, para cerrar el diálogo y enviar un mensaje de texto, muestra lo siguiente:

{ "hostAppDataAction": { "chatDataAction": { "createMessageAction": { "message": {
  "text": "Your information has been submitted."
}}}}}

Para actualizar un mensaje después de que el usuario envía un diálogo, muestra un objeto DataActions que contenga una de las siguientes acciones:

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.