Tworzenie aplikacji Google Chat jako webhooka

Na tej stronie opisaliśmy, jak skonfigurować webhook, aby wysyłać wiadomości asynchroniczne do pokoju Google Chat za pomocą zewnętrznych wyzwalaczy. Możesz na przykład skonfigurować aplikację monitorującą, aby powiadamiała personel dyżurny w Hangouts Chat o awarii serwera. 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 webhookem ani podłączoną aplikacją zewnętrzną, ponieważ komunikacja jest jednokierunkowa. Webhooki nie są konwersacyjne. Nie może odpowiadać na wiadomości od użytkowników ani otrzymywać od nich zdarzeń interakcji z aplikacją Google Chat. Aby odpowiadać na wiadomości, zamiast webhooka utwórz aplikację do obsługi czatu.

Webhook nie jest technicznie aplikacją Google Chat (łączy aplikacje za pomocą standardowych żądań HTTP), ale na potrzeby uproszczenia na tej stronie jest tak nazywany. Każdy webhook działa tylko w pokoju czatu, w którym jest zarejestrowany. Wewnętrzne wywołania webhooka działają w czatach, 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.

Ten diagram przedstawia architekturę webhooka połączonego z Chatem:

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

Na poprzednim diagramie aplikacja Google Chat przesyła taki przepływ informacji:

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

Wymagania wstępne

Python

Node.js

Java

Google Apps Script

Utwórz webhooka

Aby utworzyć webhooka, zarejestruj go w pokoju czatu, w którym chcesz otrzymywać wiadomości, a potem napisz skrypt, który wysyła wiadomości.

Rejestrowanie przychodzącego webhooka

  1. W przeglądarce otwórz Google Chat. Webhooków nie można konfigurować w aplikacji mobilnej Google Chat.
  2. Otwórz pokój, do którego chcesz dodać webhook.
  3. Obok tytułu pokoju kliknij strzałkę , aby rozwinąć więcej opcji, a następnie kliknij Aplikacje i integracje.
  4. Kliknij Dodaj webhooki.

  5. W polu Nazwa wpisz Quickstart Webhook.

  6. W polu 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.

Pisanie skryptu webhooka

Przykładowy skrypt webhooka wysyła wiadomość do pokoju, w którym webhook został zarejestrowany, przez wysłanie żądania POST na jego adres URL. Interfejs Chat API odpowiada instancji 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 narzędziu pom.xml skopiuj i wklej ten kod:

    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 aplikacji 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 New Project (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

Uruchom skrypt w interfejsie wiersza poleceń:

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 go zarejestrowano.

Rozpocznij wątek wiadomości lub odpowiedz na niego

  1. W treści żądania wiadomości podaj wartość spaces.messages.thread.threadKey. W zależności od tego, czy rozpoczynasz wątek, czy na niego odpowiadasz, użyj jednej z tych wartości w polu threadKey:

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

    • W przypadku odpowiadania w wątku podaj właściwość threadKey, która została ustawiona, gdy wątek się zaczynał. Aby na przykład opublikować odpowiedź w wątku, w którym pierwsza wiadomość zawierała MY-THREAD, ustaw MY-THREAD.

  2. Zdefiniuj zachowanie wątku, jeśli określony element threadKey nie zostanie znaleziony:

    • Odpowiedz w wątku lub zacznij nowy wątek. Do adresu URL webhooka dodaj parametr messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD. Przekazanie tego parametru adresu URL powoduje, że Google Chat wyszukuje istniejący wątek przy użyciu określonego parametru threadKey. Jeśli zostanie znaleziona, wiadomość zostanie opublikowany jako odpowiedź w tym wątku. Jeśli nie zostanie znaleziony, wiadomość rozpocznie nowy wątek odpowiadający temu zapytaniu 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 Google Chat wyszukuje istniejący wątek przy użyciu określonego parametru threadKey. Jeśli zostanie znaleziony, wiadomość zostanie opublikowana jako odpowiedź w tym wątku. Jeśli nie znaleziono żadnego, wiadomość nie została wysłana.

    Więcej informacji znajdziesz w artykule messageReplyOption.

Ten przykładowy kod rozpoczyna się w wątku wiadomości lub odpowiada na nie:

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ługa błędów

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

  • Nieprawidłowe żądanie.
  • Webhook lub pokój, w którym się znajduje, został usunięty.
  • Przejściowe problemy, takie jak brak połączenia sieciowego czy limity.

Podczas tworzenia webhooka należy odpowiednio obsługiwać błędy:

Interfejs API Google Chat zwraca błędy jako google.rpc.Status, co obejmuje błąd HTTP code, który wskazuje typ błędu: błąd klienta (seria 400) lub błąd serwera (seria 500). Aby przejrzeć wszystkie mapowania HTTP, otwórz google.rpc.Code.

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

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

Ograniczenia i uwagi

  • Gdy tworzysz wiadomość za pomocą webhooka w Google Chat API, odpowiedź nie zawiera pełnej wiadomości. Odpowiedź zawiera tylko pola name i thread.name.