Créer une application Google Chat en tant que webhook

Cette page explique comment configurer un webhook pour envoyer des messages asynchrones dans un espace Chat à l'aide de déclencheurs externes. Par exemple, vous pouvez configurer une application de surveillance pour avertir le personnel d'astreinte sur Chat lorsqu'un serveur tombe en panne. Pour envoyer un message synchrone avec une application Chat, consultez la section Envoyer un message.

Avec ce type de conception d'architecture, les utilisateurs ne peuvent pas interagir avec le webhook ni avec l'application externe connectée, car la communication est à sens unique. Les webhooks ne sont pas conversationnels. Ils ne peuvent pas répondre aux messages des utilisateurs ni recevoir de événements d'interaction avec l'application Chat. Pour répondre aux messages, créez une application Chat au lieu d'un webhook.

Bien qu'un webhook ne soit pas techniquement une application Chat (les webhooks connectent des applications à l'aide de requêtes HTTP standards), cette page l'appelle une application Chat pour simplifier. Chaque webhook ne fonctionne que dans l'espace Chat dans lequel il est enregistré. Les webhooks entrants fonctionnent dans les messages privés, mais uniquement lorsque toutes les applications Chat sont activées pour tous les utilisateurs. Vous ne pouvez pas publier de webhooks sur Google Workspace Marketplace.

Le schéma suivant illustre l'architecture d'un webhook connecté à Chat:

Architecture des webhooks entrants pour envoyer des messages asynchrones à Chat.

Dans le schéma précédent, le flux d'informations d'une application Chat est le suivant:

  1. La logique de l'application Chat reçoit des informations de services tiers externes, tels qu'un système de gestion de projet ou un outil de gestion des tickets.
  2. La logique de l'application Chat est hébergée dans un système cloud ou sur site qui peut envoyer des messages à l'aide d'une URL de webhook vers un espace Chat spécifique.
  3. Les utilisateurs peuvent recevoir des messages de l'application Chat dans cet espace Chat spécifique, mais ne peuvent pas interagir avec l'application Chat.

Prérequis

Python

Node.js

Java

Apps Script

Créer un webhook

Pour créer un webhook, enregistrez-le dans l'espace Chat dans lequel vous souhaitez recevoir des messages, puis écrivez un script qui envoie des messages.

Enregistrer le webhook entrant

  1. Dans un navigateur, ouvrez Chat. Les webhooks ne sont pas configurables depuis l'application mobile Chat.
  2. Accédez à l'espace dans lequel vous souhaitez ajouter un webhook.
  3. À côté du titre du salon, cliquez sur la flèche de développement , puis sur Applications et intégrations.
  4. Cliquez sur Ajouter des webhooks.

  5. Dans le champ Nom, saisissez Quickstart Webhook.

  6. Dans le champ URL de l'avatar, saisissez https://developers.google.com/chat/images/chat-product-icon.png.

  7. Cliquez sur Enregistrer.

  8. Pour copier l'URL du webhook, cliquez sur Plus, puis sur Copier le lien.

Écrire le script du webhook

L'exemple de script de webhook envoie un message à l'espace dans lequel le webhook est enregistré en envoyant une requête POST à l'URL du webhook. L'API Chat répond avec une instance de Message.

Sélectionnez une langue pour découvrir comment créer un script de webhook:

Python

  1. Dans votre répertoire de travail, créez un fichier nommé quickstart.py.

  2. Dans quickstart.py, collez le code suivant:

    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. Remplacez la valeur de la variable url par l'URL du webhook que vous avez copiée lorsque vous l'avez enregistré.

Node.js

  1. Dans votre répertoire de travail, créez un fichier nommé index.js.

  2. Dans index.js, collez le code suivant:

    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. Remplacez la valeur de la variable url par l'URL du webhook que vous avez copiée lorsque vous l'avez enregistré.

Java

  1. Dans votre répertoire de travail, créez un fichier nommé pom.xml.

  2. Dans pom.xml, copiez et collez le code suivant:

    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. Dans votre répertoire de travail, créez la structure de répertoire src/main/java suivante.

  4. Dans le répertoire src/main/java, créez un fichier nommé App.java.

  5. Dans App.java, collez le code suivant:

    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. Remplacez la valeur de la variable URL par l'URL du webhook que vous avez copiée lorsque vous l'avez enregistré.

Apps Script

  1. Dans un navigateur, accédez à Apps Script.

  2. Cliquez sur Nouveau projet.

  3. Collez le code suivant :

    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. Remplacez la valeur de la variable url par l'URL du webhook que vous avez copiée lorsque vous l'avez enregistré.

Exécuter le script du webhook

Dans une CLI, exécutez le script:

Python

  python3 quickstart.py

Node.js

  node index.js

Java

  mvn compile exec:java -Dexec.mainClass=App

Apps Script

  • Cliquez sur Exécuter.

Lorsque vous exécutez le code, le webhook envoie un message à l'espace dans lequel vous l'avez enregistré.

Démarrer ou répondre à un fil de discussion

  1. Spécifiez spaces.messages.thread.threadKey dans le corps de la requête de message. Selon que vous démarrez ou répondez à un fil de discussion, utilisez les valeurs suivantes pour threadKey:

    • Si vous démarrez un fil de discussion, définissez threadKey sur une chaîne arbitraire, mais notez cette valeur pour publier une réponse au fil de discussion.

    • Si vous répondez à un fil de discussion, spécifiez le threadKey défini au début du fil. Par exemple, pour publier une réponse au fil de discussion dans lequel le message initial a utilisé MY-THREAD, définissez MY-THREAD.

  2. Définissez le comportement du thread si le threadKey spécifié n'est pas trouvé:

    • Répondez à un fil de discussion ou en démarrez un nouveau. Ajoutez le paramètre messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD à l'URL du webhook. Si vous transmettez ce paramètre d'URL, Chat recherche un fil de discussion existant à l'aide de l'threadKey spécifiée. Si un fil de discussion est trouvé, le message est publié en réponse à ce fil. Si aucun n'est trouvé, le message démarre un nouveau thread correspondant à ce threadKey.

    • Répondez à un fil de discussion ou ne faites rien. Ajoutez le paramètre messageReplyOption=REPLY_MESSAGE_OR_FAIL à l'URL du webhook. Si vous transmettez ce paramètre d'URL, Chat recherche un fil de discussion existant à l'aide de l'threadKey spécifié. Si un fil de discussion est trouvé, le message est publié en réponse à ce fil. Si aucun n'est trouvé, le message n'est pas envoyé.

    Pour en savoir plus, consultez messageReplyOption.

L'exemple de code suivant démarre ou répond à un fil de discussion:

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

Gérer les erreurs

Les requêtes webhook peuvent échouer pour différentes raisons, y compris les suivantes:

  • Demande incorrecte.
  • Le webhook ou l'espace qui l'héberge est supprimé.
  • Problèmes intermittents tels que la connectivité réseau ou les limites de quota

Lorsque vous créez votre webhook, vous devez gérer les erreurs de manière appropriée en procédant comme suit:

L'API Google Chat renvoie les erreurs sous la forme d'un google.rpc.Status, qui inclut une erreur HTTP code qui indique le type d'erreur rencontré: une erreur client (série 400) ou une erreur serveur (série 500). Pour consulter toutes les mises en correspondance HTTP, consultez google.rpc.Code.

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

Pour savoir comment interpréter les codes d'état HTTP et gérer les erreurs, consultez la section Erreurs.

Limites et points à noter

  • Lorsque vous créez un message avec un webhook dans l'API Google Chat, la réponse ne contient pas le message complet. La réponse ne renseigne que les champs name et thread.name.
  • Les webhooks sont soumis à la limite de requêtes spaces.messages.create par espace de 60 par 60 secondes, partagée entre toutes les applications Chat de l'espace. Pour en savoir plus sur les quotas de l'API Chat, consultez la section Limites d'utilisation.