Send messages to Google Chat with incoming webhooks

Incoming webhooks let you send asynchronous messages into Google Chat from applications that aren't Chat apps. For example, you can configure a monitoring application to notify on-call personnel on Google Chat when a server goes down.

To asynchronously send, update, or delete a message in a Chat space with a Chat app, see Create, read, update, delete messages.

Architecture for incoming webhooks to send asynchronous messages to Google Chat.

Prerequisites

To run the example in this guide, you need:

Python

  • Python 3.10.7 or greater.
  • Access to the internet and a web browser.
  • A Google Workspace account with access to Google Chat.
  • An existing Google Chat space.
  • The httplib2 library. If necessary, run the following command-line interface (CLI) command to install the library using pip:

    pip install httplib2
    

Node.js

Apps Script

Java

Create a webhook

To create a webhook, register it in the Google Chat space you want to receive messages, then write a script that sends messages.

Step 1: Register the incoming webhook

  1. In a web browser, open Google Chat.
  2. Go to the space to which you want to add a webhook.
  3. At the top, next to space title, click Down Arrow > Apps & integrations.
  4. Click Manage webhooks.
  5. If this space already has other webhooks, click Add another. Otherwise, skip this step.
  6. For Name, enter "Quickstart Webhook".
  7. For Avatar URL, enter https://developers.google.com/chat/images/chat-product-icon.png.
  8. Click SAVE.
  9. To copy the full webhook URL, click Copy.
  10. Click outside the box to close the Incoming webhooks dialog.

Step 2: Write the webhook script

The example webhook script posts a message to the space in which the webhook is registered by POSTing a create message request to the webhook URL. Google Chat API responds with an instance of Message.

Choose a language below for specific instructions about how to create the webhook script:

Python

  1. In your working directory, create a file named quickstart.py.

  2. In quickstart.py, copy and paste the following code:

    python/webhook/quickstart.py
    from json import dumps
    
    from httplib2 import Http
    
    WEBHOOK_URL = "[URL FROM WEBHOOK]"
    
    def main():
        """Google Chat incoming webhook quickstart."""
        url = WEBHOOK_URL
        bot_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(bot_message),
        )
        print(response)
    
    
    if __name__ == '__main__':
        main()
  3. Replace the value for the url variable with the webhook URL you copied in Step 1: Register the incoming webhook.

Node.js

  1. In your working directory, create a file named index.js.

  2. In index.js, copy and paste the following code:

    node/webhook/index.js
    /**
     * Sends asynchronous message into Google Chat
     * @return{obj} response
     */
    function webhook() {
      const fetch = require('node-fetch');
      const webhookURL = 'https://chat.googleapis.com/v1/spaces/AAAAGCYeSRY/messages?key=AIzaSyDdI0hCZtE6vySjMm-WEfRq3CPzqKqqsHI&token=u9IG_MuTBXw-tnqupPrPNinY2spKFcRBDp6dSldGUAw%3D';
    
      const data = JSON.stringify({
        'text': 'Hello from a Node script!',
      });
      let resp;
      fetch(webhookURL, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json; charset=UTF-8',
        },
        body: data,
      }).then((response) => {
        resp = response;
        console.log(response);
      });
      return resp;
    }
    
  3. Replace the value for the webhookURL variable with the webhook URL you copied in Step 1: Register the incoming webhook.

Apps Script

  1. Go to the Apps Script page.

  2. Click New Project

  3. Copy-and-paste the following code:

    apps-script/webhook/webhook.gs
    function webhook() {
      const url = "https://chat.googleapis.com/v1/spaces/AAAAGCYeSRY/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);
      Logger.log(response);
    }
  4. Replace the value for the url variable with the webhook URL you copied in Step 1: Register the incoming webhook.

Java

  1. In your working directory, create a file named pom.xml.

  2. In pom.xml, copy and paste the following:

    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.hangouts.chat.webhook</groupId>
      <artifactId>java-webhook-app</artifactId>
      <version>0.1.0</version>
    
      <name>java-webhook-app</name>
      <url>https://github.com/googleworkspace/hangouts-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. In your working directory, create the following directory structure src/main/java.

  4. In the src/main/java directory, create a file named App.java.

  5. In App.java, copy and paste the following code:

    java/webhook/src/main/java/com/google/hangouts/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. Replace the value for the URL variable with the webhook URL you copied in Step 1: Register the incoming webhook.

Step 3: Run the webhook script

Run the sample by running the following command from your working directory in your CLI:

Python

  python3 quickstart.py

Node.js

  node index.js

Apps Script

  • Click Run

Java

  mvn compile exec:java -Dexec.mainClass=App

When you run the sample code, the webhook sends a message to the space in which you registered it.

Start or reply to a message thread

You can start a message thread or reply to one by adding the threadKey parameter to the webhook URL. Each threadKey is unique to the app that sets it. If two different Chat apps or webhooks set the same threadKey, two different threads start.

Start a message thread

To post the first message of a thread with a webhook, append the threadKey and messageReplyOption parameters to the webhook URL. Set the threadKey to an arbitrary string, but remember what it is; you'll need to specify it again to post a reply to the thread.

  https://chat.googleapis.com/v1/spaces/SPACE_ID/messages?threadKey=ARBITRARY_STRING&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD

Reply to a message thread

To send a message to an existing message thread, append the threadKey and messageReplyOption parameters to the webhook URL set to the value used to start the thread. For example, sending a message to following URL posts a reply to the thread where threadKey is MY-THREAD and messageReplyOption is REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD:

  https://chat.googleapis.com/v1/spaces/SPACE_ID/messages?threadKey=MY-THREAD&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD

Limits and considerations

As you configure webhooks, take note of these limits and considerations:

  • Each webhook only works in the Chat space in which it's registered.

  • You can't publish webhooks on the Google Workspace Marketplace.

  • Webhooks aren't conversational. They can't respond to or receive messages from users or events from Google Chat.

  • If only select organizational units (OUs) in your domain have Chat apps enabled, incoming webhooks return the following error:

    {
      "error": {
        "code": 403,
        "message": "The caller does not have permission",
        "status": "PERMISSION_DENIED"
      }
    }
    
  • Incoming webhooks work in direct messages, but only when all users have Chat apps enabled.

  • Because The icon for manage webhooks Manage webhooks is only available from a web browser, webhooks must be set up from the Chat web app. Webhooks are not configurable from the Chat mobile app.