Informationen von Google Chat-Nutzern erheben und verarbeiten

In dieser Anleitung wird beschrieben, wie Google Chat-Apps Informationen von Nutzern erfassen und verarbeiten können, indem sie Formulareingaben in kartenbasierten Oberflächen erstellen.

Ein Dialogfeld mit verschiedenen Widgets.
Abbildung 1: Eine Beispiel-Chat-App, die ein Dialogfeld zum Erfassen von Kontaktinformationen öffnet.

Chat-Apps fordern Informationen von Nutzern an, um Aktionen in oder außerhalb von Google Chat auszuführen. Das kann auf folgende Weise geschehen:

  • Konfigurieren Sie die Einstellungen. So können Nutzer beispielsweise Benachrichtigungseinstellungen anpassen oder die Chat-App konfigurieren und einem oder mehreren Bereichen hinzufügen.
  • Informationen in anderen Google Workspace-Anwendungen erstellen oder aktualisieren Nutzer können beispielsweise einen Termin in Google Kalender erstellen.
  • Nutzern erlauben, auf Ressourcen in anderen Apps oder Webservices zuzugreifen und diese zu aktualisieren. Eine Chat-App kann Nutzern beispielsweise helfen, den Status eines Support-Tickets direkt über einen Chat-Gruppenbereich zu aktualisieren.

Vorbereitung

HTTP

Eine Google Chat-App, die Nutzerinteraktionen empfängt und darauf reagiert. Kurzanleitung für HTTP

Apps Script

Eine Google Chat-App, die Nutzerinteraktionen empfängt und darauf reagiert. Apps Script-Kurzanleitung

Formulare mit Karten erstellen

Zum Erfassen von Informationen werden in Chat-Apps Formulare und ihre Eingaben entworfen und in Karten eingebunden. Chat-Apps können die folgenden Chat-Oberflächen verwenden, um Karten für Nutzer anzuzeigen:

  • Nachrichten, die eine oder mehrere Karten enthalten.
  • Startseiten: Das ist eine Karte, die auf dem Tab Startseite in Direktnachrichten mit der Chat-App angezeigt wird.
  • Dialogfelder: Das sind Karten, die in einem neuen Fenster über Nachrichten und Startseiten geöffnet werden.

Chat-Apps können die Karten mit den folgenden Widgets erstellen:

  • Formulareingabe-Widgets, in denen Nutzer um Informationen gebeten werden. Optional können Sie Formulareingabe-Widgets validieren, um sicherzustellen, dass Nutzer Informationen korrekt eingeben und formatieren. Chat-Apps können die folgenden Formulareingabe-Widgets verwenden:

    • Texteingaben (textInput) für Freiformtext oder vorgeschlagenen Text.
    • Auswahleeingaben (selectionInput) sind auswählbare UI-Elemente wie Kästchen, Optionsfelder und Drop-down-Menüs. Auswahl-Widgets können auch Elemente aus Google Workspace-Daten (z. B. einen Chat-Gruppenbereich) oder einer dynamischen Datenquelle vorschlagen. Weitere Informationen finden Sie in den Abschnitten Drop-down-Menü hinzufügen und Mehrfachauswahlmenü hinzufügen.
    • Datumsauswahl (dateTimePicker) für Datums- und Zeiteinträge.
  • Ein Schaltflächen-Widget, damit Nutzer Werte senden können, die sie auf der Karte eingegeben haben. Nachdem ein Nutzer auf den Button geklickt hat, kann die Chat-App die empfangenen Informationen verarbeiten.

Im folgenden Beispiel werden auf einer Karte Kontaktinformationen mithilfe einer Texteingabe, einer Auswahl für Datum und Uhrzeit und einer Auswahl eingeholt:

Weitere Beispiele für interaktive Widgets, mit denen Sie Informationen erfassen können, finden Sie unter Interaktive Karte oder interaktiven Dialog gestalten.

Drop-down-Menü hinzufügen

Wenn Sie Auswahlmöglichkeiten anpassen oder Nutzern erlauben möchten, ein einzelnes Element aus einer dynamischen Datenquelle auszuwählen, können Chat-Apps Drop-down-Menüs verwenden. Diese sind eine Art von SelectionInput-Widget. Die folgende Karte enthält beispielsweise ein Drop-down-Menü, in dem Nutzer dynamisch aus einer Liste von Kontakten auswählen können:

Sie können Elemente für ein Drop-down-Menü aus den folgenden Datenquellen abrufen:

Elemente aus einer Google Workspace-Datenquelle einfügen

Wenn Sie Elemente aus Google Workspace-Datenquellen wie Google Workspace-Nutzern abrufen möchten, geben Sie das Feld platformDataSource in einem DataSourceConfig-Objekt an. Im Gegensatz zu anderen Auswahl-Eingabetypen lassen Sie SelectionItem-Objekte weg, da diese Auswahl-Elemente dynamisch aus Google Workspace stammen.

Der folgende Code zeigt ein Drop-down-Menü mit Google Workspace-Nutzern:

JSON

{
  "sections": [
    {
      "header": "Section Header",
      "widgets": [
        {
          "selectionInput": {
            "name": "contacts",
            "type": "DROPDOWN",
            "label": "Select contact from organization",
            "data_source_configs": [
              {
                "platformDataSource": {
                  "commonDataSource": "USER"
                },
                "min_characters_trigger": 1
              }
            ]
          }
        }
      ]
    }
  ]
}

Elemente aus einer externen Datenquelle einfügen

Drop-down-Menüs können auch Elemente aus einer Drittanbieter- oder externen Datenquelle enthalten. Wenn Sie eine externe Datenquelle verwenden möchten, geben Sie das Feld remoteDataSource in einem DataSourceConfig-Objekt an, das die Funktion enthält, mit der Elemente aus der Datenquelle abgefragt und zurückgegeben werden.

Um die Anzahl der Anfragen an eine externe Datenquelle zu reduzieren, können Sie vorgeschlagene Elemente einfügen, die im Drop-down-Menü angezeigt werden, bevor Nutzer etwas eingeben. Wenn Sie Vorschläge aus einer externen Datenquelle generieren möchten, geben Sie statische SelectionItem-Objekte an.

Im folgenden Code wird ein Drop-down-Menü gezeigt, in dem Elemente aus einer externen Datenquelle abgefragt und eingefügt werden:

JSON

{
  "sections": [
    {
      "header": "Section Header",
      "widgets": [
        {
          "selectionInput": {
            "name": "crm_leads",
            "type": "DROPDOWN",
            "label": "Select CRM Lead",
            "data_source_configs": [
              {
                "remoteDataSource": {
                  "function": "getCrmLeads"
                },
                "min_characters_trigger": 2
              }
            ],
            "items": [
              {
                "text": "Suggested Lead 1",
                "value": "lead-1"
              }
            ]
          }
        }
      ]
    }
  ]
}

Ein vollständiges Beispiel, das zeigt, wie vorgeschlagene Elemente zurückgegeben werden, finden Sie im Abschnitt Auswahlelemente vorschlagen.

Multiselect-Menü hinzufügen

Wenn Sie Auswahlmöglichkeiten anpassen oder Nutzern erlauben möchten, Elemente aus einer dynamischen Datenquelle auszuwählen, können Chat-Apps Multiselect-Menüs verwenden. Diese sind eine Art von SelectionInput-Widget. Die folgende Karte enthält beispielsweise ein Menü mit Mehrfachauswahl, in dem Nutzer dynamisch aus einer Liste von Kontakten auswählen können:

Sie können Elemente für ein Mehrfachauswahlmenü aus den folgenden Datenquellen abrufen:

  • Google Workspace-Daten, einschließlich Nutzer oder Chatbereiche, in denen der Nutzer Mitglied ist. Im Menü werden nur Elemente aus derselben Google Workspace-Organisation angezeigt.
  • Externe Datenquellen, z. B. eine relationale Datenbank. Sie können beispielsweise Mehrfachauswahlmenüs verwenden, damit ein Nutzer aus einer Liste von Vertriebs-Leads aus einem CRM-System (Customer Relationship Management) auswählen kann.

Elemente aus einer Google Workspace-Datenquelle einfügen

Wenn Sie Google Workspace-Datenquellen verwenden möchten, geben Sie das Feld platformDataSource im SelectionInput-Widget an. Im Gegensatz zu anderen Auswahl-Eingabetypen lassen Sie SelectionItem-Objekte weg, da diese Auswahl-Elemente dynamisch aus Google Workspace stammen.

Im folgenden Code sehen Sie ein Menü mit Mehrfachauswahl für Google Workspace-Nutzer. Um Nutzer zu erfassen, wird durch die Auswahl von commonDataSource der Wert USER festgelegt:

JSON

{
  "selectionInput": {
    "name": "contacts",
    "type": "MULTI_SELECT",
    "label": "Selected contacts",
    "multiSelectMaxSelectedItems": 5,
    "multiSelectMinQueryLength": 1,
    "platformDataSource": {
      "commonDataSource": "USER"
    }
  }
}

Der folgende Code zeigt ein Mehrfachauswahlmenü mit Chatbereichen. Zum Ausfüllen von Leerzeichen wird im Auswahl-Input das Feld hostAppDataSource angegeben. Im Menü für die Mehrfachauswahl wird auch defaultToCurrentSpace auf true gesetzt. Dadurch wird der aktuelle Bereich zur Standardauswahl im Menü:

JSON

{
  "selectionInput": {
    "name": "spaces",
    "type": "MULTI_SELECT",
    "label": "Selected contacts",
    "multiSelectMaxSelectedItems": 3,
    "multiSelectMinQueryLength": 1,
    "platformDataSource": {
      "hostAppDataSource": {
        "chatDataSource": {
          "spaceDataSource": {
            "defaultToCurrentSpace": true
          }
        }
      }
    }
  }
}

Elemente aus einer externen Datenquelle einfügen

In Menüs mit Mehrfachauswahl können auch Elemente aus einer Drittanbieter- oder externen Datenquelle eingefügt werden. Wenn Sie eine externe Datenquelle verwenden möchten, geben Sie das Feld externalDataSource im Widget SelectionInput an, das die Funktion enthält, mit der Elemente aus der Datenquelle abgefragt und zurückgegeben werden.

Um die Anzahl der Anfragen an eine externe Datenquelle zu reduzieren, können Sie vorgeschlagene Elemente einfügen, die im Mehrfachauswahlmenü angezeigt werden, bevor Nutzer etwas eingeben. Sie können beispielsweise Kontakte, nach denen der Nutzer vor Kurzem gesucht hat, automatisch ausfüllen. Wenn Sie Vorschläge aus einer externen Datenquelle generieren möchten, geben Sie statische SelectionItem-Objekte an.

Das folgende Codebeispiel zeigt ein Menü mit Mehrfachauswahl, in dem Elemente aus einer externen Datenquelle abgefragt und eingefügt werden:

Node.js

node/chat/selection-input/index.js
selectionInput: {
  name: "contacts",
  type: "MULTI_SELECT",
  label: "Selected contacts",
  multiSelectMaxSelectedItems: 3,
  multiSelectMinQueryLength: 1,
  externalDataSource: { function: FUNCTION_URL },
  // Suggested items loaded by default.
  // The list is static here but it could be dynamic.
  items: [getSuggestedContact("3")]
}

Ersetzen Sie FUNCTION_URL durch den HTTP-Endpunkt, mit dem die externe Datenquelle abgefragt wird.

Python

python/chat/selection-input/main.py
'selectionInput': {
  'name': "contacts",
  'type': "MULTI_SELECT",
  'label': "Selected contacts",
  'multiSelectMaxSelectedItems': 3,
  'multiSelectMinQueryLength': 1,
  'externalDataSource': { 'function': FUNCTION_URL },
  # Suggested items loaded by default.
  # The list is static here but it could be dynamic.
  'items': [get_suggested_contact("3")]
}

Ersetzen Sie FUNCTION_URL durch den HTTP-Endpunkt, mit dem die externe Datenquelle abgefragt wird.

Java

java/chat/selection-input/src/main/java/com/google/chat/selectionInput/App.java
.setSelectionInput(new GoogleAppsCardV1SelectionInput()
  .setName("contacts")
  .setType("MULTI_SELECT")
  .setLabel("Selected contacts")
  .setMultiSelectMaxSelectedItems(3)
  .setMultiSelectMinQueryLength(1)
  .setExternalDataSource(new GoogleAppsCardV1Action().setFunction(FUNCTION_URL))
  // Suggested items loaded by default.
  // The list is static here but it could be dynamic.
  .setItems(List.of(getSuggestedContact("3")))))))))));

Ersetzen Sie FUNCTION_URL durch den HTTP-Endpunkt, mit dem die externe Datenquelle abgefragt wird.

Apps Script

In diesem Beispiel wird eine Kartenmitteilung gesendet, indem Karten-JSON zurückgegeben wird. Sie können auch den Apps Script-Kartendienst verwenden.

apps-script/chat/selection-input/selection-input.gs
selectionInput: {
  name: "contacts",
  type: "MULTI_SELECT",
  label: "Selected contacts",
  multiSelectMaxSelectedItems: 3,
  multiSelectMinQueryLength: 1,
  externalDataSource: { function: "queryContacts" },
  // Suggested items loaded by default.
  // The list is static here but it could be dynamic.
  items: [getSuggestedContact("3")]
}

Ein vollständiges Beispiel, das zeigt, wie vorgeschlagene Elemente zurückgegeben werden, finden Sie im Abschnitt Auswahlelemente vorschlagen.

Daten von interaktiven Widgets empfangen

Wenn Nutzer auf eine Schaltfläche klicken, wird die Aktion der entsprechenden Chat-App mit Informationen zur Interaktion ausgelöst. Im commonEventObject der Ereignisnutzlast enthält das formInputs-Objekt alle Werte, die der Nutzer eingibt.

Sie können die Werte aus dem Objekt event.commonEventObject.formInputs.WIDGET_NAME abrufen, wobei WIDGET_NAME das Feld name ist, das Sie für das Widget angegeben haben. Die Werte werden als bestimmter Datentyp für das Widget zurückgegeben.

Im Folgenden sehen Sie einen Teil eines Ereignisobjekts, in dem ein Nutzer Werte für jedes Widget eingegeben hat:

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

Damit Ihre Chat-App die Daten empfangen kann, muss sie das Ereignisobjekt verarbeiten, um die Werte abzurufen, die Nutzer in Widgets eingeben. In der folgenden Tabelle sehen Sie, wie Sie den Wert für ein bestimmtes Formulareingabe-Widget abrufen. In der Tabelle wird für jedes Widget der Datentyp angezeigt, den das Widget akzeptiert, wo der Wert im Ereignisobjekt gespeichert ist, sowie ein Beispielwert.

Formular-Eingabe-Widget Art der Eingabedaten Eingabewert aus dem Ereignisobjekt Beispielwert
textInput stringInputs event.commonEventObject.formInputs.contactName.stringInputs.value[0] Kai O
selectionInput stringInputs So rufen Sie den ersten oder einzigen Wert ab: event.commonEventObject.formInputs.contactType.stringInputs.value[0] Personal
dateTimePicker, in das nur Datumsangaben eingegeben werden können. dateInput event.commonEventObject.formInputs.contactBirthdate.dateInput.msSinceEpoch. 1000425600000

Nachdem die Chat-App Daten empfangen hat, kann sie Folgendes tun:

Auswahlmöglichkeiten vorschlagen

Wenn eine Karte ein Mehrfachauswahlmenü oder ein Drop-down-Menü enthält, in dem Elemente aus einer externen Datenquelle eingefügt werden, kann die Chat-App Vorschläge zurückgeben, die auf den Eingaben der Nutzer im Menü basieren. Wenn ein Nutzer beispielsweise mit der Eingabe von Atl für ein Menü beginnt, in dem Städte in den USA angezeigt werden, kann Ihre Chat-App Atlanta automatisch vorschlagen, bevor der Nutzer die Eingabe abgeschlossen hat. Die Chat-App kann bis zu 100 Artikel vorschlagen.

Damit Elemente in einer Auswahl-Eingabe vorgeschlagen und dynamisch eingefügt werden können, muss im SelectionInput-Widget auf der Karte eine Funktion angegeben werden, mit der die externe Datenquelle abgefragt wird. Bei Menüs mit Mehrfachauswahl geben Sie das Feld externalDataSource an. Bei Drop-down-Menüs geben Sie das Feld remoteDataSource in einem DataSourceConfig-Objekt an.

Sie können auch die Anzahl der Zeichen konfigurieren, die ein Nutzer eingeben muss, bevor im Menü Vorschläge angezeigt werden. Legen Sie für Menüs mit Mehrfachauswahl das Feld multiSelectMinQueryLength fest. Legen Sie für Drop-down-Menüs das Feld min_characters_trigger innerhalb von DataSourceConfig fest.

Damit vorgeschlagene Elemente zurückgegeben werden, muss die Funktion Folgendes ausführen:

  1. Verarbeiten Sie ein Ereignisobjekt, das die Chat-App empfängt, wenn Nutzer in das Menü eingeben.
  2. Rufen Sie aus dem Ereignisobjekt den Wert ab, den der Nutzer eingibt. Er wird im Feld event.commonEventObject.parameters["autocomplete_widget_query"] dargestellt.
  3. Fragen Sie die Datenquelle mit dem Nutzereingabewert ab, um ein oder mehrere SelectionItems zu erhalten, die dem Nutzer vorgeschlagen werden können.
  4. Geben Sie vorgeschlagene Elemente zurück, indem Sie die Aktion RenderActions mit einem modifyCard-Objekt zurückgeben.

Das folgende Codebeispiel zeigt, wie eine Chat-App Elemente im Mehrfachauswahlmenü auf einer Karte dynamisch vorschlägt. Wenn ein Nutzer etwas in das Menü eingibt, wird mit der Funktion oder dem Endpunkt, der im Feld externalDataSource des Widgets angegeben ist, eine externe Datenquelle abgefragt und es werden Elemente vorgeschlagen, die der Nutzer auswählen kann.

Node.js

node/chat/selection-input/index.js
/**
 * Web app that responds to events sent from a Google Chat space.
 *
 * @param {Object} req Request sent from Google Chat space
 * @param {Object} res Response to send back
 */
app.post('/', async (req, res) => {
  // Stores the Google Chat event
  const chatEvent = req.body.chat;

  // Handle user interaction with multiselect.
  if(chatEvent.widgetUpdatedPayload) {
    return res.json(queryContacts(req.body));
  }

  // Replies with a card that contains the multiselect menu.
  return res.json({ hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    cardsV2: [{
      cardId: "contactSelector",
      card: { sections:[{ widgets: [{
        selectionInput: {
          name: "contacts",
          type: "MULTI_SELECT",
          label: "Selected contacts",
          multiSelectMaxSelectedItems: 3,
          multiSelectMinQueryLength: 1,
          externalDataSource: { function: FUNCTION_URL },
          // Suggested items loaded by default.
          // The list is static here but it could be dynamic.
          items: [getSuggestedContact("3")]
        }
      }]}]}
    }]
  }}}}});
});

/**
 * Get contact suggestions based on text typed by users.
 *
 * @param {Object} event the event object that contains the user's query
 * @return {Object} suggestions
 */
function queryContacts(event) {
  const query = event.commonEventObject.parameters["autocomplete_widget_query"];
  return { action: { modifyOperations: [{ updateWidget: { selectionInputWidgetSuggestions: { suggestions: [
    // The list is static here but it could be dynamic.
    getSuggestedContact("1"), getSuggestedContact("2"), getSuggestedContact("3"), getSuggestedContact("4"), getSuggestedContact("5")
  // Only return items based on the query from the user.
  ].filter(e => !query || e.text.includes(query)) }}}]}};
}

/**
 * Generate a suggested contact given an ID.
 *
 * @param {String} id The ID of the contact to return.
 * @return {Object} The contact formatted as a selection item in the menu.
 */
function getSuggestedContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}

Ersetzen Sie FUNCTION_URL durch den HTTP-Endpunkt, mit dem die externe Datenquelle abgefragt wird.

Python

python/chat/selection-input/main.py
@app.route('/', methods=['POST'])
def post() -> Mapping[str, Any]:
  """Handle requests from Google Chat

  Returns:
      Mapping[str, Any]: The response
  """
  # Stores the Google Chat event
  chatEvent = request.get_json().get('chat')

  # Handle user interaction with multiselect.
  if chatEvent.get('widgetUpdatedPayload') is not None:
    return json.jsonify(query_contacts(request.get_json()))

  # Replies with a card that contains the multiselect menu.
  return json.jsonify({ 'hostAppDataAction': { 'chatDataAction': { 'createMessageAction': {
    'message': { 'cardsV2': [{
      'cardId': "contactSelector",
      'card': { 'sections':[{ 'widgets': [{
        'selectionInput': {
          'name': "contacts",
          'type': "MULTI_SELECT",
          'label': "Selected contacts",
          'multiSelectMaxSelectedItems': 3,
          'multiSelectMinQueryLength': 1,
          'externalDataSource': { 'function': FUNCTION_URL },
          # Suggested items loaded by default.
          # The list is static here but it could be dynamic.
          'items': [get_suggested_contact("3")]
        }
      }]}]}
    }]}
  }}}})


def query_contacts(event: dict) -> dict:
  """Get contact suggestions based on text typed by users.

  Args:
      event (Mapping[str, Any]): The event object that contains the user's query

  Returns:
      Mapping[str, Any]: The response with contact suggestions.
  """
  query = event.get("commonEventObject").get("parameters").get("autocomplete_widget_query")
  return { 'action': { 'modifyOperations': [{ 'updateWidget': { 'selectionInputWidgetSuggestions': { 'suggestions': list(
    filter(lambda e: query is None or query in e["text"], [
      # The list is static here but it could be dynamic.
      get_suggested_contact("1"), get_suggested_contact("2"), get_suggested_contact("3"), get_suggested_contact("4"), get_suggested_contact("5")
    # Only return items based on the query from the user
    ])
  )}}}]}}


def get_suggested_contact(id: str) -> dict:
  """Generate a suggested contact given an ID.

  Args:
      id (str): The ID of the contact to return.

  Returns:
      Mapping[str, Any]: The contact formatted as a selection item in the menu.
  """
  return {
    'value': id,
    'startIconUri': "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    'text': "Contact " + id
  }

Ersetzen Sie FUNCTION_URL durch den HTTP-Endpunkt, mit dem die externe Datenquelle abgefragt wird.

Java

java/chat/selection-input/src/main/java/com/google/chat/selectionInput/App.java
@SpringBootApplication
@RestController
// Web app that responds to events sent from a Google Chat space.
public class App {
  private static final String FUNCTION_URL = "your-function-url";

  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
  }

  /**
   * Handle requests from Google Chat
   * 
   * @param event the event object sent by Google Chat
   * @return The response to be sent back to Google Chat
   */
  @PostMapping("/")
  @ResponseBody
  public GenericJson onEvent(@RequestBody JsonNode event) throws Exception {
    // Stores the Google Chat event
    JsonNode chatEvent = event.at("/chat");

    // Handle user interaction with multiselect.
    if (!chatEvent.at("/widgetUpdatedPayload").isEmpty()) {
      return queryContacts(event);
    }

    // Replies with a card that contains the multiselect menu.
    Message message = new Message().setCardsV2(List.of(new CardWithId()
      .setCardId("contactSelector")
      .setCard(new GoogleAppsCardV1Card()
        .setSections(List.of(new GoogleAppsCardV1Section().setWidgets(List.of(new GoogleAppsCardV1Widget()
          .setSelectionInput(new GoogleAppsCardV1SelectionInput()
            .setName("contacts")
            .setType("MULTI_SELECT")
            .setLabel("Selected contacts")
            .setMultiSelectMaxSelectedItems(3)
            .setMultiSelectMinQueryLength(1)
            .setExternalDataSource(new GoogleAppsCardV1Action().setFunction(FUNCTION_URL))
            // Suggested items loaded by default.
            // The list is static here but it could be dynamic.
            .setItems(List.of(getSuggestedContact("3")))))))))));

    return new GenericJson() {{
      put("hostAppDataAction", new GenericJson() {{
        put("chatDataAction", new GenericJson() {{
          put("createMessageAction", new GenericJson() {{
            put("message", message);
          }});
        }});
      }});
    }};
  }

  /**
   * Get contact suggestions based on text typed by users.
   *
   * @param event the event object that contains the user's query.
   * @return The response with contact suggestions.
   */
  GenericJson queryContacts(JsonNode event) throws Exception {
    String query = event.at("/commonEventObject/parameters/autocomplete_widget_query").asText();
    List<GoogleAppsCardV1SelectionItem> suggestions = List.of(
      // The list is static here but it could be dynamic.
      getSuggestedContact("1"), getSuggestedContact("2"), getSuggestedContact("3"), getSuggestedContact("4"), getSuggestedContact("5")
    // Only return items based on the query from the user
    ).stream().filter(e -> query == null || e.getText().indexOf(query) > -1).toList();

    return new GenericJson() {{
      put("action", new GenericJson() {{
        put("modifyOperations", List.of(new GenericJson() {{
          put("updateWidget", new GenericJson() {{
            put("selectionInputWidgetSuggestions", new GenericJson() {{
              put("suggestions", suggestions);
            }});
          }});
        }}));
      }});
    }};
  }

  /**
   * Generate a suggested contact given an ID.
   * 
   * @param id The ID of the contact to return.
   * @return The contact formatted as a selection item in the menu.
   */
  GoogleAppsCardV1SelectionItem getSuggestedContact(String id) {
    return new GoogleAppsCardV1SelectionItem()
      .setValue(id)
      .setStartIconUri("https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png")
      .setText("Contact " + id);
  }
}

Ersetzen Sie FUNCTION_URL durch den HTTP-Endpunkt, mit dem die externe Datenquelle abgefragt wird.

Apps Script

In diesem Beispiel wird eine Kartenmitteilung gesendet, indem Karten-JSON zurückgegeben wird. Sie können auch den Apps Script-Kartendienst verwenden.

apps-script/chat/selection-input/selection-input.gs
/**
* Responds to a Message trigger in Google Chat.
*
* @param {Object} event the event object from Google Chat
* @return {Object} Response from the Chat app.
*/
function onMessage(event) {
  // Replies with a card that contains the multiselect menu.
  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    cardsV2: [{
      cardId: "contactSelector",
      card: { sections:[{ widgets: [{
        selectionInput: {
          name: "contacts",
          type: "MULTI_SELECT",
          label: "Selected contacts",
          multiSelectMaxSelectedItems: 3,
          multiSelectMinQueryLength: 1,
          externalDataSource: { function: "queryContacts" },
          // Suggested items loaded by default.
          // The list is static here but it could be dynamic.
          items: [getSuggestedContact("3")]
        }
      }]}]}
    }]
  }}}}};
}

/**
* Get contact suggestions based on text typed by users.
*
* @param {Object} event the event object that contains the user's query
* @return {Object} suggestions
*/
function queryContacts(event) {
  const query = event.commonEventObject.parameters["autocomplete_widget_query"];
  return { action: { modifyOperations: [{ updateWidget: { selectionInputWidgetSuggestions: { suggestions: [
    // The list is static here but it could be dynamic.
    getSuggestedContact("1"), getSuggestedContact("2"), getSuggestedContact("3"), getSuggestedContact("4"), getSuggestedContact("5")
  // Only return items based on the query from the user.
  ].filter(e => !query || e.text.includes(query)) }}}]}};
}

/**
* Generate a suggested contact given an ID.
*
* @param {String} id The ID of the contact to return.
* @return {Object} The contact formatted as a selection item in the menu.
*/
function getSuggestedContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}

Daten auf eine andere Karte übertragen

Nachdem ein Nutzer Informationen von einer Karte gesendet hat, müssen Sie möglicherweise zusätzliche Karten zurückgeben, um Folgendes zu tun:

  • Nutzer beim Ausfüllen längerer Formulare unterstützen, indem Sie separate Abschnitte erstellen
  • Lassen Sie Nutzer Informationen aus der ersten Karte in der Vorschau ansehen und bestätigen, damit sie ihre Antworten vor dem Senden überprüfen können.
  • Die restlichen Teile des Formulars werden dynamisch ausgefüllt. Wenn Nutzer beispielsweise aufgefordert werden sollen, einen Termin zu erstellen, kann eine Chat-App eine erste Karte mit der Frage nach dem Grund für den Termin anzeigen und dann eine weitere Karte mit verfügbaren Zeiten basierend auf dem Termin typ einblenden.

Wenn Sie die Dateneingabe von der ursprünglichen Karte übertragen möchten, können Sie das button-Widget mit actionParameters erstellen, das die name des Widgets und den vom Nutzer eingegebenen Wert enthält, wie im folgenden Beispiel gezeigt:

Node.js

node/chat/contact-form-app/index.js
{ 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 }
    ]
  }}
}]}}

Ersetzen Sie FUNCTION_URL durch den HTTP-Endpunkt, der die Schaltflächenklicks verarbeitet.

Python

python/chat/contact-form-app/main.py
{ '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 }
    ]
  }}
}]}}

Ersetzen Sie FUNCTION_URL durch den HTTP-Endpunkt, der die Schaltflächenklicks verarbeitet.

Java

java/chat/contact-form-app/src/main/java/com/google/chat/contact/App.java
new GoogleAppsCardV1Widget().setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(
  new GoogleAppsCardV1Button()
    .setText("SUBMIT")
    .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
      .setFunction(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))))))))))));

Ersetzen Sie FUNCTION_URL durch den HTTP-Endpunkt, der die Schaltflächenklicks verarbeitet.

Apps Script

In diesem Beispiel wird eine Kartenmitteilung gesendet, indem Karten-JSON zurückgegeben wird. Sie können auch den Apps Script-Kartendienst verwenden.

apps-script/chat/contact-form-app/Code.gs
{ 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 }
    ]
  }}
}]}}

Wenn ein Nutzer auf die Schaltfläche klickt, empfängt Ihre Chat-App ein Ereignisobjekt, aus dem Sie Daten abrufen können.

Auf eine Formulareinsendung reagieren

Nachdem die Chat-App die Daten aus einer Kartenmitteilung oder einem Dialogfeld erhalten hat, antwortet sie entweder mit einer Empfangsbestätigung oder gibt einen Fehler zurück.

Im folgenden Beispiel sendet eine Chat-App eine SMS, um zu bestätigen, dass sie ein über eine Kartenmitteilung gesendetes Formular erfolgreich empfangen hat.

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

In diesem Beispiel wird eine Kartenmitteilung gesendet, indem Karten-JSON zurückgegeben wird. Sie können auch den Apps Script-Kartendienst verwenden.

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

Um ein Dialogfeld zu verarbeiten und zu schließen, geben Sie ein RenderActions-Objekt zurück, das angibt, ob Sie eine Bestätigungsnachricht senden, die ursprüngliche Nachricht oder Karte aktualisieren oder das Dialogfeld einfach schließen möchten. Eine Anleitung finden Sie unter Dialogfeld schließen.

Fehlerbehebung

In diesem Abschnitt finden Sie Schritte zur Fehlerbehebung für bestimmte Fehlercodes und Laufzeitverhalten bei der Interaktion mit Dialogfeldern in Chat.

Bei Dialoginteraktionen wird „Unbekannter Fehler beim Aufrufen des Add-ons“ zurückgegeben

Wenn Sie mit einem Dialogfeld interagieren und Fehlermeldungen mit der Meldung „Unspecified error invoking the add-on.“ und dem Code 13 sehen, deutet dies in der Regel auf einen internen Fehler hin oder darauf, dass der HTTP-Endpunkt der Chat-App die Anfrage nicht verarbeiten oder eine gültige Antwort zurückgeben konnte.

So beheben Sie diesen Fehler:

  • Prüfen Sie die Protokolle Ihres HTTP-Endpunkts auf nicht behandelte Ausnahmen oder Abstürze.
  • Prüfen Sie, ob Ihr Endpunkt innerhalb von 30 Sekunden auf Anfragen antwortet. Wenn die Ausführung des Endpunkts länger als 30 Sekunden dauert, kann Chat die Antwort nicht verarbeiten und die Interaktion schlägt fehl. Weitere Informationen finden Sie unter Ratenbeschränkungen und Best Practices.
  • Achten Sie darauf, dass Ihr Endpunkt eine gültige Antwort zurückgibt. Bei Dialogübermittlungen muss der Endpunkt ein RenderActions-Objekt im korrekten JSON-Format zurückgeben. Wenn die Antwort fehlerhaft ist oder erforderliche Felder fehlen, kann die Dialoginteraktion fehlschlagen.

Wenn eine Google Chat-App oder Karte einen Fehler zurückgibt, wird in der Chat-Oberfläche die Meldung „Ein Fehler ist aufgetreten“ angezeigt. oder „Ihre Anfrage kann nicht bearbeitet werden“. Manchmal wird in der Chat-Benutzeroberfläche keine Fehlermeldung angezeigt, aber die Chat-App oder ‑Karte liefert ein unerwartetes Ergebnis, z. B. wird eine Kartenmeldung nicht angezeigt.

Auch wenn in der Chat-Benutzeroberfläche keine Fehlermeldung angezeigt wird, sind beschreibende Fehlermeldungen und Protokolldaten verfügbar, die Ihnen helfen, Fehler zu beheben, wenn die Fehlerprotokollierung für Chat-Apps aktiviert ist. Informationen zum Ansehen, Debuggen und Beheben von Fehlern finden Sie unter Google Chat-Fehler beheben.

Chat-Apps, die keine Add‑ons sind: Von Nutzern auf Karten eingegebene Formulardaten lesen

Die folgende Dokumentation gilt für Chat-Apps, die keine Google Workspace-Add‑ons sind. Wenn Sie eine Google Chat-App migrieren möchten, die kein Add‑on ist, lesen Sie den Hilfeartikel Google Chat-App in ein Google Workspace-Add‑on umwandeln.

Formulare mit Karten erstellen

Ein Beispiel für eine Chat-App, die kein Add-on ist und ein Kontaktformular mit einer Texteingabe, einer Auswahl für Datum und Uhrzeit und einer Auswahl verwendet, finden Sie im folgenden Code:

Node.js

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

Python

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

Java

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

Apps Script

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

Daten von interaktiven Widgets empfangen

Wenn Nutzer auf eine Schaltfläche klicken, erhalten Chat-Apps, die keine Add-ons sind, ein Interaktionsereignis, das vom Speicherort der Schaltfläche abhängt:

  • Wenn sich der Button in einer Nachricht oder einem Dialogfeld befindet, erhalten Chat-Apps, die keine Add-ons sind, ein CARD_CLICKED-Interaktionsereignis mit Informationen zur Interaktion. Die Nutzlast von CARD_CLICKED-Interaktionsereignissen enthält ein common.formInputs-Objekt (event.common.formInputs) mit allen Werten, die der Nutzer eingibt.

    Sie können die Werte aus dem Objekt common.formInputs.WIDGET_NAME abrufen, wobei WIDGET_NAME das Feld name ist, das Sie für das Widget angegeben haben. Die Werte werden als bestimmter Datentyp für das Widget zurückgegeben (als Inputs-Objekt).

    Im Folgenden sehen Sie einen Teil eines CARD_CLICKED-Interaktionsereignisses, bei dem ein Nutzer Werte für jedes Widget eingegeben hat:

    HTTP

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

    Apps Script

    {
      "type": "CARD_CLICKED",
      "common": { "formInputs": {
        "contactName": { "": { "stringInputs": {
          "value": ["Kai 0"]
        }}},
        "contactBirthdate": { "": { "dateInput": {
          "msSinceEpoch": 1000425600000
        }}},
          "contactType": { "": { "stringInputs": {
          "value": ["Personal"]
        }}}
      }}
    }
    
  • Wenn sich der Button auf einer Startseite befindet, empfangen Chat-Apps, die keine Add-ons sind, ein SUBMIT_FORM-Interaktionsereignis. Die Nutzlast des Interaktionsereignisses enthält ein commonEventObject.formInputs-Objekt (event.commonEventObject.formInputs) mit allen Werten, die der Nutzer eingibt.

    Sie können die Werte aus dem Objekt commonEventObject.formInputs.WIDGET_NAME abrufen, wobei WIDGET_NAME das Feld name ist, das Sie für das Widget angegeben haben. Die Werte werden als bestimmter Datentyp für das Widget zurückgegeben (als Inputs-Objekt).

    Im Folgenden sehen Sie einen Teil eines SUBMIT_FORM-Interaktionsereignisses, bei dem ein Nutzer Werte für jedes Widget eingegeben hat:

    HTTP

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

    Apps Script

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

Damit die Daten empfangen werden, verarbeitet eine Chat-App, die kein Add-on ist, das Interaktionsereignis, um die Werte abzurufen, die Nutzer in Widgets eingeben. In der folgenden Tabelle sehen Sie, wie Sie den Wert für ein bestimmtes Formulareingabe-Widget abrufen. Für jedes Widget enthält die Tabelle den Datentyp, den das Widget akzeptiert, wo der Wert im Interaktionsereignis gespeichert wird, und einen Beispielwert.

Formular-Eingabe-Widget Art der Eingabedaten Eingabewert aus dem Interaktionsereignis Beispielwert
textInput stringInputs event.common.formInputs.contactName.stringInputs.value[0] Kai O
selectionInput stringInputs So rufen Sie den ersten oder einzigen Wert ab: event.common.formInputs.contactType.stringInputs.value[0] Personal
dateTimePicker, in das nur Datumsangaben eingegeben werden können. dateInput event.common.formInputs.contactBirthdate.dateInput.msSinceEpoch. 1000425600000

Daten auf eine andere Karte übertragen

Wenn Sie die Dateneingabe von der ursprünglichen Karte in einer Chat-App übertragen möchten, die kein Add-on ist, erstellen Sie das button-Widget mit actionParameters, die die name des Widgets und den vom Nutzer eingegebenen Wert enthalten, wie im folgenden Beispiel gezeigt:

Node.js

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

Python

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

Java

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

Apps Script

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

Wenn ein Nutzer auf die Schaltfläche klickt, empfängt die Chat-App, die kein Add-on ist, ein CARD_CLICKED-Interaktionsereignis, aus dem Sie Daten abrufen können.

Auf eine Formulareinsendung reagieren

Im folgenden Beispiel sendet eine Chat-App, die kein Add-on ist, eine Nachricht, um zu bestätigen, dass sie ein über ein Dialogfeld oder eine Kartenmitteilung gesendetes Formular erfolgreich empfangen hat:

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.
const errorMessage = "Don't forget to name your new contact!";
if (!contactName && event.dialogEventType === "SUBMIT_DIALOG") {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { actionStatus: {
      statusCode: "INVALID_ARGUMENT",
      userFacingMessage: 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.
error_message = "Don't forget to name your new contact!"
if contact_name == "" and "SUBMIT_DIALOG" == event.get('dialogEventType'):
  return { 'actionResponse': {
    'type': "DIALOG",
    'dialogAction': { 'actionStatus': {
      'statusCode': "INVALID_ARGUMENT",
      'userFacingMessage': 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.
String errorMessage = "Don't forget to name your new contact!";
if (contactName.isEmpty() && 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))));
}

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.
const errorMessage = "Don't forget to name your new contact!";
if (!contactName && event.dialogEventType === "SUBMIT_DIALOG") {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { actionStatus: {
      statusCode: "INVALID_ARGUMENT",
      userFacingMessage: errorMessage
    }}
  }};
}

Um ein Dialogfeld in einer Chat-App zu verarbeiten und zu schließen, die kein Add-on ist, geben Sie ein ActionResponse-Objekt zurück, das angibt, ob Sie eine Bestätigungsnachricht senden, die ursprüngliche Nachricht oder Karte aktualisieren oder das Dialogfeld einfach schließen möchten. Eine Anleitung finden Sie unter Dialogfeld schließen.