Tworzenie aplikacji Google Chat jako webhooka

Na tej stronie opisujemy, jak skonfigurować webhooka do wysyłania asynchronicznych wiadomości do przestrzeni w Google Chat za pomocą zewnętrznych wyzwalaczy. Możesz na przykład skonfigurować aplikację monitorującą, aby powiadamiała w Hangouts Chat osoby dyżurujące, gdy serwer przestanie działać. Aby wysłać wiadomość synchroniczną za pomocą aplikacji Chat, przeczytaj artykuł Wysyłanie wiadomości.

W przypadku tego typu architektury użytkownicy nie mogą wchodzić w interakcje z elementem webhook ani z połączoną aplikacją zewnętrzną, ponieważ komunikacja jest jednokierunkowa. Webhooki nie prowadzą rozmów. Nie mogą odpowiadać na wiadomości od użytkowników ani ich otrzymywać ani zdarzeń interakcji z aplikacją do obsługi czatu. Aby odpowiadać na wiadomości, utwórz aplikację do obsługi czatu zamiast webhooka.

Webhook nie jest technicznie aplikacją w Google Chat – łączy aplikacje za pomocą standardowych żądań HTTP – ale na tej stronie dla uproszczenia będziemy go nazywać aplikacją w Google Chat. Każdy webhook działa tylko w pokoju czatu, w którym jest zarejestrowany. Przychodzące webhooki działają na czatach bezpośrednich, ale tylko wtedy, gdy wszyscy użytkownicy mają włączone aplikacje do obsługi czatu. Nie możesz publikować webhooków w Google Workspace Marketplace.

Poniższy diagram przedstawia architekturę webhooka połączonego z Chatem:

Architektura przychodzących webhooków do wysyłania wiadomości asynchronicznych do Google Chat.

Na powyższym diagramie aplikacja Google Chat ma następujący przepływ informacji:

  1. Logika aplikacji Chat otrzymuje informacje z zewnętrznych usług innych firm, takich jak system zarządzania projektami lub narzędzie do obsługi zgłoszeń.
  2. Logika aplikacji Google Chat jest hostowana w systemie w chmurze lub lokalnym, który może wysyłać wiadomości za pomocą adresu URL webhooka do konkretnego pokoju w Google Chat.
  3. Użytkownicy mogą otrzymywać wiadomości z aplikacji Google Chat w tym konkretnym pokoju, ale nie mogą wchodzić w interakcje z aplikacją.

Wymagania wstępne

Python

Node.js

Java

Google Apps Script

Tworzenie webhooka

Aby utworzyć webhooka, zarejestruj go w pokoju w Chat, w którym chcesz odbierać wiadomości, a następnie napisz skrypt, który będzie je wysyłać.

Zarejestruj przychodzącego webhooka

  1. W przeglądarce otwórz Chat. Webhooków nie można konfigurować w aplikacji mobilnej Google Chat.
  2. Otwórz przestrzeń, w której chcesz dodać webhooka.
  3. Obok tytułu pokoju kliknij strzałkę rozwijania , a następnie kliknij Aplikacje i integracje.
  4. Kliknij Dodaj webhooki.

  5. W polu Nazwa wpisz Quickstart Webhook.

  6. W polu Adres URL awatara wpisz https://developers.google.com/chat/images/chat-product-icon.png.

  7. Kliknij Zapisz.

  8. Aby skopiować adres URL webhooka, kliknij Więcej, a następnie Kopiuj link.

Napisz skrypt webhooka

Przykładowy skrypt webhooka wysyła wiadomość do przestrzeni, w której jest zarejestrowany, wysyłając żądanie POST na adres URL webhooka. Interfejs Chat API odpowiada instancją Message.

Wybierz język, aby dowiedzieć się, jak utworzyć skrypt webhooka:

Python

  1. W katalogu roboczym utwórz plik o nazwie quickstart.py.

  2. W pliku quickstart.py wklej ten kod:

    python/webhook/quickstart.py
    from json import dumps
    from httplib2 import Http
    
    # Copy the webhook URL from the Chat space where the webhook is registered.
    # The values for SPACE_ID, KEY, and TOKEN are set by Chat, and are included
    # when you copy the webhook URL.
    
    def main():
        """Google Chat incoming webhook quickstart."""
        url = "https://chat.googleapis.com/v1/spaces/SPACE_ID/messages?key=KEY&token=TOKEN"
        app_message = {"text": "Hello from a Python script!"}
        message_headers = {"Content-Type": "application/json; charset=UTF-8"}
        http_obj = Http()
        response = http_obj.request(
            uri=url,
            method="POST",
            headers=message_headers,
            body=dumps(app_message),
        )
        print(response)
    
    
    if __name__ == "__main__":
        main()
  3. Zastąp wartość zmiennej url adresem URL webhooka skopiowanym podczas rejestracji webhooka.

Node.js

  1. W katalogu roboczym utwórz plik o nazwie index.js.

  2. W pliku index.js wklej ten kod:

    node/webhook/index.js
    /**
     * Sends asynchronous message to Google Chat
     * @return {Object} response
     */
    async function webhook() {
      const url = "https://chat.googleapis.com/v1/spaces/SPACE_ID/messages"
      const res = await fetch(url, {
        method: "POST",
        headers: {"Content-Type": "application/json; charset=UTF-8"},
        body: JSON.stringify({text: "Hello from a Node script!"})
      });
      return await res.json();
    }
    
    webhook().then(res => console.log(res));
  3. Zastąp wartość zmiennej url adresem URL webhooka skopiowanym podczas rejestracji webhooka.

Java

  1. W katalogu roboczym utwórz plik o nazwie pom.xml.

  2. W polu pom.xml skopiuj i wklej ten tekst:

    java/webhook/pom.xml
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>com.google.chat.webhook</groupId>
      <artifactId>java-webhook-app</artifactId>
      <version>0.1.0</version>
    
      <name>java-webhook-app</name>
      <url>https://github.com/googleworkspace/google-chat-samples/tree/main/java/webhook</url>
    
      <properties>
        <maven.compiler.target>11</maven.compiler.target>
        <maven.compiler.source>11</maven.compiler.source>
      </properties>
    
      <dependencies>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.9.1</version>
        </dependency>
      </dependencies>
    
      <build>
        <pluginManagement>
          <plugins>
            <plugin>
              <artifactId>maven-compiler-plugin</artifactId>
              <version>3.8.0</version>
            </plugin>
          </plugins>
        </pluginManagement>
      </build>
    </project>
  3. W katalogu roboczym utwórz tę strukturę katalogów:src/main/java

  4. W katalogu src/main/java utwórz plik o nazwie App.java.

  5. W pliku App.java wklej ten kod:

    java/webhook/src/main/java/com/google/chat/webhook/App.java
    import com.google.gson.Gson;
    import java.net.http.HttpClient;
    import java.net.http.HttpRequest;
    import java.net.http.HttpResponse;
    import java.util.Map;
    import java.net.URI;
    
    public class App {
      private static final String URL = "https://chat.googleapis.com/v1/spaces/AAAAGCYeSRY/messages";
      private static final Gson gson = new Gson();
      private static final HttpClient client = HttpClient.newHttpClient();
    
      public static void main(String[] args) throws Exception {
        String message = gson.toJson(Map.of("text", "Hello from Java!"));
    
        HttpRequest request = HttpRequest.newBuilder(URI.create(URL))
          .header("accept", "application/json; charset=UTF-8")
          .POST(HttpRequest.BodyPublishers.ofString(message)).build();
    
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    
        System.out.println(response.body());
      }
    }
  6. Zastąp wartość zmiennej URL adresem URL webhooka, który został skopiowany podczas rejestracji webhooka.

Google Apps Script

  1. W przeglądarce otwórz Apps Script.

  2. Kliknij Nowy projekt.

  3. Wklej ten kod:

    apps-script/webhook/webhook.gs
    function webhook() {
      const url = "https://chat.googleapis.com/v1/spaces/SPACE_ID/messages"
      const options = {
        "method": "post",
        "headers": {"Content-Type": "application/json; charset=UTF-8"},
        "payload": JSON.stringify({"text": "Hello from Apps Script!"})
      };
      const response = UrlFetchApp.fetch(url, options);
      console.log(response);
    }
  4. Zastąp wartość zmiennej url adresem URL webhooka, który został skopiowany podczas rejestracji webhooka.

Uruchamianie skryptu webhooka

W interfejsie wiersza poleceń uruchom skrypt:

Python

  python3 quickstart.py

Node.js

  node index.js

Java

  mvn compile exec:java -Dexec.mainClass=App

Google Apps Script

  • Kliknij Wykonaj.

Gdy uruchomisz kod, webhook wyśle wiadomość do pokoju, w którym został zarejestrowany.

Rozpoczynanie wątku wiadomości lub odpowiadanie w nim

  1. Określ spaces.messages.thread.threadKey w treści żądania wiadomości. W zależności od tego, czy rozpoczynasz wątek, czy na niego odpowiadasz, użyj tych wartości w przypadku parametru threadKey:

    • Jeśli rozpoczynasz wątek, ustaw wartość parametru threadKey na dowolny ciąg znaków, ale zanotuj tę wartość, aby móc opublikować odpowiedź w wątku.

    • Jeśli odpowiadasz na wątek, podaj wartość parametru threadKey, która została ustawiona podczas rozpoczynania wątku. Na przykład, aby opublikować odpowiedź w wątku, w którym pierwsza wiadomość używała MY-THREAD, ustaw MY-THREAD.

  2. Określ zachowanie wątku, jeśli nie znaleziono określonego elementu threadKey:

    • Odpowiedz w wątku lub rozpocznij nowy wątek. Dodaj parametr messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD do adresu URL webhooka. Przekazanie tego parametru adresu URL powoduje, że Chat szuka istniejącego wątku z użyciem określonego threadKey. Jeśli zostanie znaleziony, wiadomość zostanie opublikowana jako odpowiedź w tym wątku. Jeśli nie zostanie znaleziona żadna odpowiednia wiadomość, rozpocznie się nowy wątek odpowiadający temu threadKey.

    • Odpowiedz w wątku lub nie rób nic. Dodaj parametr messageReplyOption=REPLY_MESSAGE_OR_FAIL do adresu URL webhooka. Przekazanie tego parametru adresu URL powoduje, że Chat szuka istniejącego wątku z użyciem określonego threadKey. Jeśli zostanie znaleziony, wiadomość zostanie opublikowana jako odpowiedź w tym wątku. Jeśli nie zostanie znaleziony żaden adres, wiadomość nie zostanie wysłana.

    Więcej informacji znajdziesz w messageReplyOption.

Poniższy przykładowy kod rozpoczyna wątek wiadomości lub odpowiada na niego:

Python

python/webhook/thread-reply.py
from json import dumps
from httplib2 import Http

# Copy the webhook URL from the Chat space where the webhook is registered.
# The values for SPACE_ID, KEY, and TOKEN are set by Chat, and are included
# when you copy the webhook URL.
#
# Then, append messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD to the
# webhook URL.


def main():
    """Google Chat incoming webhook that starts or replies to a message thread."""
    url = "https://chat.googleapis.com/v1/spaces/SPACE_ID/messages?key=KEY&token=TOKEN&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD"
    app_message = {
        "text": "Hello from a Python script!",
        # To start a thread, set threadKey to an arbitratry string.
        # To reply to a thread, specify that thread's threadKey value.
        "thread": {"threadKey": "THREAD_KEY_VALUE"},
    }
    message_headers = {"Content-Type": "application/json; charset=UTF-8"}
    http_obj = Http()
    response = http_obj.request(
        uri=url,
        method="POST",
        headers=message_headers,
        body=dumps(app_message),
    )
    print(response)


if __name__ == "__main__":
    main()

Node.js

node/webhook/thread-reply.js
/**
 * Sends asynchronous message to Google Chat
 * @return {Object} response
 */
async function webhook() {
  const url = "https://chat.googleapis.com/v1/spaces/SPACE_ID/messages?key=KEY&token=TOKEN&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD"
  const res = await fetch(url, {
    method: "POST",
    headers: {"Content-Type": "application/json; charset=UTF-8"},
    body: JSON.stringify({
      text: "Hello from a Node script!",
      thread: {threadKey: "THREAD_KEY_VALUE"}
    })
  });
  return await res.json();
}

webhook().then(res => console.log(res));

Google Apps Script

apps-script/webhook/thread-reply.gs
function webhook() {
  const url = "https://chat.googleapis.com/v1/spaces/SPACE_ID/messages?key=KEY&token=TOKEN&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD"
  const options = {
    "method": "post",
    "headers": {"Content-Type": "application/json; charset=UTF-8"},
    "payload": JSON.stringify({
      "text": "Hello from Apps Script!",
      "thread": {"threadKey": "THREAD_KEY_VALUE"}
    })
  };
  const response = UrlFetchApp.fetch(url, options);
  console.log(response);
}

Obsługuj błędy

Żądania webhooka mogą się nie powieść z różnych powodów, m.in.:

  • Nieprawidłowe żądanie.
  • Webhook lub pokój, w którym jest on hostowany, zostaną usunięte.
  • Przejściowe problemy, takie jak połączenie sieciowe lub limity.

Podczas tworzenia webhooka należy odpowiednio obsługiwać błędy, wykonując te czynności:

Interfejs Google Chat API zwraca błędy w postaci google.rpc.Status, która zawiera błąd HTTP code wskazujący typ napotkanego błędu: błąd klienta (seria 400) lub błąd serwera (seria 500). Aby przejrzeć wszystkie mapowania HTTP, zobacz google.rpc.Code.

{
    "code": 503,
    "message": "The service is currently unavailable.",
    "status": "UNAVAILABLE"
}

Aby dowiedzieć się, jak interpretować kody stanu HTTP i obsługiwać błędy, zapoznaj się z sekcją Błędy.

Ograniczenia i kwestie do rozważenia

  • Podczas tworzenia wiadomości za pomocą webhooka w Google Chat API odpowiedź nie zawiera pełnej wiadomości. Odpowiedź wypełnia tylko pola namethread.name.
  • Webhooki podlegają limitowi spaces.messages.create na pokój: 1 żądanie na sekundę, współdzielone przez wszystkie webhooki w pokoju. Chat może też odrzucać żądania webhooka, które przekraczają 1 zapytanie na sekundę w tym samym pokoju. Więcej informacji o limitach interfejsu Chat API znajdziesz w artykule Limity wykorzystania.