Создайте приложение Google Chat в качестве веб-перехватчика.

На этой странице описано, как настроить веб-перехватчик для отправки асинхронных сообщений в пространство чата с использованием внешних триггеров. Например, вы можете настроить приложение мониторинга для уведомления дежурного персонала в чате о сбое сервера. Чтобы отправить синхронное сообщение с помощью приложения чата, см. раздел «Отправка сообщения» .

При таком типе архитектуры пользователи не могут взаимодействовать с веб-хуком или подключенным внешним приложением, поскольку связь односторонняя. Веб-хуки не являются диалоговыми. Они не могут отвечать на сообщения пользователей или получать сообщения от них, а также обрабатывать события взаимодействия в чат-приложении . Для ответа на сообщения следует создавать чат-приложение вместо веб-хука.

Хотя веб-хук технически не является приложением чата — веб-хуки соединяют приложения с помощью стандартных HTTP-запросов — на этой странице он упоминается как приложение чата для упрощения. Каждый веб-хук работает только в том пространстве чата, в котором он зарегистрирован. Входящие веб-хуки работают в личных сообщениях, но только если у всех пользователей включены приложения чата . Вы не можете публиковать веб-хуки в Google Workspace Marketplace.

На следующей диаграмме показана архитектура веб-перехватчика, подключенного к чату:

Архитектура для обработки входящих веб-хуков, позволяющая отправлять асинхронные сообщения в чат.

На приведенной выше диаграмме показан следующий поток информации в чат-приложении:

  1. Логика приложения «Чат» получает информацию от внешних сторонних сервисов, таких как система управления проектами или система обработки заявок.
  2. Логика чат-приложения размещается либо в облачной, либо в локальной системе и может отправлять сообщения, используя URL-адрес веб-перехватчика, в определенное пространство чата.
  3. Пользователи могут получать сообщения от приложения «Чат» в конкретном чате, но не могут взаимодействовать с самим приложением «Чат».

Предварительные требования

Node.js

Python

Java

Apps Script

Создайте веб-перехватчик

Чтобы создать веб-хук, зарегистрируйте его в чате, куда вы хотите получать сообщения, а затем напишите скрипт, который будет отправлять эти сообщения.

Зарегистрируйте входящий веб-перехватчик

  1. Откройте приложение «Чат» в браузере. Веб-хуки нельзя настроить в мобильном приложении «Чат».
  2. Перейдите в раздел, куда вы хотите добавить веб-хук.
  3. Рядом с названием пространства нажмите стрелку , а затем нажмите «Приложения и интеграции» .
  4. Нажмите «Добавить веб-перехватчики» .

  5. В поле «Имя» введите Quickstart Webhook .

  6. В поле «URL аватара» введите https://developers.google.com/chat/images/chat-product-icon.png .

  7. Нажмите « Сохранить ».

  8. Чтобы скопировать URL-адрес веб-перехватчика, нажмите More , а затем Copy link .

    URL веб-перехватчика содержит два параметра: key , общее значение, используемое всеми веб-перехватчиками, и token , уникальное значение, которое необходимо хранить в секрете для обеспечения безопасности вашего веб-перехватчика.

Напишите скрипт веб-перехватчика.

В приведенном примере скрипт веб-перехватчика отправляет сообщение в пространство, где он зарегистрирован, путем отправки POST запроса на URL-адрес веб-перехватчика. API чата отвечает экземпляром объекта Message .

Выберите язык, чтобы узнать, как создать скрипт веб-перехватчика:

Node.js

  1. В рабочей директории создайте файл с именем index.js .

  2. В index.js вставьте следующий код:

    solutions/webhook-chat-app/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?key=KEY&token=TOKEN"
      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. Замените значение переменной url на URL-адрес веб-перехватчика, который вы скопировали при регистрации веб-перехватчика.

Python

  1. В рабочей директории создайте файл с именем quickstart.py .

  2. В файл quickstart.py вставьте следующий код:

    solutions/webhook-chat-app/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. Замените значение переменной url на URL-адрес веб-перехватчика, который вы скопировали при регистрации веб-перехватчика.

Java

  1. В рабочей директории создайте файл с именем pom.xml .

  2. В pom.xml скопируйте и вставьте следующее:

    solutions/webhook-chat-app/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>webhook-app</artifactId>
      <version>0.1.0</version>
      <name>webhook-app</name>
    
      <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. В вашей рабочей директории создайте следующую структуру каталогов src/main/java .

  4. В каталоге src/main/java создайте файл с именем App.java .

  5. В App.java вставьте следующий код:

    solutions/webhook-chat-app/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/SPACE_ID/messages?key=KEY&token=TOKEN";
      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. Замените значение переменной URL на URL-адрес веб-перехватчика, который вы скопировали при регистрации веб-перехватчика.

Apps Script

  1. В браузере перейдите в раздел Apps Script .

  2. Нажмите «Новый проект».

  3. Вставьте следующий код:

    solutions/webhook-chat-app/webhook.gs
    function webhook() {
      const url = "https://chat.googleapis.com/v1/spaces/SPACE_ID/messages?key=KEY&token=TOKEN"
      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. Замените значение переменной url на URL-адрес веб-перехватчика, который вы скопировали при регистрации веб-перехватчика.

Запустите скрипт веб-перехватчика

В командной строке запустите скрипт:

Node.js

  node index.js

Python

  python3 quickstart.py

Java

  mvn compile exec:java -Dexec.mainClass=App

Apps Script

  • Нажмите «Выполнить» .

При запуске кода веб-хук отправляет сообщение в то пространство, в котором вы его зарегистрировали.

Начать или ответить на сообщение в ветке обсуждения

  1. Укажите spaces.messages.thread.threadKey в теле запроса сообщения. В зависимости от того, начинаете ли вы обсуждение или отвечаете на него, используйте следующие значения для threadKey :

    • При создании темы установите threadKey в произвольную строку, но запишите это значение, чтобы отправить ответ в тему.

    • При ответе на ветку обсуждения укажите ключ threadKey , который был установлен при её создании. Например, чтобы отправить ответ на ветку, где в исходном сообщении использовался MY-THREAD , установите MY-THREAD .

  2. Определите поведение потока, если указанный threadKey не найден:

    • Ответьте на существующую ветку обсуждения или создайте новую. Добавьте параметр messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD к URL-адресу веб-перехватчика. Передача этого параметра URL-адреса заставляет Chat искать существующую ветку обсуждения, используя указанный threadKey . Если ветка найдена, сообщение отправляется в качестве ответа на эту ветку. Если ветка не найдена, сообщение создает новую ветку обсуждения, соответствующую указанному threadKey .

    • Ответить на ветку обсуждения или ничего не делать. Добавьте параметр messageReplyOption=REPLY_MESSAGE_OR_FAIL к URL-адресу веб-перехватчика. Передача этого параметра URL-адреса заставляет Chat искать существующую ветку обсуждения, используя указанный threadKey . Если ветка найдена, сообщение отправляется в качестве ответа на эту ветку. Если ветка не найдена, сообщение не отправляется.

    Для получения более подробной информации см. messageReplyOption .

Приведенный ниже пример кода запускает цепочку сообщений или отвечает на нее:

Node.js

solutions/webhook-chat-app/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));

Python

solutions/webhook-chat-app/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()

Java

solutions/webhook-chat-app/src/main/java/com/google/chat/webhook/AppThread.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/SPACE_ID/messages?key=KEY&token=TOKEN&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD";
  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!",
      "thread", Map.of(
        "threadKey", "THREAD_KEY_VALUE"
      )
    ));

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

Apps Script

solutions/webhook-chat-app/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);
}

Обработка ошибок

Запросы через веб-перехватчик могут завершаться неудачей по различным причинам, в том числе:

  • Неверный запрос.
  • Веб-хук или пространство, на котором он размещен, удаляется.
  • Периодические проблемы, такие как проблемы с подключением к сети или ограничениями по квоте.

При создании веб-хука следует надлежащим образом обрабатывать ошибки следующим образом:

API Google Chat возвращает ошибки в виде объекта google.rpc.Status , который содержит code ошибки HTTP, указывающий на тип возникшей ошибки: ошибка клиента (серия 400) или ошибка сервера (серия 500). Чтобы просмотреть все сопоставления HTTP, см. google.rpc.Code .

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

Чтобы узнать, как интерпретировать коды состояния HTTP и обрабатывать ошибки, см. раздел «Ошибки» .

Ограничения и соображения

  • При создании сообщения с помощью веб-хука в Google Chat API ответ не содержит полного сообщения. В ответе заполняются только поля name и thread.name .
  • Для вебхуков действует квота spaces.messages.create на одно пространство: 1 запрос в секунду, распределяемый между всеми вебхуками в пространстве. Чат также может отклонять запросы вебхуков, превышающие 1 запрос в секунду в том же пространстве. Дополнительную информацию о квотах API чата см. в разделе «Ограничения использования» .