将 Google Chat 应用构建为网络钩子

本页面介绍了如何设置网络钩子以将异步消息发送到 使用外部触发器的 Chat 聊天室。例如,您可以 配置监控应用程序以通知值班人员 在服务器出现故障时聊天。发送同步消息 使用 Chat 应用,请参阅 发送消息

这种类型的架构 因此用户无法与 webhook 或已连接的外部 因为通信是单向的网络钩子不是对话式的。 他们无法回复或接收来自用户的消息, Chat 应用互动事件。 如需回复消息,请按以下步骤操作: 构建 Chat 扩展应用 而不是网络钩子

虽然网络钩子从技术层面来讲 Chat 应用 - Webhook 使用标准 HTTP 请求 - 此页面称其为用于 简化。每个网络钩子只能在以下国家/地区的 Chat 聊天室中使用: 它已注册传入的网络钩子适用于私信,但前提是 所有用户均有 已启用聊天应用。 您无法将网络钩子发布到 Google Workspace Marketplace。

下图显示了将 Webhook 连接到 聊天:

用于向 Chat 发送异步消息的传入网络钩子的架构。

在上图中,Chat 应用具有以下特征 信息流:

  1. Chat 应用逻辑会从 外部第三方服务(例如项目管理系统或 票务工具
  2. Chat 应用逻辑托管在云端或 该系统本地系统,该系统可以使用 webhook 网址发送到 特定 Chat 聊天室。
  3. 用户可以在以下应用中接收来自 Chat 应用的消息: 但无法与对方聊天 Chat 应用。

前提条件

Python

  • Business 或 Enterprise 有权访问以下内容的 Google Workspace 账号: Google Chat。 您的 Google Workspace 组织必须允许用户 添加和使用传入的网络钩子
  • Python 3.6 或更高版本
  • pip 软件包管理工具
  • httplib2 库。如需安装该库,请在命令行界面中运行以下命令:

    pip install httplib2
    
  • Google Chat 聊天室。如要使用 Google Chat API 创建联系人,请参阅 创建聊天室。要在 Chat 中创建账号,请执行以下操作: 请访问 帮助中心文档

Node.js

Java

Apps 脚本

创建网络钩子

如要创建网络钩子,请在您要创建的 Chat 聊天室中注册该网络钩子 来接收消息,然后编写一个发送消息的脚本。

注册传入的网络钩子

  1. 在浏览器中,打开 聊天。 无法通过 Chat 移动应用配置网络钩子。
  2. 前往您要添加网络钩子的聊天室。
  3. 点击相应聊天室标题旁边的 展开箭头,然后点击应用和集成
  4. 点击 Add webhooks

  5. 名称字段中,输入 Quickstart Webhook

  6. 头像网址字段中,输入 https://developers.google.com/chat/images/chat-product-icon.png

  7. 点击保存

  8. 如需复制网络钩子网址,请点击 更多,然后点击 复制链接

编写 webhook 脚本

网络钩子脚本示例将一条消息发送到 方法是向网络钩子网址发送 POST 请求。通过 Chat API 会返回一个 Message

选择一种语言,了解如何创建网络钩子脚本:

Python

  1. 在您的工作目录中,创建一个名为 quickstart.py 的文件。

  2. quickstart.py 中,粘贴以下代码:

    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. url 变量的值替换为 是在注册网络钩子时复制的。

Node.js

  1. 在您的工作目录中,创建一个名为 index.js 的文件。

  2. index.js 中,粘贴以下代码:

    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. url 变量的值替换为 是您在注册网络钩子时复制的

Java

  1. 在您的工作目录中,创建一个名为 pom.xml 的文件。

  2. pom.xml 中,复制并粘贴以下内容:

    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. 在您的工作目录中,创建以下目录结构 src/main/java

  4. src/main/java 目录中,创建一个名为 App.java 的文件。

  5. App.java 中,粘贴以下代码:

    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. URL 变量的值替换为您 是在注册 webhook 时复制的。

Apps 脚本

  1. 在浏览器中,转到 Apps 脚本

  2. 点击 New Project

  3. 粘贴以下代码:

    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. url 变量的值替换为您 是在注册 webhook 时复制的。

运行 webhook 脚本

在 CLI 中,运行以下脚本:

Python

  python3 quickstart.py

Node.js

  node index.js

Java

  mvn compile exec:java -Dexec.mainClass=App

Apps 脚本

  • 点击运行

运行代码时,webhook 会将一条消息发送到 已经注册它

发起或回复消息串

  1. 指定 spaces.messages.thread.threadKey 作为消息请求正文的一部分。具体取决于您是开始 回复会话时,请为 threadKey 使用以下值:

    • 如果要启动线程,请将 threadKey 设置为任意字符串,但 记下该值以向主题帖发布回复。

    • 如果要回复某个会话,请指定在threadKey 会话串已启动。例如,要发布对包含 初始消息使用 MY-THREAD,设置 MY-THREAD

  2. 定义找不到指定的 threadKey 时的线程行为:

    • 回复消息串或发起新消息串。将 将 messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD 参数设为 网络钩子网址传递此网址参数会导致 Chat 使用指定的 threadKey 查找现有线程。如果有 ,则会将该帖子作为回复发布到该会话。如果没有 则相应消息会发起与其对应的新会话 threadKey

    • 回复消息串或不执行任何操作。将 messageReplyOption=REPLY_MESSAGE_OR_FAIL 参数添加到网络钩子网址。 传递此网址参数会导致 Chat 使用指定的 threadKey 查找现有线程。如果有 该会话,则会将该帖子作为回复发布到该会话。如果没有 则该邮件不会被发送。

    如需了解详情,请参阅 messageReplyOption

以下代码示例可发起或回复消息串:

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 脚本

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