Creare un'app Google Chat come webhook

Questa pagina descrive come configurare un webhook per inviare messaggi asincroni in uno spazio Chat utilizzando trigger esterni. Ad esempio, puoi configurare un'applicazione di monitoraggio per inviare una notifica al personale di reperibilità su Chat quando un server è inattivo. Per inviare un messaggio sincrono con un'app di chat, vedi Inviare un messaggio.

Con questo tipo di architettura, gli utenti non possono interagire con il webhook o con l'applicazione esterna connessa perché la comunicazione è unidirezionale. I webhook non sono conversazionali. Non possono rispondere o ricevere messaggi da utenti o eventi di interazione dell'app Chat. Per rispondere ai messaggi, crea un'app Chat anziché un webhook.

Anche se tecnicamente un webhook non è un'app Chat (i webhook collegano le applicazioni utilizzando richieste HTTP standard), questa pagina lo definisce un'app Chat per semplificare la terminologia. Ogni webhook funziona solo nello spazio di Chat in cui è registrato. I webhook in entrata funzionano nei messaggi diretti, ma solo quando tutti gli utenti hanno attivato le app di chat. Non puoi pubblicare webhook su Google Workspace Marketplace.

Il seguente diagramma mostra l'architettura di un webhook connesso a Chat:

Architettura per i webhook in entrata per inviare messaggi asincroni a Chat.

Nel diagramma precedente, un'app Chat ha il seguente flusso di informazioni:

  1. La logica dell'app Chat riceve informazioni da servizi esterni di terze parti, ad esempio un sistema di gestione dei progetti o uno strumento di gestione dei ticket.
  2. La logica dell'app Chat è ospitata in un sistema cloud o on-premise che può inviare messaggi utilizzando un URL webhook a uno spazio Chat specifico.
  3. Gli utenti possono ricevere messaggi dall'app Chat in quello spazio Chat specifico, ma non possono interagire con l'app Chat.

Prerequisiti

Python

Node.js

Java

Apps Script

Creare un webhook

Per creare un webhook, registralo nello spazio Chat in cui vuoi ricevere i messaggi, quindi scrivi uno script che invii i messaggi.

Registra il webhook in entrata

  1. In un browser, apri Chat. I webhook non sono configurabili dall'app mobile Chat.
  2. Vai allo spazio in cui vuoi aggiungere un webhook.
  3. Accanto al titolo dello spazio, fai clic sulla freccia di espansione Altro e poi su App e integrazioni.
  4. Fai clic su Aggiungi webhook.

  5. Nel campo Nome, inserisci Quickstart Webhook.

  6. Nel campo URL avatar, inserisci https://developers.google.com/chat/images/chat-product-icon.png.

  7. Fai clic su Salva.

  8. Per copiare l'URL del webhook, fai clic su Altro e poi su Copia link.

Scrivere lo script webhook

Lo script webhook di esempio invia un messaggio allo spazio in cui il webhook è registrato inviando una richiesta POST all'URL webhook. L'API Chat risponde con un'istanza di Message.

Seleziona una lingua per scoprire come creare uno script webhook:

Python

  1. Nella directory di lavoro, crea un file denominato quickstart.py.

  2. In quickstart.py, incolla il seguente codice:

    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. Sostituisci il valore della variabile url con l'URL webhook che hai copiato quando hai registrato il webhook.

Node.js

  1. Nella directory di lavoro, crea un file denominato index.js.

  2. In index.js, incolla il seguente codice:

    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. Sostituisci il valore della variabile url con l'URL webhook che hai copiato quando hai registrato il webhook.

Java

  1. Nella directory di lavoro, crea un file denominato pom.xml.

  2. In pom.xml, copia e incolla quanto segue:

    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. Nella directory di lavoro, crea la seguente struttura di directory src/main/java.

  4. Nella directory src/main/java, crea un file denominato App.java.

  5. In App.java, incolla il seguente codice:

    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. Sostituisci il valore della variabile URL con l'URL del webhook che hai copiato quando hai registrato il webhook.

Apps Script

  1. In un browser, vai a Apps Script.

  2. Fai clic su Nuovo progetto.

  3. Incolla il seguente codice:

    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. Sostituisci il valore della variabile url con l'URL del webhook che hai copiato quando hai registrato il webhook.

Esegui lo script webhook

In un'interfaccia a riga di comando, esegui lo script:

Python

  python3 quickstart.py

Node.js

  node index.js

Java

  mvn compile exec:java -Dexec.mainClass=App

Apps Script

  • Fai clic su Esegui.

Quando esegui il codice, il webhook invia un messaggio allo spazio in cui lo hai registrato.

Avviare o rispondere a un thread di messaggi

  1. Specifica spaces.messages.thread.threadKey come parte del corpo della richiesta di messaggio. A seconda che tu stia avviando o rispondendo a un thread, utilizza i seguenti valori per threadKey:

    • Se avvii un thread, imposta threadKey su una stringa arbitraria, ma prendi nota di questo valore per pubblicare una risposta al thread.

    • Se rispondi a un thread, specifica il threadKey impostato all'avvio del thread. Ad esempio, per pubblicare una risposta al thread in cui il messaggio iniziale utilizzava MY-THREAD, imposta MY-THREAD.

  2. Definisci il comportamento del thread se non viene trovato threadKey specificato:

    • Rispondi a un thread o avviane uno nuovo. Aggiungi il parametro messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD all'URL del webhook. Il passaggio di questo parametro URL fa sì che Chat cerchi un thread esistente utilizzando il threadKey specificato. Se ne viene trovato uno, il messaggio viene pubblicato come risposta a quel thread. Se non viene trovato, il messaggio avvia un nuovo thread corrispondente a quel threadKey.

    • Rispondi a un thread o non fare nulla. Aggiungi il parametro messageReplyOption=REPLY_MESSAGE_OR_FAIL all'URL webhook. Il passaggio di questo parametro URL fa sì che Chat cerchi un thread esistente utilizzando il threadKey specificato. Se ne viene trovato uno, il messaggio viene pubblicato come risposta a quel thread. Se non viene trovato alcun contatto, il messaggio non viene inviato.

    Per saperne di più, consulta la pagina messageReplyOption.

Il seguente codice campione avvia o risponde a un thread di messaggi:

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

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

Gestisci gli errori

Le richieste webhook possono non riuscire per diversi motivi, tra cui:

  • Richiesta non valida.
  • Il webhook o lo spazio che lo ospita viene eliminato.
  • Problemi intermittenti come la connettività di rete o i limiti di quota.

Quando crei il webhook, devi gestire gli errori in modo appropriato:

  • Registrazione dell'errore.
  • Per gli errori basati su tempo, quota o connettività di rete, riprova la richiesta con backoff esponenziale.
  • Non fare nulla, il che è appropriato se l'invio del messaggio webhook non è importante.

L'API Google Chat restituisce gli errori come google.rpc.Status, che include un errore HTTP code che indica il tipo di errore riscontrato: un errore client (serie 400) o un errore server (serie 500). Per esaminare tutti i mapping HTTP, consulta google.rpc.Code.

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

Per scoprire come interpretare i codici di stato HTTP e gestire gli errori, consulta la sezione Errori.

Limitazioni e considerazioni

  • Quando crei un messaggio con un webhook nell'API Google Chat, la risposta non contiene il messaggio completo. La risposta compila solo i campi name e thread.name.
  • I webhook sono soggetti alla quota per spazio per spaces.messages.create: 1 richiesta al secondo, condivisa tra tutti i webhook dello spazio. Chat potrebbe anche rifiutare le richieste webhook che superano 1 query al secondo nello stesso spazio. Per ulteriori informazioni sulle quote dell'API Chat, consulta Limiti di utilizzo.