將 Google Chat 應用程式建構為 Webhook

本頁說明如何設定 Webhook,使用外部觸發條件將非同步訊息傳送至 Chat 聊天室。例如,您可以設定監控應用程式,以便在伺服器故障時,通知即時通訊人員。如要透過 Chat 應用程式傳送同步訊息,請參閱「傳送訊息」。

使用這種架構設計時,使用者無法與 Webhook 或連線的外部應用程式互動,因為通訊是單向的。Webhook 並非對話式。無法回覆或接收來自使用者的訊息或 Chat 應用程式互動事件。如要回應訊息,請建構 Chat 應用程式,而非 Webhook。

雖然技術上來說 Webhook 並非 Chat 應用程式 (亦即 Webhook 使用標準 HTTP 要求連結應用程式),但本頁將 Webhook 稱為 Chat 應用程式以利簡化。每個 Webhook 僅適用於註冊的 Chat 聊天室。傳入的 Webhook 可在即時訊息中運作,但只有在所有使用者已啟用 Chat 擴充應用程式時才能使用。您無法將 Webhook 發布至 Google Workspace Marketplace。

下圖顯示連線至 Chat 的 Webhook 架構:

將非同步訊息傳送至 Chat 的連入 Webhook 架構。

在上圖中,Chat 應用程式含有下列資訊流:

  1. Chat 應用程式邏輯會接收來自外部第三方服務的資訊,例如專案管理系統或票證工具。
  2. Chat 應用程式邏輯託管於雲端或內部部署系統,可以使用 Webhook 網址向特定 Chat 聊天室傳送訊息。
  3. 使用者可以接收該特定 Chat 聊天室中的 Chat 應用程式訊息,但無法與 Chat 應用程式互動。

必要條件

Python

  • 可存取 ChatGoogle Workspace 帳戶。您的 Google Workspace 機構必須允許使用者新增及使用連入的 Webhook
  • Python 3.10.7 以上版本。
  • httplib2 程式庫。如有需要,請執行下列指令列介面 (CLI) 指令,使用 pip 安裝程式庫:

    pip install httplib2
    
  • 現有的 Chat 聊天室。

Node.js

Java

Apps Script

建立 Webhook

如要建立 Webhook,請在要接收訊息的 Chat 聊天室中註冊 Webhook,然後編寫用來傳送訊息的指令碼。

註冊連入 Webhook

  1. 在瀏覽器中開啟 Chat。無法透過 Chat 行動應用程式設定 Webhook。
  2. 前往要新增 Webhook 的聊天室。
  3. 按一下聊天室標題旁邊的「展開更多」箭頭圖示 ,然後點選「應用程式與整合」
  4. 按一下 「Add Webhooks」(新增 Webhook)

  5. 在「Name」欄位中輸入 Quickstart Webhook

  6. 在「顯示圖片網址」欄位中輸入 https://developers.google.com/chat/images/chat-product-icon.png

  7. 點選「儲存」

  8. 如要複製 Webhook 網址,請依序點選 「更多」圖示「複製連結」

編寫 Webhook 指令碼

範例 Webhook 指令碼會傳送 POST 要求至 Webhook 網址,藉此將訊息傳送至註冊 Webhook 的聊天室。Chat API 會使用 Message 例項回應。

請選取語言,瞭解如何建立 Webhook 指令碼:

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 變數的值替換成您在註冊 Webhook 時複製的 Webhook 網址。

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 變數的值替換成您在註冊 Webhook 時複製的 Webhook 網址。

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 時複製的 Webhook 網址。

Apps Script

  1. 使用瀏覽器前往 Apps Script

  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 網址。

執行 Webhook 指令碼

在 CLI 中,執行指令碼:

Python

  python3 quickstart.py

Node.js

  node index.js

Java

  mvn compile exec:java -Dexec.mainClass=App

Apps Script

  • 點按「執行」

執行程式碼時,Webhook 會將訊息傳送至您註冊程式碼的聊天室。

發起或回覆訊息串

  1. 請將 spaces.messages.thread.threadKey 指定為訊息要求主體的一部分。根據您要啟動還是回覆執行緒,使用以下的 threadKey 值:

    • 如要啟動執行緒,請將 threadKey 設為任意字串,但請記下這個值,才能在執行緒上發布回覆。

    • 如要回覆執行緒,請指定在啟動執行緒時設定的 threadKey。舉例來說,如要針對初始訊息使用 MY-THREAD 的執行緒發布回覆,請設定 MY-THREAD

  2. 如果找不到指定的 threadKey,請定義執行緒行為:

    • 回覆討論串或發起新討論串。將 messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD 參數加入 Webhook 網址。傳送此網址參數可讓 Chat 使用指定的 threadKey 尋找現有執行緒。如果有找到,訊息會以回覆該討論串的形式發布。如果沒有找到,訊息就會啟動與該 threadKey 相對應的新執行緒。

    • 回覆討論串或不採取任何行動。將 messageReplyOption=REPLY_MESSAGE_OR_FAIL 參數加入 Webhook 網址。傳送此網址參數可讓 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 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);
}