Zbieranie i przetwarzanie informacji od użytkowników Google Chat

Z tego przewodnika dowiesz się, jak aplikacje Google Chat mogą zbierać i przetwarzać informacje od użytkowników, tworząc dane wejściowe formularza w interfejsach opartych na kartach.

Okno dialogowe zawierające różne widżety.
Ilustracja 1. Aplikacja Google Chat, która otwiera okno dialogowe do zbierania informacji kontaktowych.

Aplikacje do czatu proszą użytkowników o informacje, aby wykonywać działania w Google Chat lub poza nim, w tym w następujący sposób:

  • Skonfiguruj ustawienia. Może to być na przykład umożliwienie użytkownikom dostosowywania ustawień powiadomień lub konfigurowania i dodawania aplikacji Google Chat do co najmniej jednego pokoju.
  • tworzyć lub aktualizować informacje w innych aplikacjach Google Workspace; Na przykład zezwól użytkownikom na tworzenie wydarzeń w Kalendarzu Google.
  • Umożliwiać użytkownikom dostęp do zasobów w innych aplikacjach lub usługach internetowych i ich aktualizowanie. Na przykład aplikacja do obsługi czatu może pomagać użytkownikom w aktualizowaniu stanu zgłoszenia bezpośrednio z pokoju w Google Chat.

Wymagania wstępne

HTTP

Dodatek do Google Workspace, który rozszerza Google Chat. Aby go utworzyć, wykonaj czynności opisane w tym krótkim wprowadzeniu dotyczącym HTTP.

Google Apps Script

Dodatek do Google Workspace, który rozszerza Google Chat. Aby go utworzyć, wykonaj czynności opisane w krótkim wprowadzeniu do Apps Script.

Tworzenie formularzy za pomocą kart

Aby zbierać informacje, aplikacje w Google Chat projektują formularze i ich pola wejściowe oraz tworzą z nich karty. Aby wyświetlać karty użytkownikom, aplikacje do obsługi czatu mogą korzystać z tych interfejsów Google Chat:

  • wiadomości na czacie zawierające co najmniej 1 kartę;
  • Okna, czyli karty, które otwierają się w nowym oknie z wiadomości i stron głównych.

Aplikacje do obsługi czatu mogą tworzyć karty za pomocą tych widżetów:

  • Widżety wprowadzania danych w formularzu, które proszą użytkowników o informacje. Opcjonalnie możesz dodać weryfikację do widżetów wprowadzania danych w formularzu, aby mieć pewność, że użytkownicy wprowadzają i formatują informacje prawidłowo. Aplikacje do obsługi czatu mogą używać tych widżetów wprowadzania danych:

    • Pola tekstowe (textInput) do wpisywania tekstu w dowolnej formie lub sugerowanego tekstu.
    • Pola wyboru (selectionInput) to elementy interfejsu, które można wybrać, np. pola wyboru, przyciski opcji i menu. Widżety wprowadzania wyboru mogą też wypełniać i sugerować elementy z danych Google Workspace (np. z pokoju czatu w Google Chat) lub dynamicznego źródła danych. Szczegółowe informacje znajdziesz w sekcjach Dodawanie menuDodawanie menu wielokrotnego wyboru.

    • Selektory daty i godziny (dateTimePicker) do wprowadzania daty i godziny.

  • Widżet przycisku, aby użytkownicy mogli przesyłać wartości wpisane na karcie. Gdy użytkownik kliknie przycisk, aplikacja Google Chat może przetworzyć otrzymane informacje.

W poniższym przykładzie karta zbiera dane kontaktowe za pomocą pola tekstowego, selektora daty i godziny oraz pola wyboru:

Więcej przykładów interaktywnych widżetów, których możesz używać do zbierania informacji, znajdziesz w artykule Projektowanie interaktywnej karty lub okna w dokumentacji interfejsu Google Chat API.

Dodawanie menu

Aby dostosować elementy wyboru lub umożliwić użytkownikom wybór pojedynczego elementu z dynamicznego źródła danych, aplikacje na czacie mogą używać menu, które są rodzajem widżetu SelectionInput. Na przykład ta karta wyświetla menu, w którym użytkownicy mogą dynamicznie wybierać kontakty z listy:

Elementy menu możesz wypełniać danymi z tych źródeł:

Wypełnianie elementów ze źródła danych Google Workspace

Aby wypełnić elementy ze źródeł danych Google Workspace, takich jak użytkownicy Google Workspace, określ pole platformDataSource w obiekcie DataSourceConfig. W przeciwieństwie do innych typów danych wejściowych wyboru możesz pominąć obiekty SelectionItem, ponieważ te elementy wyboru są dynamicznie pobierane z Google Workspace.

Poniższy kod przedstawia menu rozwijane z użytkownikami Google Workspace:

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
              }
            ]
          }
        }
      ]
    }
  ]
}

Wypełnianie elementów z zewnętrznego źródła danych

Menu rozwijane mogą też zawierać elementy pochodzące ze źródła danych zewnętrznego lub firmy zewnętrznej. Aby użyć zewnętrznego źródła danych, w obiekcie DataSourceConfig określ pole remoteDataSource, które zawiera funkcję wysyłającą zapytania i zwracającą elementy ze źródła danych.

Aby zmniejszyć liczbę żądań wysyłanych do zewnętrznego źródła danych, możesz uwzględnić sugerowane produkty, które pojawiają się w menu przed wpisaniem przez użytkowników tekstu w menu. Aby wypełnić sugerowane produkty z zewnętrznego źródła danych, określ statyczne obiekty SelectionItem.

Poniższy kod pokazuje menu, które wysyła zapytania i wypełnia elementy z zewnętrznego źródła danych:

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"
              }
            ]
          }
        }
      ]
    }
  ]
}

Pełny przykład pokazujący, jak zwracać sugerowane elementy, znajdziesz w sekcji Sugerowanie elementów do wyboru.

Dodawanie menu wielokrotnego wyboru

Aby dostosować elementy wyboru lub umożliwić użytkownikom wybieranie elementów z dynamicznego źródła danych, aplikacje na czacie mogą używać menu wielokrotnego wyboru, które są rodzajem widżetu SelectionInput. Na przykład poniższa karta wyświetla menu wielokrotnego wyboru, w którym użytkownicy mogą dynamicznie wybierać elementy z listy kontaktów:

Elementy menu wielokrotnego wyboru możesz wypełniać danymi z tych źródeł:

  • dane Google Workspace, które obejmują użytkowników lub pokoje czatu, których użytkownik jest członkiem; Menu zawiera tylko elementy z tej samej organizacji Google Workspace.
  • zewnętrzne źródła danych, np. relacyjna baza danych; Możesz na przykład użyć menu wielokrotnego wyboru, aby pomóc użytkownikowi wybrać z listy potencjalnych klientów z systemu zarządzania relacjami z klientami (CRM).

Wypełnianie elementów ze źródła danych Google Workspace

Aby używać źródeł danych Google Workspace, w widżecie SelectionInput określ pole platformDataSource. W przeciwieństwie do innych typów danych wejściowych wyboru możesz pominąć obiekty SelectionItem, ponieważ te elementy wyboru są dynamicznie pobierane z Google Workspace.

Poniższy kod pokazuje menu wielokrotnego wyboru użytkowników Google Workspace. Aby wypełnić listę użytkowników, dane wejściowe wyboru ustawiają wartość commonDataSource na USER:

JSON

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

Poniższy kod pokazuje menu wielokrotnego wyboru przestrzeni na czacie. Aby wypełnić miejsca, w polu wyboru należy podać pole hostAppDataSource. W menu wielokrotnego wyboru ustawia się też wartość defaultToCurrentSpace na true, co sprawia, że bieżący pokój jest domyślnie wybierany w menu:

JSON

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

Wypełnianie elementów z zewnętrznego źródła danych

Menu wielokrotnego wyboru mogą też wypełniać elementy pochodzące ze źródła danych zewnętrznego lub firmy zewnętrznej. Aby użyć zewnętrznego źródła danych, w widżecie SelectionInput podaj pole externalDataSource zawierające funkcję, która wysyła zapytania do źródła danych i zwraca z niego elementy.

Aby zmniejszyć liczbę żądań wysyłanych do zewnętrznego źródła danych, możesz uwzględnić sugerowane elementy, które pojawiają się w menu wielokrotnego wyboru, zanim użytkownicy wpiszą tekst w menu. Możesz na przykład wypełnić listę ostatnio wyszukiwanych kontaktów użytkownika. Aby wypełnić sugerowane produkty z zewnętrznego źródła danych, określ statyczne obiekty SelectionItem.

Poniższy przykładowy kod pokazuje menu wielokrotnego wyboru, które wysyła zapytania i wypełnia elementy z zewnętrznego źródła danych:

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")]
}

Zastąp FUNCTION_URL punktem końcowym HTTP, który wysyła zapytania do zewnętrznego źródła danych.

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")]
}

Zastąp FUNCTION_URL punktem końcowym HTTP, który wysyła zapytania do zewnętrznego źródła danych.

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

Zastąp FUNCTION_URL punktem końcowym HTTP, który wysyła zapytania do zewnętrznego źródła danych.

Google Apps Script

W tym przykładzie wysyłana jest wiadomość z kartą przez zwrócenie kodu JSON karty. Możesz też użyć usługi kart Apps Script.

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")]
}

Pełny przykład pokazujący, jak zwracać sugerowane elementy, znajdziesz w sekcji Sugerowanie elementów do wyboru.

Otrzymywanie danych z interaktywnych widżetów

Gdy użytkownicy klikną przycisk, wywoływane jest działanie aplikacji Google Chat z informacjami o interakcji. W parametrze commonEventObject ładunku zdarzenia obiekt formInputs zawiera wszystkie wartości wpisane przez użytkownika.

Wartości możesz pobrać z obiektu commonEventObject.formInputs.WIDGET_NAME, gdzie WIDGET_NAME to pole name określone dla widżetu. Wartości są zwracane jako określony typ danych widżetu.

Poniżej przedstawiamy fragment obiektu zdarzenia, w którym użytkownik wprowadził wartości w poszczególnych widżetach:

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

Aby otrzymać dane, aplikacja w Google Chat obsługuje obiekt zdarzenia, aby uzyskać wartości wpisywane przez użytkowników w widżetach. W tabeli poniżej znajdziesz informacje o tym, jak uzyskać wartość danego widżetu wejściowego formularza. W przypadku każdego widżetu tabela zawiera typ danych, który akceptuje widżet, miejsce przechowywania wartości w obiekcie zdarzenia oraz przykładową wartość.

Widżet wprowadzania danych w formularzu Typ danych wejściowych Wartość wejściowa z obiektu zdarzenia Przykładowa wartość
textInput stringInputs event.commonEventObject.formInputs.contactName.stringInputs.value[0] Kai O
selectionInput stringInputs Aby uzyskać pierwszą lub jedyną wartość, event.commonEventObject.formInputs.contactType.stringInputs.value[0] Personal
dateTimePicker, które akceptuje tylko daty. dateInput event.commonEventObject.formInputs.contactBirthdate.dateInput.msSinceEpoch. 1000425600000

Po otrzymaniu danych aplikacja do obsługi czatu może wykonać dowolną z tych czynności:

  • W przypadku kart zawierających menu wielokrotnego wyboru wypełniaj lub sugeruj elementy na podstawie tego, co użytkownik wpisuje w menu.
  • Przenieś dane na inną kartę, aby użytkownik mógł sprawdzić swoje informacje lub przejść do następnej sekcji formularza.
  • Odpowiedz użytkownikowi, aby potwierdzić, że użytkownik prawidłowo wypełnił formularz.

Sugerowanie elementów wyboru

Jeśli karta zawiera menu wielokrotnego wyboru lub menu, które wypełnia elementy z zewnętrznego źródła danych, aplikacja Google Chat może zwracać sugerowane elementy na podstawie tego, co użytkownicy wpisują w menu. Jeśli na przykład użytkownik zacznie wpisywać Atl w menu, które zawiera miasta w Stanach Zjednoczonych, Twoja aplikacja w Google Chat może automatycznie zasugerować Atlanta, zanim użytkownik skończy wpisywać. Aplikacja Google Chat może sugerować maksymalnie 100 produktów.

Aby sugerować i dynamicznie wypełniać elementy w polu wyboru, widżet SelectionInputna karcie musi określać funkcję, która wysyła zapytania do zewnętrznego źródła danych. W przypadku menu wielokrotnego wyboru określasz pole externalDataSource. W przypadku menu określasz pole remoteDataSource w obiekcie DataSourceConfig.

Możesz też skonfigurować liczbę znaków, które użytkownik wpisuje, zanim menu zwróci sugestie. W przypadku menu wielokrotnego wyboru ustaw pole multiSelectMinQueryLength. W przypadku menu ustaw pole min_characters_trigger w sekcji DataSourceConfig.

Aby zwracać sugerowane produkty, funkcja musi wykonać te czynności:

  1. Obsługuj obiekt zdarzenia, który aplikacja do obsługi czatu otrzymuje, gdy użytkownicy wpisują tekst w menu.
  2. Z obiektu zdarzenia pobierz wartość wpisaną przez użytkownika, która jest reprezentowana w polu event.commonEventObject.parameters["autocomplete_widget_query"].
  3. Wysyłaj do źródła danych zapytanie z danymi wejściowymi użytkownika, aby uzyskać co najmniej 1 SelectionItems do zaproponowania użytkownikowi.
  4. Aby zwrócić sugerowane produkty, zwróć działanie RenderActionsmodifyCard obiektem.

Poniższy przykładowy kod pokazuje, jak aplikacja do obsługi czatu dynamicznie sugeruje elementy w menu wielokrotnego wyboru na karcie. Gdy użytkownik wpisuje tekst w menu, funkcja lub punkt końcowy podany w polu externalDataSource widżetu wysyła zapytanie do zewnętrznego źródła danych i sugeruje elementy, które użytkownik może wybrać.

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

Zastąp FUNCTION_URL punktem końcowym HTTP, który wysyła zapytania do zewnętrznego źródła danych.

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
  }

Zastąp FUNCTION_URL punktem końcowym HTTP, który wysyła zapytania do zewnętrznego źródła danych.

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

Zastąp FUNCTION_URL punktem końcowym HTTP, który wysyła zapytania do zewnętrznego źródła danych.

Google Apps Script

W tym przykładzie wysyłana jest wiadomość z kartą przez zwrócenie kodu JSON karty. Możesz też użyć usługi kart Apps Script.

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

Przenoszenie danych na inną kartę

Gdy użytkownik prześle informacje z karty, możesz potrzebować dodatkowych kart, aby wykonać jedną z tych czynności:

  • Ułatw użytkownikom wypełnianie dłuższych formularzy, tworząc w nich osobne sekcje.
  • Umożliwiaj użytkownikom wyświetlanie podanych informacji z początkowej karty i ich potwierdzanie, aby mogli sprawdzić odpowiedzi przed przesłaniem.
  • dynamicznie wypełniać pozostałe części formularza. Na przykład, aby zachęcić użytkowników do utworzenia spotkania, aplikacja do obsługi czatu może wyświetlić początkową kartę z prośbą o podanie powodu spotkania, a następnie wypełnić inną kartę, która zawiera dostępne terminy na podstawie typu spotkania.

Aby przenieść dane wejściowe z pierwszej karty, możesz utworzyć widżet button z elementem actionParameters zawierającym name widżetu i wartość wprowadzoną przez użytkownika, jak pokazano w tym przykładzie:

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 }
    ]
  }}
}]}}

Zastąp FUNCTION_URL punktem końcowym HTTP, który obsługuje kliknięcia przycisku.

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 }
    ]
  }}
}]}}

Zastąp FUNCTION_URL punktem końcowym HTTP, który obsługuje kliknięcia przycisku.

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

Zastąp FUNCTION_URL punktem końcowym HTTP, który obsługuje kliknięcia przycisku.

Google Apps Script

W tym przykładzie wysyłana jest wiadomość z kartą przez zwrócenie kodu JSON karty. Możesz też użyć usługi kart Apps Script.

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 }
    ]
  }}
}]}}

Gdy użytkownik kliknie przycisk, aplikacja do obsługi czatu otrzyma obiekt zdarzenia, z którego możesz pobrać dane.

Odpowiadanie na przesłany formularz

Po otrzymaniu danych z wiadomości na karcie lub okna aplikacji w Google Chat odpowiada ona potwierdzeniem odbioru lub zwraca błąd.

W tym przykładzie aplikacja do obsługi czatu wysyła wiadomość tekstową z potwierdzeniem, że otrzymała formularz przesłany z wiadomości w formie karty.

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

Google Apps Script

W tym przykładzie wysyłana jest wiadomość z kartą przez zwrócenie kodu JSON karty. Możesz też użyć usługi kart 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."
}}}}};

Aby przetworzyć i zamknąć okno, zwracasz obiekt RenderActions określający, czy chcesz wysłać wiadomość z potwierdzeniem, zaktualizować pierwotną wiadomość lub kartę, czy tylko zamknąć okno. Instrukcje znajdziesz w artykule Zamykanie okna.

Rozwiązywanie problemów

W tej sekcji znajdziesz instrukcje rozwiązywania problemów z określonymi kodami błędów i zachowaniami środowiska wykonawczego podczas interakcji z oknami w Google Chat.

Interakcje z oknem zwracają błąd „Podczas wywoływania dodatku wystąpił nieokreślony błąd”

Jeśli podczas interakcji z oknem zobaczysz dzienniki błędów z komunikatem „Nieokreślony błąd podczas wywoływania dodatku” i kodem 13, zwykle oznacza to błąd wewnętrzny lub że punkt końcowy HTTP aplikacji Chat nie przetworzył żądania lub nie zwrócił prawidłowej odpowiedzi.

Aby rozwiązać ten problem:

  • Sprawdź logi punktu końcowego HTTP pod kątem nieobsłużonych wyjątków lub awarii.
  • Sprawdź, czy punkt końcowy odpowiada na żądania w ciągu 30 sekund. Jeśli działanie punktu końcowego trwa dłużej niż 30 sekund, Chat nie może przetworzyć odpowiedzi i interakcja się nie powiedzie. Więcej informacji znajdziesz w artykule Limity żądań i sprawdzone metody.
  • Sprawdź, czy punkt końcowy zwraca prawidłową odpowiedź. W przypadku przesłania okna dialogowego punkt końcowy musi zwracać obiekt RenderActions w prawidłowym formacie JSON. Jeśli odpowiedź jest nieprawidłowo sformatowana lub nie zawiera wymaganych pól, interakcja z oknem może się nie powieść.

Gdy aplikacja Google Chat lub karta zwraca błąd, w interfejsie Google Chat pojawia się komunikat „Coś poszło nie tak”. lub „Nie udało się przetworzyć Twojej prośby”. Czasami interfejs Google Chat nie wyświetla żadnego komunikatu o błędzie, ale aplikacja lub karta Google Chat daje nieoczekiwany wynik, np. wiadomość na karcie może się nie pojawić.

Chociaż w interfejsie czatu może nie wyświetlać się komunikat o błędzie, opisowe komunikaty o błędach i dane logowania są dostępne, aby pomóc w naprawieniu błędów, gdy rejestrowanie błędów w aplikacjach na czat jest włączone. Pomoc dotyczącą wyświetlania, debugowania i naprawiania błędów znajdziesz w artykule Rozwiązywanie problemów z Google Chat.