Criar caixas de diálogo interativas

Esta página descreve como um app do Google Chat pode abrir caixas de diálogo para mostrar interfaces de usuário (IUs) e responder aos usuários.

Os diálogos são interfaces baseadas em cards e janelas que abrem em um espaço ou mensagem do Chat. A caixa de diálogo e o conteúdo dela ficam visíveis apenas para o usuário que a abriu.

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

Pré-requisitos

HTTP

Um complemento do Google Workspace que amplia o Google Chat. Para criar um, conclua o início rápido de HTTP.

Apps Script

Um complemento do Google Workspace que amplia o Google Chat. Para criar um, conclua o guia de início rápido do Apps Script.

Abrir uma caixa de diálogo

Uma caixa de diálogo com vários widgets diferentes.
Figura 1: um app de chat que abre uma caixa de diálogo para coletar informações de contato.

Esta seção explica como responder e configurar uma caixa de diálogo fazendo o seguinte:

  1. Acione a solicitação de caixa de diálogo de uma interação do usuário.
  2. Processe a solicitação retornando e abrindo uma caixa de diálogo.
  3. Depois que os usuários enviarem informações, processe o envio fechando a caixa de diálogo ou retornando outra.

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

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

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

  • Responder a um comando. Para acionar a solicitação de um comando, marque a caixa de seleção Abre uma caixa de diálogo ao configurar o comando.
  • Responder a um clique de botão em uma mensagem, como parte de um card ou na parte de baixo da mensagem. Para acionar a solicitação de um botão em uma mensagem, configure a ação onClick do botão definindo o interaction como OPEN_DIALOG.
Botão que aciona uma caixa de diálogo
Figura 2: um app do Chat envia uma mensagem pedindo 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 exemplo de código a seguir mostra como acionar uma solicitação de caixa de diálogo usando um botão em uma mensagem de card. Para abrir a caixa de diálogo, defina o campo onClick.action.interaction do botão como OPEN_DIALOG:

Node.js

node/chat/contact-form-app/index.js
{ buttonList: { buttons: [{
  text: "ADD CONTACT",
  onClick: { action: {
    function: FUNCTION_URL,
    interaction: "OPEN_DIALOG",
    parameters: [
      { key: "actionName", value: "openInitialDialog" }
    ]
  }}
}]}}

Substitua FUNCTION_URL pelo endpoint HTTP que processa os cliques no botão.

Python

python/chat/contact-form-app/main.py
{ 'buttonList': { 'buttons': [{
  'text': "ADD CONTACT",
  'onClick': { 'action': {
    'function': FUNCTION_URL,
    'interaction': "OPEN_DIALOG",
    'parameters': [
      { 'key': "actionName", 'value': "openInitialDialog" }
    ]
  }}
}]}}

Substitua FUNCTION_URL pelo endpoint HTTP que processa os cliques no botão.

Java

java/chat/contact-form-app/src/main/java/com/google/chat/contact/App.java
.setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(new GoogleAppsCardV1Button()
  .setText("ADD CONTACT")
  .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
    .setFunction(FUNCTION_URL)
    .setInteraction("OPEN_DIALOG")
    .setParameters(List.of(
      new GoogleAppsCardV1ActionParameter().setKey("actionName").setValue("openInitialDialog"))))))))));

Substitua FUNCTION_URL pelo endpoint HTTP que processa os cliques no botão.

Apps Script

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

apps-script/chat/contact-form-app/Code.gs
{ buttonList: { buttons: [{
  text: "ADD CONTACT",
  onClick: { action: {
    function: "openInitialDialog",
    interaction: "OPEN_DIALOG"
  }}
}]}}

Abrir a caixa de diálogo inicial

Quando um usuário aciona uma solicitação de caixa de diálogo, o app de chat recebe um objeto de evento com uma carga útil que especifica um objeto dialogEventType como REQUEST_DIALOG.

Para abrir uma caixa de diálogo, o app Chat pode responder à solicitação retornando um objeto RenderActions com a navegação pushCard para mostrar um card. O card precisa conter elementos da interface do usuário (UI), incluindo um ou mais sections[] de widgets. Para coletar informações dos usuários, você pode especificar widgets de entrada de formulário e um widget de botão. Para saber mais sobre como criar entradas de formulário, consulte Coletar e processar informações dos usuários.

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

Node.js

node/chat/contact-form-app/index.js
/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @return {Object} open the dialog.
 */
function openInitialDialog() {
  return { action: { navigations: [{ pushCard: { sections: [{ 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 }
      ]
    }},
    { buttonList: { buttons: [{
      text: "NEXT",
      onClick: { action: {
        function: FUNCTION_URL,
        parameters: [
          { key: "actionName", value: "openConfirmationDialog" }
        ]
      }}
    }]}}
  ]}]}}]}};
}

Substitua FUNCTION_URL pelo endpoint HTTP que processa os cliques no botão.

Python

python/chat/contact-form-app/main.py
def open_initial_dialog() -> Mapping[str, Any]:
  """Opens the initial step of the dialog that lets users add contact details.

  Returns:
    Mapping[str, Any]: open the dialog.
  """
  return { 'action': { 'navigations': [{ 'pushCard': { 'sections': [{ '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 }
      ]
    }},
    { 'buttonList': { 'buttons': [{
      'text': "NEXT",
      'onClick': { 'action': {
        'function': FUNCTION_URL,
        'parameters': [
          { 'key': "actionName", 'value': "openConfirmationDialog" }
        ]
      }}
    }]}}
  ]}]}}]}}

Substitua FUNCTION_URL pelo endpoint HTTP que processa os cliques no botão.

Java

java/chat/contact-form-app/src/main/java/com/google/chat/contact/App.java
/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @return {Object} open the dialog.
 */
GenericJson openInitialDialog() {
  GoogleAppsCardV1Card cardV2 = new GoogleAppsCardV1Card()
    .setSections(List.of(new GoogleAppsCardV1Section().setWidgets(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)))),
      new GoogleAppsCardV1Widget().setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(
        new GoogleAppsCardV1Button()
          .setText("NEXT")
          .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
            .setFunction(FUNCTION_URL)
            .setParameters(List.of(
              new GoogleAppsCardV1ActionParameter().setKey("actionName").setValue("openConfirmationDialog"))))))))))));
  return new GenericJson() {{
    put("action", new GenericJson() {{
      put("navigations", List.of(new GenericJson() {{
        put("pushCard", cardV2);
      }}));
    }});
  }};
}

Substitua FUNCTION_URL pelo endpoint HTTP que processa os cliques no botão.

Apps Script

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

apps-script/chat/contact-form-app/Code.gs
/**
 * 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"
    }},
    { 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 }
      ]
    }},
    { buttonList: { buttons: [{
      text: "NEXT",
      onClick: { action: { function : "openConfirmationDialog" }}
    }]}}
  ]}]}}]}};
}

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 app de chat recebe um objeto de evento com um objeto ButtonClickedPayload. No payload, o dialogEventType é definido como SUBMIT_DIALOG. Para entender como coletar e processar as informações na caixa de diálogo, consulte Coletar e processar informações de usuários do Google Chat.

Seu app do Chat precisa responder ao objeto de evento fazendo 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 de chat podem retornar uma ou mais caixas de diálogo adicionais para ajudar os usuários a revisar informações antes de enviar, preencher formulários de várias etapas ou preencher o conteúdo do formulário de forma dinâmica.

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

Para acompanhar os dados inseridos pelos usuários na caixa de diálogo inicial, adicione parâmetros ao botão que abre a próxima caixa de diálogo. Para mais detalhes, consulte Transferir dados para outro cartão.

Neste exemplo, um app do Chat abre uma caixa de diálogo inicial que leva a uma segunda caixa de diálogo para confirmação antes do envio:

Node.js

node/chat/contact-form-app/index.js
/**
 * Responds to a message in Google Chat.
 *
 * @return {Object} response that handles dialogs.
 */
function handleMessage() {
  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: FUNCTION_URL,
          interaction: "OPEN_DIALOG",
          parameters: [
            { key: "actionName", value: "openInitialDialog" }
          ]
        }}
      }]}}
    ]
  }}}}};
}

/**
 * Responds to a button clicked in Google Chat.
 *
 * @param {Object} event The event object from the Google Workspace add-on.
 * @return {Object} response depending on the button clicked.
 */
function handleButtonClicked(event) {
  // Initial dialog form page
  if (event.commonEventObject.parameters.actionName === "openInitialDialog") {
    return openInitialDialog();
  // Confirmation dialog form page
  } else if (event.commonEventObject.parameters.actionName === "openConfirmationDialog") {
    return openConfirmationDialog(event);
  // Submission dialog form page
  } else if (event.commonEventObject.parameters.actionName === "submitDialog") {
    return submitDialog(event);
  }
}

/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @return {Object} open the dialog.
 */
function openInitialDialog() {
  return { action: { navigations: [{ pushCard: { sections: [{ 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 }
      ]
    }},
    { buttonList: { buttons: [{
      text: "NEXT",
      onClick: { action: {
        function: FUNCTION_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];
  const birthdate = event.commonEventObject.formInputs["contactBirthdate"].dateInput.msSinceEpoch;
  const type = event.commonEventObject.formInputs["contactType"].stringInputs.value[0];
  // Display the input values for confirmation
  return { action: { navigations: [{ pushCard: { sections: [{ widgets: [
    { textParagraph: { text: "Confirm contact information and submit:" }},
    { textParagraph: { text: "<b>Name:</b> " + name }},
    { textParagraph: { text: "<b>Birthday:</b> " + new Date(birthdate) }},
    { textParagraph: { text: "<b>Type:</b> " + type }},
    { buttonList: { buttons: [{
      text: "SUBMIT",
      onClick: { action: {
        function: FUNCTION_URL,
        parameters: [
          { key: "actionName", value: "submitDialog" },
          // Pass input values as parameters for last dialog step (submission)
          { key: "contactName", value: name },
          { key: "contactBirthdate", value: birthdate },
          { key: "contactType", value: type }
        ]
      }}
    }]}}
  ]}]}}]}};
}

Substitua FUNCTION_URL pelo endpoint HTTP que processa os cliques no botão.

Python

python/chat/contact-form-app/main.py
def handle_message() -> Mapping[str, Any]:
  """Responds to a message in Google Chat.

  Returns:
    Mapping[str, Any]: the response that handles dialogs.
  """
  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': FUNCTION_URL,
          'interaction': "OPEN_DIALOG",
          'parameters': [
            { 'key': "actionName", 'value': "openInitialDialog" }
          ]
        }}
      }]}}
    ]
  }}}}}


def handle_button_clicked(event: Mapping[str, Any]) -> Mapping[str, Any]:
  """Responds to a button clicked in Google Chat.

  Args:
    Mapping[str, Any] event: the event object from the Google Workspace add-on

  Returns:
    Mapping[str, Any]: the response depending on the button clicked.
  """
  # Initial dialog form page
  if "openInitialDialog" == event['commonEventObject']['parameters']['actionName']:
    return open_initial_dialog()
  # Confirmation dialog form page
  elif "openConfirmationDialog" == event['commonEventObject']['parameters']['actionName'] :
    return open_confirmation_dialog(event)
  # Submission dialog form page
  elif "submitDialog" == event['commonEventObject']['parameters']['actionName']:
    return submit_dialog(event)


def open_initial_dialog() -> Mapping[str, Any]:
  """Opens the initial step of the dialog that lets users add contact details.

  Returns:
    Mapping[str, Any]: open the dialog.
  """
  return { 'action': { 'navigations': [{ 'pushCard': { 'sections': [{ '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 }
      ]
    }},
    { 'buttonList': { 'buttons': [{
      'text': "NEXT",
      'onClick': { 'action': {
        'function': FUNCTION_URL,
        'parameters': [
          { 'key': "actionName", 'value': "openConfirmationDialog" }
        ]
      }}
    }]}}
  ]}]}}]}}


def open_confirmation_dialog(event: Mapping[str, Any]) -> Mapping[str, Any]:
  """Opens the second step of the dialog that lets users confirm details.

  Args:
    Mapping[str, Any] event: the event object from the Google Workspace add-on

  Returns:
    Mapping[str, Any]: update the dialog.
  """
  name = event.get('commonEventObject').get('formInputs')["contactName"].get('stringInputs').get('value')[0]
  birthdateEpoch = event.get('commonEventObject').get('formInputs')["contactBirthdate"].get('dateInput').get('msSinceEpoch')
  birthdate = datetime.fromtimestamp(int(birthdateEpoch) / 1000.0).strftime("%Y-%m-%d")
  type = event.get('commonEventObject').get('formInputs')["contactType"].get('stringInputs').get('value')[0]
  # Display the input values for confirmation
  return { 'action': { 'navigations': [{ 'pushCard': { 'sections': [{ 'widgets': [
    { 'textParagraph': { 'text': "Confirm contact information and submit:" }},
    { 'textParagraph': { 'text': "<b>Name:</b> " + name }},
    { 'textParagraph': { 'text': "<b>Birthday:</b> " + birthdate }},
    { 'textParagraph': { 'text': "<b>Type:</b> " + type }},
    { 'buttonList': { 'buttons': [{
      'text': "SUBMIT",
      'onClick': { 'action': {
        'function': FUNCTION_URL,
        'parameters': [
          { 'key': "actionName", 'value': "submitDialog" },
          # Pass input values as parameters for last dialog step (submission)
          { 'key': "contactName", 'value': name },
          { 'key': "contactBirthdate", 'value': birthdate },
          { 'key': "contactType", 'value': type }
        ]
      }}
    }]}}
  ]}]}}]}}

Substitua FUNCTION_URL pelo endpoint HTTP que processa os cliques no botão.

Java

java/chat/contact-form-app/src/main/java/com/google/chat/contact/App.java
/**
 * Responds to a message in Google Chat.
 *
 * @return response that handles dialogs.
 */
GenericJson handleMessage() {
  Message message = new Message()
    .setText("To add a contact, use the `ADD CONTACT` button below.")
    .setAccessoryWidgets(List.of(new AccessoryWidget()
      .setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(new GoogleAppsCardV1Button()
        .setText("ADD CONTACT")
        .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
          .setFunction(FUNCTION_URL)
          .setInteraction("OPEN_DIALOG")
          .setParameters(List.of(
            new GoogleAppsCardV1ActionParameter().setKey("actionName").setValue("openInitialDialog"))))))))));
  return new GenericJson() {{
    put("hostAppDataAction", new GenericJson() {{
      put("chatDataAction", new GenericJson() {{
        put("createMessageAction", new GenericJson() {{
          put("message", message);
        }});
      }});
    }});
  }};
}

/**
 * Responds to a button clicked in Google Chat.
 *
 * @param event The event object from the Google Workspace add-on.
 * @return response depending on the button clicked.
 */
GenericJson handleButtonClicked(JsonNode event) {
  String actionName = event.at("/commonEventObject/parameters/actionName").asText();
  // Initial dialog form page
  if ("openInitialDialog".equals(actionName)) {
    return openInitialDialog();
  // Confirmation dialog form page
  } else if ("openConfirmationDialog".equals(actionName)) {
    return openConfirmationDialog(event);
  // Submission dialog form page
  } else if ("submitDialog".equals(actionName)) {
    return submitDialog(event);
  }
  return null; 
}

/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @return {Object} open the dialog.
 */
GenericJson openInitialDialog() {
  GoogleAppsCardV1Card cardV2 = new GoogleAppsCardV1Card()
    .setSections(List.of(new GoogleAppsCardV1Section().setWidgets(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)))),
      new GoogleAppsCardV1Widget().setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(
        new GoogleAppsCardV1Button()
          .setText("NEXT")
          .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
            .setFunction(FUNCTION_URL)
            .setParameters(List.of(
              new GoogleAppsCardV1ActionParameter().setKey("actionName").setValue("openConfirmationDialog"))))))))))));
  return new GenericJson() {{
    put("action", new GenericJson() {{
      put("navigations", List.of(new GenericJson() {{
        put("pushCard", cardV2);
      }}));
    }});
  }};
}

/**
 * Opens the second step of the dialog that lets users confirm details.
 *
 * @param event The event object from the Google Workspace add-on.
 * @return update the dialog.
 */
GenericJson openConfirmationDialog(JsonNode event) {
  // Retrieve the form input values
  String name = event.at("/commonEventObject/formInputs/contactName/stringInputs/value").get(0).asText();
  String birthdateEpoch = event.at("/commonEventObject/formInputs/contactBirthdate/dateInput/msSinceEpoch").asText();
  String birthdate = new SimpleDateFormat("MM/dd/yyyy").format(new Date((long)Double.parseDouble(birthdateEpoch)));
  String type = event.at("/commonEventObject/formInputs/contactType/stringInputs/value").get(0).asText();
  // Display the input values for confirmation
  GoogleAppsCardV1Card cardV2 = new GoogleAppsCardV1Card()
    .setSections(List.of(new GoogleAppsCardV1Section().setWidgets(List.of(
      new GoogleAppsCardV1Widget().setTextParagraph(new GoogleAppsCardV1TextParagraph()
        .setText("Confirm contact information and submit:")),
      new GoogleAppsCardV1Widget().setTextParagraph(new GoogleAppsCardV1TextParagraph()
        .setText("<b>Name:</b> " + name)),
      new GoogleAppsCardV1Widget().setTextParagraph(new GoogleAppsCardV1TextParagraph()
        .setText("<b>Birthday:</b> " + birthdate)),
      new GoogleAppsCardV1Widget().setTextParagraph(new GoogleAppsCardV1TextParagraph()
        .setText("<b>Type:</b> " + type)),
      new GoogleAppsCardV1Widget().setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(
        new GoogleAppsCardV1Button()
          .setText("SUBMIT")
          .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
            .setFunction(FUNCTION_URL)
            .setParameters(List.of(
              new GoogleAppsCardV1ActionParameter().setKey("actionName").setValue("submitDialog"),
              // Pass input values as parameters for last dialog step (submission)
              new GoogleAppsCardV1ActionParameter().setKey("contactName").setValue(name),
              new GoogleAppsCardV1ActionParameter().setKey("contactBirthdate").setValue(birthdate),
              new GoogleAppsCardV1ActionParameter().setKey("contactType").setValue(type))))))))))));
  return new GenericJson() {{
    put("action", new GenericJson() {{
      put("navigations", List.of(new GenericJson() {{
        put("pushCard", cardV2);
      }}));
    }});
  }};
}

Substitua FUNCTION_URL pelo endpoint HTTP que processa os cliques no botão.

Apps Script

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

apps-script/chat/contact-form-app/Code.gs
/**
 * 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"
    }},
    { 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 }
      ]
    }},
    { 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];
  const birthdate = event.commonEventObject.formInputs["contactBirthdate"].dateInput.msSinceEpoch;
  const type = event.commonEventObject.formInputs["contactType"].stringInputs.value[0];
  // Display the input values for confirmation
  return { action: { navigations: [{ pushCard: { sections: [{ widgets: [
    { textParagraph: { text: "Confirm contact information and submit:" }},
    { textParagraph: { text: "<b>Name:</b> " + name }},
    { textParagraph: { text: "<b>Birthday:</b> " + new Date(birthdate) }},
    { textParagraph: { text: "<b>Type:</b> " + type }},
    { buttonList: { buttons: [{
      text: "SUBMIT",
      onClick: { action: {
        function: "submitDialog",
        // Pass input values as parameters for last dialog step (submission)
        parameters: [
          { key: "contactName", value: name },
          { key: "contactBirthdate", value: birthdate },
          { key: "contactType", value: type }
        ]
      }}
    }]}}
  ]}]}}]}};
}

Fechar a caixa de diálogo

Quando os usuários clicam em um botão de envio em uma caixa de diálogo, o app de chat executa a ação associada e fornece o objeto de evento com buttonClickedPayload definido como:

  • isDialogEvent é true.
  • dialogEventType é SUBMIT_DIALOG.

O app Chat precisa retornar um objeto RenderActions com EndNavigation definido como CLOSE_DIALOG.

Opcional: mostrar uma notificação temporária

Ao fechar a caixa de diálogo, você também pode mostrar uma notificação de texto temporária para o usuário que está interagindo com o app.

Para mostrar uma notificação, retorne o objeto RenderActions com o campo notification definido.

O exemplo a seguir fecha a caixa de diálogo com uma notificação de texto:

Node.js

node/chat/contact-form-app/index.js
// Validate the parameters.
if (!event.commonEventObject.parameters["contactName"]) {
  return { action: {
    navigations: [{ endNavigation: { action: "CLOSE_DIALOG"}}],
    notification: { text: "Failure, the contact name was missing!" }
  }};
}

Python

python/chat/contact-form-app/main.py
# Validate the parameters.
if event.get('commonEventObject').get('parameters')["contactName"] == "":
  return { 'action': {
    'navigations': [{ 'endNavigation': { 'action': "CLOSE_DIALOG"}}],
    'notification': { 'text': "Failure, the contact name was missing!" }
  }}

Java

java/chat/contact-form-app/src/main/java/com/google/chat/contact/App.java
    // Validate the parameters.
    if (event.at("/commonEventObject/parameters/contactName").asText().isEmpty()) {
      return new GenericJson() {{
        put("action", new GenericJson() {{
          put("navigations", List.of(new GenericJson() {{
            put("endNavigation", new GenericJson() {{
              put("action", "CLOSE_DIALOG");
            }});
          }}));
          put("notification", new GenericJson() {{
            put("text", "Failure, the contact name was missing!");
          }});
        }});
      }};
    }

    return new GenericJson() {{
      put("hostAppDataAction", new GenericJson() {{
        put("chatDataAction", new GenericJson() {{
          put("createMessageAction", new GenericJson() {{
            put("message", new Message()
              .setText( "✅ " + event.at("/commonEventObject/parameters/contactName").asText() +
                        " has been added to your contacts."));
          }});
        }});
      }});
    }};
  }
}

Apps Script

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

apps-script/chat/contact-form-app/Code.gs
// Validate the parameters.
if (!event.commonEventObject.parameters["contactName"]) {
  return { action: {
    navigations: [{ endNavigation: { action: "CLOSE_DIALOG"}}],
    notification: { text: "Failure, the contact name was missing!" }
  }};
}

Para mais detalhes sobre como transmitir parâmetros entre caixas de diálogo, consulte Transferir dados para outro card.

Opcional: envie uma mensagem de confirmação pelo chat

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

Para enviar uma nova mensagem, retorne um objeto DataActions com o campo CreateMessageAction definido com a nova mensagem. Por exemplo, para fechar a caixa de diálogo e enviar uma mensagem de texto, retorne o seguinte:

O exemplo a seguir fecha a caixa de diálogo enviando uma nova mensagem:

Node.js

node/chat/contact-form-app/index.js
return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
  text: "✅ " + event.commonEventObject.parameters["contactName"] + " has been added to your contacts."
}}}}};

Python

python/chat/contact-form-app/main.py
return { 'hostAppDataAction': { 'chatDataAction': { 'createMessageAction': { 'message': {
  'text': "✅ " + event.get('commonEventObject').get('parameters')["contactName"] + " has been added to your contacts."
}}}}}

Java

java/chat/contact-form-app/src/main/java/com/google/chat/contact/App.java
return new GenericJson() {{
  put("hostAppDataAction", new GenericJson() {{
    put("chatDataAction", new GenericJson() {{
      put("createMessageAction", new GenericJson() {{
        put("message", new Message()
          .setText( "✅ " + event.at("/commonEventObject/parameters/contactName").asText() +
                    " has been added to your contacts."));
      }});
    }});
  }});
}};

Apps Script

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

apps-script/chat/contact-form-app/Code.gs
return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
  text: "✅ " + event.commonEventObject.parameters["contactName"] + " has been added to your contacts."
}}}}};

Para atualizar uma mensagem depois que o usuário envia uma caixa de diálogo, retorne um objeto DataActions que contenha uma das seguintes ações:

Resolver problemas

Quando um app ou card do Google Chat retorna um erro, a interface do Chat mostra a mensagem "Ocorreu um erro". ou "Não foi possível processar sua solicitação". Às vezes, a interface do Chat não mostra nenhuma mensagem de erro, mas o app ou card do Chat produz um resultado inesperado. Por exemplo, uma mensagem do card pode não aparecer.

Embora uma mensagem de erro não apareça na interface do Chat, mensagens de erro descritivas e dados de registro estão disponíveis para ajudar você a corrigir erros quando o registro de erros para apps do Chat está ativado. Para ajuda com a visualização, depuração e correção de erros, consulte Solucionar e corrigir erros do Google Chat.