Abrir caixas de diálogo interativas

Esta página descreve como seu app do Chat pode abrir caixas de diálogo de responder aos usuários.

Caixas de diálogo são interfaces em janelas baseadas em cards abertos em um espaço ou uma mensagem do Chat. A caixa de diálogo e os o conteúdo fica visível apenas para o usuário que o abriu.

Os apps de chat podem usar caixas de diálogo para solicitar e coletar informações Usuários do chat, incluindo formulários de várias etapas. Para mais detalhes sobre a criação de entradas de formulários, consulte Coletar e processar informações dos usuários.

Pré-requisitos

Node.js

  • Um app do Google Chat com recursos interativos ativados. Para criar um interativo do Chat que usa um serviço HTTP, conclua este guia de início rápido.

Python

  • Um app do Google Chat com recursos interativos ativados. Para criar um interativo do Chat que usa um serviço HTTP, conclua este guia de início rápido.

Apps Script

  • Um app do Google Chat com recursos interativos ativados. Para criar um interativo com o app Chat no Apps Script, conclua este guia de início rápido.

Abrir uma caixa de diálogo

Uma caixa de diálogo com vários widgets diferentes.
Figura 1: uma caixa de diálogo que coleta dados de contato.

Nesta seção, explicamos como responder e configurar uma caixa de diálogo fazendo o seguinte:

  1. Acionar a solicitação da caixa de diálogo de uma interação do usuário.
  2. Para processar a solicitação, retorne e abra uma caixa de diálogo.
  3. Depois que os usuários enviarem as informações, processe o envio fechando a caixa de diálogo ou retornar outra caixa de diálogo.

Acionar uma solicitação de caixa de diálogo

Um app do Chat só pode abrir caixas de diálogo para responder a um usuário interação, como um comando de barra ou o clique de um botão em uma mensagem em um card.

Para responder aos usuários com uma caixa de diálogo, um app do Chat precisa crie uma interação que acione a solicitação de caixa de diálogo, como esta:

  • Responda a um comando de barra. Para acionar a solicitação por um comando de barra, marque a caixa de seleção Abre uma caixa de diálogo ao configurar o comando.
  • Responda ao clique de um botão mensagem, como parte de um card ou na parte inferior da mensagem. Para acionar o de um botão em uma mensagem, você configura o onClick do botão definindo interaction como OPEN_DIALOG.
  • Responder a um clique de botão na página inicial de um app do Chat. Para saber mais sobre como abrir caixas de diálogo em páginas iniciais, consulte Crie uma página inicial para o app do Google Chat.
.
Botão que aciona uma caixa de diálogo
Figura 2: um app do Chat envia uma mensagem solicitando que os usuários usem o comando de barra /addContact.
A mensagem também inclui um botão em que os usuários podem clicar para acionar o comando.

O JSON a seguir mostra como acionar uma solicitação de caixa de diálogo por um botão em um mensagem do cartão. Para abrir a caixa de diálogo, o button.interaction está definido como OPEN_DIALOG:

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

Em que BUTTON_TEXT é o texto mostrado no botão. e FUNCTION_NAME é a função executada para abrir o caixa de diálogo.

Abrir a caixa de diálogo inicial

Quando um usuário aciona uma solicitação de caixa de diálogo, seu app do Chat recebe um evento de interação, representado como event no API Chat. Se a interação acionar uma solicitação de caixa de diálogo, o evento O campo dialogEventType está definido como REQUEST_DIALOG.

Para abrir uma caixa de diálogo, o app do Chat pode responder ao de destino retornando uma actionResponse objeto com o type definido como DIALOG e Message objeto. Para especificar o conteúdo da caixa de diálogo, inclua o seguinte objetos:

  • Um actionResponse com o type definido como DIALOG.
  • Um objeto dialogAction. O campo body contém os elementos da interface do usuário (IU) a serem exibir no card, incluindo um ou mais sections de widgets. Para coletar informações dos usuários, especifique formulários de widgets de entrada e um widget de botão. Para saber mais sobre como projetar entradas de formulário, consulte Coletar e processar informações dos usuários.

O JSON a seguir mostra como um app do Chat retorna uma resposta que abre uma caixa de diálogo:

{ "actionResponse": {
  "type": "DIALOG",
  "dialogAction": { "dialog": { "body": { "sections": [{
    "widgets": [{
      WIDGETS,
      { "buttonList": { "buttons": [{
        "text": "BUTTON_TEXT",
        "onClick": {
          "action": {"function": "FUNCTION_NAME"}
        }
      }]}}
    }]
  }]}}}
}}

Em que BUTTON_TEXT é o texto mostrado no botão (como Next ou Submit), WIDGETS representa um ou mais widgets de entrada de formulário FUNCTION_NAME é a função executada quando os usuários clicam em um botão.

Processar o envio da caixa de diálogo

Quando os usuários clicam em um botão que envia uma caixa de diálogo, seu O app do Chat recebe uma interação CARD_CLICKED evento em que dialogEventType é SUBMIT_DIALOG.

Seu app do Chat precisa processar o evento de interação da seguinte forma: realizando uma das seguintes ações:

Opcional: retornar outra caixa de diálogo

Depois que os usuários enviam a caixa de diálogo inicial, os apps do Chat podem retornar uma ou mais caixas de diálogo adicionais para ajudar os usuários a revisar as informações antes enviar, preencher formulários de várias etapas ou preencher o conteúdo do formulário dinamicamente.

Para carregar os dados inseridos pelos usuários na caixa de diálogo inicial, adicione para o botão que abre a próxima caixa de diálogo ou transmita o valor CARD_CLICKED na caixa de diálogo inicial. Para mais detalhes, consulte Transferir dados para outro cartão.

Neste exemplo, um app do Chat abre uma caixa de diálogo que retorna uma segunda caixa de diálogo antes do envio. Para carregar os dados de entrada, o O app do Chat transmite o evento de interação CARD_CLICKED como parâmetro para a função que abre a próxima caixa de diálogo:

Node.js

// Respond to button clicks on attached cards
if (event.type === "CARD_CLICKED") {

  // Open the first dialog.
  if (event.common.invokedFunction === "openDialog") {
    openDialog(event);
  }

  // Open the second dialog.
  if (event.common.invokedFunction === "openNextDialog") {
    openNextDialog(event);
  }
}

/**
* Opens and starts a dialog that lets users add details about a contact.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openDialog(event) {
  res.json({ "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      { "buttonList": { "buttons": [{
        "text": "Next",
        "onClick": { "action": {
          "function": "openNextDialog"
        }}
      }]}}
    ]}]}}}
  }});
};

/**
* Opens a second dialog that lets users add more contact details.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openNextDialog(event) {
  res.json({ "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      {
        "horizontalAlignment": "END",
        "buttonList": { "buttons": [{
          "text": "Submit",
          "onClick": { "action": {
            "function": "submitDialog"
          }}
        }]}
      }
    ]}]}}}
  }});
}

Python

from typing import Any, Mapping

import flask
import functions_framework

@functions_framework.http
def main(req: flask.Request) -> Mapping[str, Any]:
  """Responds to a MESSAGE event in Google Chat that includes the /createContact
     slash command by opening a dialog.

  Args:
      req (flask.Request): the event object from Chat API.

  Returns:
      Mapping[str, Any]: open a Dialog in response to a card's button click.
  """

  if req.method == 'GET':
    return 'Sorry, this function must be called from a Google Chat.'

  request = req.get_json(silent=True)

  if request.get('type') == 'CARD_CLICKED':
    if invoked_function := request.get('common', dict()).get('invokedFunction'):
      if invoked_function == 'open_dialog':
        return open_dialog(request)

      elif invoked_function == 'open_next_dialog':
        return open_dialog(request)

def open_dialog(request: Mapping[str, Any]) -> Mapping[str, Any]:
  """Opens a dialog in Google Chat.

  Args:
      request (Mapping[str, Any]): the event object from Chat API.

  Returns:
      Mapping[str, Any]: open a Dialog in response to a card's button click.
  """
  return { "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      { "buttonList": { "buttons": [{
        "text": "Next",
        "onClick": { "action": {
          "function": "open_next_dialog"
        }}
      }]}}
    ]}]}}}
  }}

def open_next_dialog(request: Mapping[str, Any]) -> Mapping[str, Any]:
  """Opens a second dialog that lets users add more contact details.

  Args:
      request (Mapping[str, Any]): the event object from Chat API.

  Returns:
      Mapping[str, Any]: open a Dialog in response to a card's button click.
  """
  return { "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      {
        "horizontalAlignment": "END",
        "buttonList": { "buttons": [{
          "text": "Submit",
          "onClick": { "action": {
            "function": "submit_dialog"
          }}
        }]}
      }
    ]}]}}}
  }}

Apps Script

Este exemplo envia uma mensagem de card retornando JSON do cartão. Você também pode usar o Serviço de card do Apps Script.

/**
* Responds to a CARD_CLICKED event in Google Chat.
*
* @param {Object} event the event object from Google Chat
*/
function onCardClick(event) {

  // When a user clicks a card, the Chat app checks to see which function to run.
  if (event.common.invokedFunction === "openDialog") {
    return openDialog(event);
  }

  if (event.common.invokedFunction === "openNextDialog") {
    return openNextDialog(event);
  }
}

/**
* Opens and starts a dialog that lets users add details about a contact.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openDialog(event) {
  return { "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      { "buttonList": { "buttons": [{
        "text": "Next",
        "onClick": { "action": {
          "function": "openNextDialog"
        }}
      }]}}
    ]}]}}}
  }};
}

/**
* Opens a second dialog that lets users add more contact details.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openNextDialog(event) {
  return { "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      {
        "horizontalAlignment": "END",
        "buttonList": { "buttons": [{
          "text": "Submit",
          "onClick": { "action": {
            "function": "submitDialog"
          }}
        }]}
      }
    ]}]}}}
  }};
}

Em que WIDGETS representa um ou mais widgets de entrada de formulário.

Fechar a caixa de diálogo

Quando os usuários clicam em um botão em uma caixa de diálogo, seu O app do Chat recebe um evento de interação com o seguintes informações:

As seções a seguir explicam como validar os dados que os usuários inserem e feche a caixa de diálogo.

Validar os dados de entrada do usuário e fechar a caixa de diálogo

Para processar os dados inseridos pelos usuários, o app do Chat usa o event.common.formInputs objeto. Para saber mais sobre como recuperar valores de widgets de entrada, consulte Coletar e processar informações dos usuários.

Se o usuário omitir um campo obrigatório ou inserir valores incorretos, o O app do Chat pode responder com um erro retornando um ActionResponse que tenha "actionStatus": "ERROR MESSAGE".

O exemplo a seguir verifica se um usuário insere um valor para um widget que aceita strings (stringInputs), como um widget textInput. Se ausente, o O app de chat retorna um erro. Se estiver presente, o app do Chat confirma o envio da caixa de diálogo e fecha a caixa de diálogo:

Node.js

/**
* Checks for a form input error, the absence of
* a "name" value, and returns an error if absent.
* Otherwise, confirms successful receipt of a dialog.
*
* Confirms successful receipt of a dialog.
*
* @param {Object} event the event object from Chat API.
*
* @return {Object} open a Dialog in Google Chat.
*/
function submitDialog(event) {

  // Checks to make sure the user entered a value
  // in a dialog. If no value detected, returns
  // an error message. Any "actionStatus" value other than "OK"
  // gets returned as an error.
  if (event.common.formInputs.WIDGET_NAME.stringInputs.value[0] === "") {
    res.json({
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "ERROR_MESSAGE"
        }
      }
    });

    // Otherwise the Chat app indicates that it received
    // form data from the dialog. An "actionStatus" of "OK" is
    // interpreted as code 200, and the dialog closes.
  } else {
    res.json({
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "OK"
        }
      }
    });
  }
}

Python

def receive_dialog(event: Mapping[str, Any]) -> Mapping[str, Any]:
  """Checks for a form input error, the absence of a "name" value, and returns
     an error if absent. Otherwise, confirms successful receipt of a dialog.

  Args:
      event (Mapping[str, Any]): the event object from Chat API.

  Returns:
      Mapping[str, Any]: the response.
  """

  if common := event.get('common'):
    if form_inputs := common.get('formInputs'):
      if contact_name := form_inputs.get('WIDGET_NAME'):
        if string_inputs := contact_name.get('stringInputs'):
          if name := string_inputs.get('value')[0]:
            return {
              'actionResponse': {
                'type': 'DIALOG',
                'dialogAction': {
                  'actionStatus': 'OK'
                }
              }
            }
          else:
            return {
              'actionResponse': {
                'type': 'DIALOG',
                'dialogAction': {
                  'actionStatus': 'ERROR_MESSAGE'
                }
              }
            }

Apps Script

Este exemplo envia uma mensagem de card retornando JSON do cartão. Você também pode usar o Serviço de card do Apps Script.

/**
* Checks for a form input error, the absence of
* a "name" value, and returns an error if absent.
* Otherwise, confirms successful receipt of a dialog.
*
* Confirms successful receipt of a dialog.
*
* @param {Object} event the event object from Chat API.
*
* @return {object} open a Dialog in Google Chat.
*/
function submitDialog(event) {

  // Checks to make sure the user entered a value
  // in a dialog. If no value detected, returns
  // an error message. Any "actionStatus" value other than "OK"
  // gets returned as an error.
  if (event.common.formInputs.WIDGET_NAME[""].stringInputs.value[0] === "") {
    return {
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "ERROR_MESSAGE"
        }
      }
    };

    // Otherwise the Chat app indicates that it received
    // form data from the dialog. An "actionStatus" of "OK" is
    // interpreted as code 200, and the dialog closes.
  } else {
    return {
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "OK"
        }
      }
    };
  }
}

Neste exemplo, WIDGET_NAME representa o campo name do (como contactName) e ERROR_MESSAGE representa o o conteúdo da mensagem de erro (como Don't forget to name your contact). Para detalhes sobre o processamento de dados de entrada de widgets, consulte Receber dados de widgets interativos.

Opcional: enviar uma mensagem de confirmação

Ao fechar a caixa de diálogo, você também pode enviar uma nova mensagem ou atualizar um um já criado.

Para enviar uma nova mensagem, retorne um ActionResponse Objeto com o type definido como NEW_MESSAGE. Por exemplo, para fechar a caixa de diálogo e enviar uma mensagem de texto, retorne o seguinte comando:

  {
    "actionResponse": {
      "type": "NEW_MESSAGE",
    },
    "text": "Your information has been submitted."
  }

Para atualizar uma mensagem, retorne um objeto actionResponse que contenha as atualizada e define type como um dos seguintes:

Resolver problemas

Quando um app ou card retornar um erro, o A interface do chat mostra a mensagem "Algo deu errado". ou "Não foi possível processar sua solicitação". Às vezes, a interface do Chat não exibe nenhuma mensagem de erro, mas o app do Chat ou produz um resultado inesperado; por exemplo, uma mensagem de cartão pode não aparecer.

Embora uma mensagem de erro possa não aparecer na interface do Chat, mensagens de erro descritivas e dados de registro estão disponíveis para ajudar você a corrigir os erros quando a geração de registros de erros nos apps do Chat está ativada. Para receber ajuda com a visualização, depurar e corrigir erros, consulte Resolver problemas e corrigir erros do Google Chat.