Otwórz interaktywne okna

Na tej stronie dowiesz się, jak Twoja aplikacja Google Chat może otwierać okna odpowiadania użytkownikom.

Okna to oparte na kartach okna interfejsy, które otwierają się z poziomu pokoju czatu lub wiadomości. Okno i jego zawartość są widoczne tylko dla użytkownika, który je otworzy.

Aplikacje do obsługi czatu mogą używać okien, aby prosić użytkowników Google Chat o informacje, w tym formularze wieloetapowe, i zbierać od nich informacje. Więcej informacji o przesyłaniu danych wejściowych do formularza znajdziesz w artykule Zbieranie i przetwarzanie informacji od użytkowników.

Wymagania wstępne

Node.js

Aplikacja Google Chat, w której można korzystać z funkcji interaktywnych. Aby utworzyć interaktywną aplikację Google Chat przy użyciu usługi HTTP, wykonaj to krótkie wprowadzenie.

Python

Aplikacja Google Chat, w której włączono funkcje interaktywne. Aby utworzyć interaktywną aplikację Google Chat przy użyciu usługi HTTP, wykonaj to krótkie wprowadzenie.

Java

Aplikacja Google Chat, w której włączono funkcje interaktywne. Aby utworzyć interaktywną aplikację do obsługi czatu przy użyciu usługi HTTP, wykonaj to krótkie wprowadzenie.

Google Apps Script

Aplikacja Google Chat, w której można korzystać z funkcji interaktywnych. Aby utworzyć interaktywną aplikację do obsługi czatu w Apps Script, zapoznaj się z tym krótkim wprowadzeniem.

Otwórz okno

Okno z różnymi różnymi widżetami.
Ilustracja 1. Przykładowa aplikacja Google Chat, która otwiera okno dialogowe do zbierania informacji kontaktowych.

W tej sekcji dowiesz się, jak odpowiadać i konfigurować dialogy:

  1. Wywołanie żądania dialogu w reakcji na interakcję użytkownika.
  2. Zaakceptuj prośbę, wracając do okna i otwierając okno dialogowe.
  3. Gdy użytkownicy prześlą informacje, przetwórz przesłane dane, zamykając okno lub wyświetlając inne okno.

Wywołanie prośby o wyświetlenie okna

Aplikacja Google Chat może otwierać okna dialogowe tylko w odpowiedzi na interakcję użytkownika, taką jak polecenie po ukośniku lub kliknięcie przycisku w wiadomości na karcie.

Aby odpowiedzieć użytkownikom za pomocą dialogu, aplikacja do czatu musi stworzyć interakcję, która uruchamia prośbę o dialog, np.:

Przycisk wywołujący okno
Rys. 2. Aplikacja do obsługi czatu wysyła wiadomość z prośbą o użycie polecenia po ukośniku /addContact.
Wiadomość zawiera również przycisk, który użytkownicy mogą kliknąć, aby wywołać polecenie.

Poniższy przykładowy kod pokazuje, jak wywołać żądanie okna za pomocą przycisku w komunikacie karty. Aby można było otworzyć to okno, pole button.interaction jest ustawione na OPEN_DIALOG:

Node.js

node/contact-form-app/index.js
buttonList: { buttons: [{
  text: "Add Contact",
  onClick: { action: {
    function: "openInitialDialog",
    interaction: "OPEN_DIALOG"
  }}
}]}

Python

python/contact-form-app/main.py
'buttonList': { 'buttons': [{
  'text': "Add Contact",
  'onClick': { 'action': {
    'function': "openInitialDialog",
    'interaction': "OPEN_DIALOG"
  }}
}]}

Java

java/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("openInitialDialog")
    .setInteraction("OPEN_DIALOG"))))))));

Google Apps Script

W tym przykładzie wysłanie wiadomości dotyczącej karty wymaga zwrócenia pliku JSON karty. Możesz też użyć usługi kart Apps Script.

apps-script/contact-form-app/main.gs
buttonList: { buttons: [{
  text: "Add Contact",
  onClick: { action: {
    function: "openInitialDialog",
    interaction: "OPEN_DIALOG"
  }}
}]}

Otwórz pierwsze okno

Gdy użytkownik wywoła żądanie w oknie, Twoja aplikacja do obsługi czatu otrzyma zdarzenie interakcji reprezentowane w interfejsie Chat API jako typ event. Jeśli interakcja powoduje wysłanie żądania dialogu, pole dialogEventType zdarzenia ma wartość REQUEST_DIALOG.

Aby otworzyć okno, aplikacja Google Chat może odpowiedzieć na to żądanie, zwracając obiekt actionResponse z obiektem type ustawionym na DIALOG i Message. Aby określić zawartość okna, użyj tych obiektów:

  • Obiekt actionResponse z wartością type ustawioną na DIALOG.
  • Obiekt dialogAction. Pole body zawiera elementy interfejsu użytkownika, które mają być wyświetlane na karcie, w tym co najmniej 1 widżet sections. Aby zbierać informacje od użytkowników, możesz użyć widżetów formularza i widżetu przycisku. Więcej informacji o projektowaniu pól formularza znajdziesz w artykule Zbieranie i przetwarzanie informacji od użytkowników.

Ten przykładowy kod pokazuje, jak aplikacja do obsługi czatu zwraca odpowiedź otwierającą okno:

Node.js

node/contact-form-app/index.js
/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @return {Object} a message with an action response to open a dialog.
 */
function openInitialDialog() {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { dialog: { body: { sections: [{
      header: "Add new contact",
      widgets: CONTACT_FORM_WIDGETS.concat([{
        buttonList: { buttons: [{
          text: "Review and submit",
          onClick: { action: { function: "openConfirmation" }}
        }]}
      }])
    }]}}}
  }};
}

Python

python/contact-form-app/main.py
def open_initial_dialog() -> dict:
  """Opens the initial step of the dialog that lets users add contact details."""
  return { 'actionResponse': {
    'type': "DIALOG",
    'dialogAction': { 'dialog': { 'body': { 'sections': [{
      'header': "Add new contact",
      'widgets': CONTACT_FORM_WIDGETS + [{
        'buttonList': { 'buttons': [{
          'text': "Review and submit",
          'onClick': { 'action': { 'function': "openConfirmation" }}
        }]}
      }]
    }]}}}
  }}

Java

java/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.
Message openInitialDialog() {
  return new Message().setActionResponse(new ActionResponse()
    .setType("DIALOG")
    .setDialogAction(new DialogAction().setDialog(new Dialog().setBody(new GoogleAppsCardV1Card()
      .setSections(List.of(new GoogleAppsCardV1Section()
        .setHeader("Add new contact")
        .setWidgets(Stream.concat(
          CONTACT_FORM_WIDGETS.stream(),
          List.of(new GoogleAppsCardV1Widget()
            .setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(new GoogleAppsCardV1Button()
            .setText("Review and submit")
            .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
              .setFunction("openConfirmation"))))))).stream()).collect(Collectors.toList()))))))));
}

Google Apps Script

W tym przykładzie wysyłamy wiadomość z karty, zwracając obiekt JSON karty. Możesz też użyć usługi kart Apps Script.

apps-script/contact-form-app/main.gs
/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @return {Object} a message with an action response to open a dialog.
 */
function openInitialDialog() {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { dialog: { body: { sections: [{
      header: "Add new contact",
      widgets: CONTACT_FORM_WIDGETS.concat([{
        buttonList: { buttons: [{
          text: "Review and submit",
          onClick: { action: { function: "openConfirmation" }}
        }]}
      }])
    }]}}}
  }};
}

Obsługa przesyłania okna

Gdy użytkownicy klikają przycisk, który przesyła okno dialogowe, Twoja aplikacja do czatu otrzymuje zdarzenie interakcji CARD_CLICKED, w którym parametr dialogEventTypema wartość SUBMIT_DIALOG.

Aplikacja Google Chat musi obsłużyć zdarzenie interakcji, wykonując jedną z tych czynności:

  • Zwróć kolejne okno, aby wypełnić inną kartę lub formularz.
  • Zamknij okno po zweryfikowaniu danych przesłanych przez użytkownika i opcjonalnie wyślij wiadomość z potwierdzeniem.

Opcjonalnie: zwróć kolejne okno

Gdy użytkownicy prześlą pierwsze okno, aplikacje Google Chat mogą zwrócić jedno lub kilka dodatkowych okien, aby ułatwić użytkownikom przeglądanie informacji przed przesłaniem, wypełnienie wieloetapowych formularzy lub dynamiczne wypełnianie treści formularza.

Aby przetwarzać dane wprowadzane przez użytkowników, aplikacja Chat używa obiektu event.common.formInputs. Więcej informacji o pobieraniu wartości z widżetów z danymi wejściowymi znajdziesz w artykule Zbieranie i przetwarzanie informacji o użytkownikach.

Aby śledzić dane wpisywane przez użytkowników w początkowym oknie, musisz dodać parametry do przycisku otwierającego następne okno. Szczegółowe informacje znajdziesz w artykule Przenoszenie danych na inną kartę.

W tym przykładzie aplikacja Google Chat otwiera pierwsze okno, które prowadzi do drugiego okna z prośbą o potwierdzenie przed przesłaniem:

Node.js

node/contact-form-app/index.js
/**
 * Responds to CARD_CLICKED interaction events in Google Chat.
 *
 * @param {Object} event the CARD_CLICKED interaction event from Google Chat.
 * @return {Object} message responses specific to the dialog handling.
 */
function onCardClick(event) {
  // Initial dialog form page
  if (event.common.invokedFunction === "openInitialDialog") {
    return openInitialDialog();
  // Confirmation dialog form page
  } else if (event.common.invokedFunction === "openConfirmation") {
    return openConfirmation(event);
  // Submission dialog form page
  } else if (event.common.invokedFunction === "submitForm") {
    return submitForm(event);
  }
}

/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @return {Object} a message with an action response to open a dialog.
 */
function openInitialDialog() {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { dialog: { body: { sections: [{
      header: "Add new contact",
      widgets: CONTACT_FORM_WIDGETS.concat([{
        buttonList: { buttons: [{
          text: "Review and submit",
          onClick: { action: { function: "openConfirmation" }}
        }]}
      }])
    }]}}}
  }};
}

/**
 * Returns the second step as a dialog or card message that lets users confirm details.
 *
 * @param {Object} event the interactive event with form inputs.
 * @return {Object} returns a dialog or private card message.
 */
function openConfirmation(event) {
  const name = fetchFormValue(event, "contactName") ?? "";
  const birthdate = fetchFormValue(event, "contactBirthdate") ?? "";
  const type = fetchFormValue(event, "contactType") ?? "";
  const cardConfirmation = {
    header: "Your contact",
    widgets: [{
      textParagraph: { text: "Confirm contact information and submit:" }}, {
      textParagraph: { text: "<b>Name:</b> " + name }}, {
      textParagraph: {
        text: "<b>Birthday:</b> " + convertMillisToDateString(birthdate)
      }}, {
      textParagraph: { text: "<b>Type:</b> " + type }}, {
      buttonList: { buttons: [{
        text: "Submit",
        onClick: { action: {
          function: "submitForm",
          parameters: [{
            key: "contactName", value: name }, {
            key: "contactBirthdate", value: birthdate }, {
            key: "contactType", value: type
          }]
        }}
      }]}
    }]
  };

  // Returns a dialog with contact information that the user input.
  if (event.isDialogEvent) {
    return { action_response: {
      type: "DIALOG",
      dialogAction: { dialog: { body: { sections: [ cardConfirmation ]}}}
    }};
  }

  // Updates existing card message with contact information that the user input.
  return {
    actionResponse: { type: "UPDATE_MESSAGE" },
    privateMessageViewer: event.user,
    cardsV2: [{
      card: { sections: [cardConfirmation]}
    }]
  }
}

Python

python/contact-form-app/main.py
def on_card_click(event: dict) -> dict:
  """Responds to CARD_CLICKED interaction events in Google Chat."""
  # Initial dialog form page
  if "openInitialDialog" == event.get('common').get('invokedFunction'):
    return open_initial_dialog()
  # Confirmation dialog form page
  elif "openConfirmation" == event.get('common').get('invokedFunction'):
    return open_confirmation(event)
  # Submission dialog form page
  elif "submitForm" == event.get('common').get('invokedFunction'):
    return submit_form(event)


def open_initial_dialog() -> dict:
  """Opens the initial step of the dialog that lets users add contact details."""
  return { 'actionResponse': {
    'type': "DIALOG",
    'dialogAction': { 'dialog': { 'body': { 'sections': [{
      'header': "Add new contact",
      'widgets': CONTACT_FORM_WIDGETS + [{
        'buttonList': { 'buttons': [{
          'text': "Review and submit",
          'onClick': { 'action': { 'function': "openConfirmation" }}
        }]}
      }]
    }]}}}
  }}


def open_confirmation(event: dict) -> dict:
  """Returns the second step as a dialog or card message that lets users confirm details."""
  name = fetch_form_value(event, "contactName") or ""
  birthdate = fetch_form_value(event, "contactBirthdate") or ""
  type = fetch_form_value(event, "contactType") or ""
  card_confirmation = {
    'header': "Your contact",
    'widgets': [{
      'textParagraph': { 'text': "Confirm contact information and submit:" }}, {
      'textParagraph': { 'text': "<b>Name:</b> " + name }}, {
      'textParagraph': {
        'text': "<b>Birthday:</b> " + convert_millis_to_date_string(birthdate)
      }}, {
      'textParagraph': { 'text': "<b>Type:</b> " + type }}, {
      'buttonList': { 'buttons': [{
        'text': "Submit",
        'onClick': { 'action': {
          'function': "submitForm",
          'parameters': [{
            'key': "contactName", 'value': name }, {
            'key': "contactBirthdate", 'value': birthdate }, {
            'key': "contactType", 'value': type
          }]
        }}
      }]}
    }]
  }

  # Returns a dialog with contact information that the user input.
  if event.get('isDialogEvent'): 
    return { 'action_response': {
      'type': "DIALOG",
      'dialogAction': { 'dialog': { 'body': { 'sections': [card_confirmation] }}}
    }}

  # Updates existing card message with contact information that the user input.
  return {
    'actionResponse': { 'type': "UPDATE_MESSAGE" },
    'privateMessageViewer': event.get('user'),
    'cardsV2': [{
      'card': { 'sections': [card_confirmation] }
    }]
  }

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
// Responds to CARD_CLICKED interaction events in Google Chat.
Message onCardClick(JsonNode event) {
  String invokedFunction = event.at("/common/invokedFunction").asText();
  // Initial dialog form page
  if ("openInitialDialog".equals(invokedFunction)) {
    return openInitialDialog();
  // Confirmation dialog form page
  } else if ("openConfirmation".equals(invokedFunction)) {
    return openConfirmation(event);
  // Submission dialog form page
  } else if ("submitForm".equals(invokedFunction)) {
    return submitForm(event);
  }
  return null; 
}

// Opens the initial step of the dialog that lets users add contact details.
Message openInitialDialog() {
  return new Message().setActionResponse(new ActionResponse()
    .setType("DIALOG")
    .setDialogAction(new DialogAction().setDialog(new Dialog().setBody(new GoogleAppsCardV1Card()
      .setSections(List.of(new GoogleAppsCardV1Section()
        .setHeader("Add new contact")
        .setWidgets(Stream.concat(
          CONTACT_FORM_WIDGETS.stream(),
          List.of(new GoogleAppsCardV1Widget()
            .setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(new GoogleAppsCardV1Button()
            .setText("Review and submit")
            .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
              .setFunction("openConfirmation"))))))).stream()).collect(Collectors.toList()))))))));
}

// Returns the second step as a dialog or card message that lets users confirm details.
Message openConfirmation(JsonNode event) {
  String name = fetchFormValue(event, "contactName") != null ?
    fetchFormValue(event, "contactName") : "";
  String birthdate = fetchFormValue(event, "contactBirthdate") != null ?
    fetchFormValue(event, "contactBirthdate") : "";
  String type = fetchFormValue(event, "contactType") != null ?
    fetchFormValue(event, "contactType") : "";
  GoogleAppsCardV1Section cardConfirmationSection = new GoogleAppsCardV1Section()
    .setHeader("Your contact")
    .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> " + convertMillisToDateString(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("submitForm")
          .setParameters(List.of(
            new GoogleAppsCardV1ActionParameter().setKey("contactName").setValue(name),
            new GoogleAppsCardV1ActionParameter().setKey("contactBirthdate").setValue(birthdate),
            new GoogleAppsCardV1ActionParameter().setKey("contactType").setValue(type))))))))));

  // Returns a dialog with contact information that the user input.
  if (event.at("/isDialogEvent") != null && event.at("/isDialogEvent").asBoolean()) {
    return new Message().setActionResponse(new ActionResponse()
      .setType("DIALOG")
      .setDialogAction(new DialogAction().setDialog(new Dialog().setBody(new GoogleAppsCardV1Card()
        .setSections(List.of(cardConfirmationSection))))));
  }

  // Updates existing card message with contact information that the user input.
  return new Message()
    .setActionResponse(new ActionResponse()
      .setType("UPDATE_MESSAGE"))
    .setPrivateMessageViewer(new User().setName(event.at("/user/name").asText()))
    .setCardsV2(List.of(new CardWithId().setCard(new GoogleAppsCardV1Card()
      .setSections(List.of(cardConfirmationSection)))));
}

Google Apps Script

W tym przykładzie wysłanie wiadomości dotyczącej karty wymaga zwrócenia pliku JSON karty. Możesz też użyć usługi karty w Apps Script.

apps-script/contact-form-app/main.gs
/**
 * Responds to CARD_CLICKED interaction events in Google Chat.
 *
 * @param {Object} event the CARD_CLICKED interaction event from Google Chat.
 * @return {Object} message responses specific to the dialog handling.
 */
function onCardClick(event) {
  // Initial dialog form page
  if (event.common.invokedFunction === "openInitialDialog") {
    return openInitialDialog();
  // Confirmation dialog form page
  } else if (event.common.invokedFunction === "openConfirmation") {
    return openConfirmation(event);
  // Submission dialog form page
  } else if (event.common.invokedFunction === "submitForm") {
    return submitForm(event);
  }
}

/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @return {Object} a message with an action response to open a dialog.
 */
function openInitialDialog() {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { dialog: { body: { sections: [{
      header: "Add new contact",
      widgets: CONTACT_FORM_WIDGETS.concat([{
        buttonList: { buttons: [{
          text: "Review and submit",
          onClick: { action: { function: "openConfirmation" }}
        }]}
      }])
    }]}}}
  }};
}

/**
 * Returns the second step as a dialog or card message that lets users confirm details.
 *
 * @param {Object} event the interactive event with form inputs.
 * @return {Object} returns a dialog or private card message.
 */
function openConfirmation(event) {
  const name = fetchFormValue(event, "contactName") ?? "";
  const birthdate = fetchFormValue(event, "contactBirthdate") ?? "";
  const type = fetchFormValue(event, "contactType") ?? "";
  const cardConfirmation = {
    header: "Your contact",
    widgets: [{
      textParagraph: { text: "Confirm contact information and submit:" }}, {
      textParagraph: { text: "<b>Name:</b> " + name }}, {
      textParagraph: {
        text: "<b>Birthday:</b> " + convertMillisToDateString(birthdate)
      }}, {
      textParagraph: { text: "<b>Type:</b> " + type }}, {
      buttonList: { buttons: [{
        text: "Submit",
        onClick: { action: {
          function: "submitForm",
          parameters: [{
            key: "contactName", value: name }, {
            key: "contactBirthdate", value: birthdate }, {
            key: "contactType", value: type
          }]
        }}
      }]}
    }]
  };

  // Returns a dialog with contact information that the user input.
  if (event.isDialogEvent) {
    return { action_response: {
      type: "DIALOG",
      dialogAction: { dialog: { body: { sections: [ cardConfirmation ]}}}
    }};
  }

  // Updates existing card message with contact information that the user input.
  return {
    actionResponse: { type: "UPDATE_MESSAGE" },
    privateMessageViewer: event.user,
    cardsV2: [{
      card: { sections: [cardConfirmation]}
    }]
  }
}

Zamknij okno

Gdy użytkownik kliknie przycisk w oknie, aplikacja Google Chat wykona powiązane działanie i dostarczy obiektowi zdarzenia te informacje:

Aplikacja do obsługi czatu powinna zwrócić obiekt ActionResponse z type ustawionym na DIALOG i dialogAction.

Opcjonalnie: wyświetl powiadomienie

Po zamknięciu okna możesz też wyświetlić powiadomienie tekstowe.

Aplikacja Chat może odpowiedzieć pomyślnie lub wyświetlić powiadomienie o błędzie, zwracając obiekt ActionResponse z ustawioną wartością actionStatus.

W tym przykładzie sprawdzamy, czy parametry są prawidłowe, i zamykamy okno z powiadomieniem tekstowym w zależności od wyniku:

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);
  }
}

Google Apps Script

W tym przykładzie wysyłamy wiadomość z karty, zwracając obiekt JSON karty. Możesz też użyć usługi kart 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
    };
  }
}

Szczegółowe informacje o przekazywaniu parametrów między dialogami znajdziesz w artykule Przenoszenie danych na inną kartę.

Opcjonalnie: wyślij wiadomość z potwierdzeniem

Po zamknięciu okna możesz też wysłać nową wiadomość lub zaktualizować istniejącą.

Aby wysłać nową wiadomość, zwróć obiekt ActionResponse z wartością type ustawioną na NEW_MESSAGE. W tym przykładzie dialog kończy się powiadomieniem tekstowym i tekstową wiadomością potwierdzającą:

Node.js

node/contact-form-app/index.js
// The Chat app indicates that it received form data from the dialog or card.
// Sends private text message that confirms submission.
const confirmationMessage = "✅ " + contactName + " has been added to your contacts.";
if (event.dialogEventType === "SUBMIT_DIALOG") {
  return {
    actionResponse: {
      type: "DIALOG",
      dialogAction: { actionStatus: {
        statusCode: "OK",
        userFacingMessage: "Success " + contactName
      }}
    }
  }
} else {
  return {
    actionResponse: { type: "NEW_MESSAGE" },
    privateMessageViewer: event.user,
    text: confirmationMessage
  };
}

Python

python/contact-form-app/main.py
# The Chat app indicates that it received form data from the dialog or card.
# Sends private text message that confirms submission.
confirmation_message = "✅ " + contact_name + " has been added to your contacts.";
if "SUBMIT_DIALOG" == event.get('dialogEventType'):
  return {
    'actionResponse': {
      'type': "DIALOG",
      'dialogAction': { 'actionStatus': {
        'statusCode': "OK",
        'userFacingMessage': "Success " + contact_name
      }}
    }
  }
else:
  return {
    'actionResponse': { 'type': "NEW_MESSAGE" },
    'privateMessageViewer': event.get('user'),
    'text': confirmation_message
  }

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
// The Chat app indicates that it received form data from the dialog or card.
// Sends private text message that confirms submission.
String confirmationMessage = "✅ " + contactName + " has been added to your contacts.";
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("OK")
      .setUserFacingMessage("Success " + contactName))));
} else {
  return new Message()
    .setActionResponse(new ActionResponse().setType("NEW_MESSAGE"))
    .setPrivateMessageViewer(new User().setName(event.at("/user/name").asText()))
    .setText(confirmationMessage);
}

Google Apps Script

W tym przykładzie wysyłamy wiadomość z karty, zwracając obiekt JSON karty. Możesz też użyć usługi kart Apps Script.

apps-script/contact-form-app/main.gs
// The Chat app indicates that it received form data from the dialog or card.
// Sends private text message that confirms submission.
const confirmationMessage = "✅ " + contactName + " has been added to your contacts.";
if (event.dialogEventType === "SUBMIT_DIALOG") {
  return {
    actionResponse: {
      type: "DIALOG",
      dialogAction: { actionStatus: {
        statusCode: "OK",
        userFacingMessage: "Success " + contactName
      }}
    }
  }
} else {
  return {
    actionResponse: { type: "NEW_MESSAGE" },
    privateMessageViewer: event.user,
    text: confirmationMessage
  };
}

Aby zaktualizować wiadomość, zwróć obiekt actionResponse zawierający zaktualizowaną wiadomość i ustaw wartość type na jedną z tych opcji:

Rozwiązywanie problemów

Gdy aplikacja Google Chat lub karta zwraca błąd, interfejs Google Chat wyświetla komunikat „Coś poszło nie tak”. lub „Nie udało się przetworzyć Twojej prośby”. Czasami w UI Google Chat nie wyświetla się żaden komunikat o błędzie, ale aplikacja lub karta Google Chat zwraca nieoczekiwany wynik, na przykład wiadomość na karcie.

Mimo że komunikat o błędzie może nie być wyświetlany w interfejsie Google Chat, są dostępne opisowe komunikaty o błędach i dane logów, które pomogą Ci w naprawianiu błędów, gdy logowanie błędów w aplikacjach Google Chat jest włączone. Informacje o wyświetlaniu, debugowaniu i naprawianiu błędów znajdziesz w artykule Rozwiązywanie problemów z błędami w Google Chat.