H繁中版
<!-- Source: https://hermesbible.com/docs/user-guide/messaging/google_chat -->

章節:訊息平台 · URL: https://hermesbible.com/docs/user-guide/messaging/google_chat

Google Chat 設定

將 Hermes Agent 連線至 Google Chat 作為機器人。此整合使用 Cloud Pub/Sub 拉取訂閱來處理傳入事件,並使用 Chat REST API 傳送訊息。 操作體驗等同於 Slack Socket Mode 或 Telegram 長輪詢:您的 Hermes 流程不需要公開 URL、隧道或 TLS 憑證。它連線、驗證並監聽訂閱——就像 Telegram 機器人監聽代碼一樣。

執行 hermes gateway setup 並選擇 Google Chat 以進行引導式說明。

注意 — Workspace 版本

Google Chat 是 Google Workspace 的一部分。您可以使用個人 Workspace(透過 Google 註冊的 @yourdomain.com)或您有管理員權限可發佈應用程式的工作 Workspace 來使用此整合。僅限 Gmail 的帳戶無法託管 Chat 應用程式。

概覽

元件
函式庫google-cloud-pubsubgoogle-api-python-clientgoogle-auth
傳入傳輸Cloud Pub/Sub 拉取訂閱(無公開端點)
傳出傳輸Chat REST API (chat.googleapis.com)
驗證具有訂閱上 roles/pubsub.subscriber 的 Service Account JSON
使用者識別Chat 資源名稱 (users/{id}) + 電子郵件

步驟 1:建立或選擇 GCP 專案

您需要一個 Google Cloud 專案來託管 Pub/Sub 主題。如果您還沒有,請在 console.cloud.google.com 建立——個人帳戶可獲得免費層級,輕鬆涵蓋機器人流量。

記下專案 ID(例如 my-chat-bot-123)。您將在後續每個步驟中使用它。


步驟 2:啟用兩個 API

在控制台中,前往 APIs & Services → Library 並啟用:

  • Google Chat API
  • Cloud Pub/Sub API

這兩者對於個人機器人產生的流量都是免費的。


步驟 3:建立 Service Account

IAM & Admin → Service Accounts → Create Service Account.

  • 名稱:hermes-chat-bot
  • 跳過「授予此 Service Account 存取專案」步驟。您只需要在特定訂閱上的 IAM——請不要授予專案層級的 Pub/Sub 角色。

建立後,開啟 SA,前往 Keys → Add Key → Create new key → JSON 並下載檔案。將其儲存在只有 Hermes 可讀取的位置(例如 ~/.hermes/google-chat-sa.jsonchmod 600)。

注意 — 沒有「Chat Bot Caller」角色

常見的錯誤是搜尋 Chat 專用的 IAM 角色並在專案層級授予它。該角色並不存在。Chat 機器人的權限來自於安裝在空間中,而非 IAM。您的 SA 只需要在下一步建立的訂閱上的 Pub/Sub 訂閱者權限。


步驟 4:建立 Pub/Sub 主題和訂閱

Pub/Sub → Topics → Create topic.

  • 主題 ID:hermes-chat-events
  • 其他所有選項保留預設值。

建立後,主題的詳細頁面有 Subscriptions 標籤。建立一個:

  • 訂閱 ID:hermes-chat-events-sub
  • 傳遞類型:Pull
  • 訊息保留:7 天(這樣在 Hermes 重啟時仍可保留積壓訊息)
  • 其他保留預設值。

步驟 5:主題上的 IAM 綁定(關鍵)

主題(不是訂閱)上,新增一個 IAM 主體:

  • 主體:chat-api-push@system.gserviceaccount.com
  • 角色:Pub/Sub Publisher

沒有這個,Google Chat 無法將事件發佈到您的主題,您的機器人將永遠不會收到任何內容。


步驟 6:訂閱上的 IAM 綁定

訂閱上,將您自己的 Service Account 新增為主體:

  • 主體:hermes-chat-bot@<your-project>.iam.gserviceaccount.com
  • 角色:Pub/Sub Subscriber

同時在同一訂閱上授予 Pub/Sub Viewer——Hermes 在啟動時會呼叫 subscription.get() 作為可達性檢查。


步驟 7:設定 Chat 應用程式

前往 APIs & Services → Google Chat API → Configuration

  • App name:您希望使用者看到的名稱(「Hermes」是合理的選擇)。
  • Avatar URL:任何公開的 PNG 圖片(Google 有一些預設選項)。
  • Description:應用程式目錄中顯示的簡短描述。
  • Functionality:啟用 Receive 1:1 messagesJoin spaces and group conversations
  • Connection settings:選擇 Cloud Pub/Sub,輸入主題名稱 projects/<your-project>/topics/hermes-chat-events
  • Visibility:限制為您的工作區(或特定使用者)——測試時請勿發佈給所有人。

儲存。


步驟 8:在測試空間中安裝機器人

在瀏覽器中開啟 Google Chat。透過在 + New Chat 選單中搜尋其名稱來與您的應用程式開始 DM。當您第一次傳送訊息時,Google 會傳送 ADDED_TO_SPACE 事件,Hermes 用它來快取機器人自己的 users/{id} 以進行自我訊息過濾。


步驟 9:設定 Hermes

~/.hermes/.env 中新增 Google Chat 部分:

# 必要
GOOGLE_CHAT_PROJECT_ID=my-chat-bot-123
GOOGLE_CHAT_SUBSCRIPTION_NAME=projects/my-chat-bot-123/subscriptions/hermes-chat-events-sub
GOOGLE_CHAT_SERVICE_ACCOUNT_JSON=/home/you/.hermes/google-chat-sa.json

# 授權 — 貼上允許與機器人交談的人員的電子郵件
GOOGLE_CHAT_ALLOWED_USERS=you@yourdomain.com,coworker@yourdomain.com

# 選擇性
GOOGLE_CHAT_HOME_CHANNEL=spaces/AAAA...         # 排程作業的預設傳遞目的地
GOOGLE_CHAT_MAX_MESSAGES=1                      # Pub/Sub FlowControl;1 會序列化每個會話的命令
GOOGLE_CHAT_MAX_BYTES=16777216                  # 16 MiB — 訊息位元組上限

專案 ID 也可以回退至 GOOGLE_CLOUD_PROJECT,SA 路徑可以回退至 GOOGLE_APPLICATION_CREDENTIALS——使用您偏好的慣例。

安裝 Google Chat 適配器所需的依賴項(目前未發佈 Hermes 附加元件——直接安裝):

pip install google-cloud-pubsub google-api-python-client google-auth google-auth-oauthlib

啟動閘道器:

hermes gateway

您應該會看到類似以下的日誌行:

[GoogleChat] Connected; project=my-chat-bot-123, subscription=<redacted>,
             bot_user_id=users/XXXX, flow_control(msgs=1, bytes=16777216)

在測試 DM 中傳送「hola」。機器人會發佈「Hermes is thinking…」標記,然後就地編輯同一則訊息以顯示真實回應——沒有「訊息已刪除」墓碑。


格式與功能

Google Chat 渲染有限的 markdown 子集:

支援不支援
*粗體*_斜體_~刪除線~`程式碼`標題、清單
透過 URL 的內嵌圖片互動式 Card v2 按鈕(此閘道器的 v1 版本)
原生檔案附件(在 /setup-files 後——見步驟 10)原生語音註解 / 圓形視訊註解

代理人的系統提示包含 Google Chat 專用提示,因此它知道這些限制並避免使用不會渲染的格式。

訊息大小限制:每則訊息 4000 字元。較長的代理人回應會自動分割成多則訊息。

執行緒支援:當使用者在執行緒內回覆時,Hermes 會偵測 thread.name 並在同一個執行緒中發佈其回覆,因此每個執行緒都有單獨的 Hermes 會話。


步驟 10:原生附件傳遞(選擇性)

預設情況下,機器人可以發佈文字、透過 URL 的內嵌圖片,以及下載音訊/視訊/文件的卡片。要傳遞原生 Chat 附件——當人類拖放檔案時得到的相同檔案小工具——每個使用者透過每使用者 OAuth 流程授權一次機器人。

為什麼需要單獨的流程

Google Chat 的 media.upload 端點硬性拒絕 Service Account 驗證:

此方法不支援使用 Service Account 進行應用程式驗證。 請使用使用者帳戶進行驗證。

沒有任何 IAM 角色或範圍可以修正這一點。該端點僅接受使用者憑證。因此,當機器人上傳檔案時,必須以使用者身份執行——特別是要求檔案的使用者。

一次性設定(每個設定檔)

  1. 在相同的 GCP 專案中,前往 APIs & Services → Credentials
  2. Create credentials → OAuth client ID → Desktop app
  3. 下載 JSON。將其移至執行 Hermes 的主機上。
  4. 使用 Hermes 註冊用戶端(在您要限定範圍的設定檔下執行):
# 預設設定檔:
python -m plugins.platforms.google_chat.oauth \
    --client-secret /path/to/client_secret.json

# 命名設定檔有自己的獨立註冊:
hermes -p <profile> python -m plugins.platforms.google_chat.oauth \
    --client-secret /path/to/client_secret.json

這會將用戶端密鑰寫入作用中設定檔的 Hermes 主目錄(例如預設設定檔的 ~/.hermes/google_chat_user_client_secret.json)。用戶端密鑰是設定檔限定範圍的,不會跨設定檔共享——每個設定檔都會註冊自己的密鑰。這是故意的:設定檔是隔離的驗證邊界,因此兩個設定檔可以指向不同的 Google OAuth 應用程式/帳戶。對於需要 Google Chat 附件傳遞的每個設定檔,註冊一次。

每使用者授權(在聊天中)

每個使用者在其與機器人的 DM 中執行一次流程:

  1. 他們傳送 /setup-files 給機器人。它回覆狀態和下一步。
  2. 他們傳送 /setup-files start。機器人回覆一個 OAuth URL。
  3. 他們開啟 URL,按一下 Allow,並看著瀏覽器無法載入 http://localhost:1/?...&code=...。該失敗是預期的——驗證碼在 URL 列中。
  4. 他們複製失敗的 URL(或僅 code=... 值)並將其貼回聊天中作為 /setup-files <PASTED_URL>。機器人將其交換為重新整理權杖。

權杖儲存在 ~/.hermes/google_chat_user_tokens/<sanitized_email>.json。該使用者 DM 中的後續檔案請求使用他們的權杖,因此機器人以他們的身份上傳,訊息會出現在他們的空間中。

要稍後撤銷:/setup-files revoke 僅刪除該使用者的權杖。其他使用者的權杖不受影響。

範圍

此流程僅請求一個範圍:chat.messages.create。這涵蓋了 media.upload 和引用上傳的 attachmentDataRefmessages.create。沒有 Drive,沒有更廣泛的 Chat 範圍——這是故意的最小權限。

多使用者行為

當要求者尚未擁有每使用者權杖時,機器人會回退到 ~/.hermes/google_chat_user_token.json 中的傳統單使用者權杖(如果來自多使用者安裝前)。當兩者都不可用時,機器人會發佈清晰的文字通知,要求要求者執行 /setup-files

使用者撤銷僅清除自己的插槽。一個使用者的權杖出現 401/403 錯誤僅會驅逐該使用者的快取。使用者之間不會互相干擾。


疑難排解

機器人傳送「hola」後保持沉默。

  1. 檢查 Pub/Sub 訂閱在控制台中是否有未傳遞的訊息。如果有,Hermes 未驗證——請驗證 GOOGLE_CHAT_SERVICE_ACCOUNT_JSON 且 SA 已列為訂閱上的 Pub/Sub Subscriber
  2. 如果訂閱沒有任何訊息,Google Chat 未發佈。請仔細檢查主題上的 IAM 綁定:chat-api-push@system.gserviceaccount.com 必須具有 Pub/Sub Publisher
  3. 檢查 hermes gateway 日誌中的 [GoogleChat] Connected。如果您看到 [GoogleChat] Config validation failed,錯誤訊息會告訴您要修正哪個環境變數。

機器人回覆但出現錯誤訊息而非代理人的答案。

檢查日誌中是否有 [GoogleChat] Pub/Sub stream died——如果這些錯誤重複出現,您的 SA 憑證可能已被輪換或訂閱已被刪除。嘗試 10 次後,適配器會標記自身為致命錯誤。

所有傳出訊息都出現「403 Forbidden」。

機器人已從空間中移除,或您在 Chat API 控制台中撤銷了它。請在空間中重新安裝它(下一個 ADDED_TO_SPACE 事件會自動重新啟用訊息傳遞)。

太多「Rate limit hit」警告。

Chat API 的預設配額允許每個空間每分鐘 60 則訊息。如果您的代理程式產生超過該限制的長串流回應,適配器會使用指數退避重試——但您仍會看到使用者可見的延遲。請考慮簡潔回應或在 GCP 控制台中提高配額。

機器人持續發佈「/setup-files」通知而非檔案。

要求者沒有每使用者 OAuth 權杖,且沒有傳統回退。請在其 DM 中執行 /setup-files 並按照步驟 10 操作。交換完成後,下一個檔案請求會原生上傳,無需重新啟動閘道器。

/setup-files start 說「No client credentials stored.」

此設定檔尚未完成一次性設定(用戶端密鑰是設定檔限定範圍的,因此一個設定檔下的註冊不會被另一個設定檔看到)。從終端機,在閘道器使用的設定檔下執行:

# 預設設定檔:
python -m plugins.platforms.google_chat.oauth \
    --client-secret /path/to/client_secret.json

# 命名設定檔:
hermes -p <profile> python -m plugins.platforms.google_chat.oauth \
    --client-secret /path/to/client_secret.json

然後再次傳送 /setup-files start

/setup-files <PASTED_URL> 說「Token exchange failed.」

驗證碼是一次性且短期有效的(通常幾分鐘)。傳送 /setup-files start 以取得新的 URL 並重試。


安全性說明

  • Service Account 範圍:適配器請求 chat.botpubsub 範圍。IAM 應為實際執行機制——授予您的 SA 最小權限(訂閱上的 roles/pubsub.subscriber + roles/pubsub.viewer),而非專案層級或組織層級的 Pub/Sub 角色。
  • 附件下載保護:Hermes 僅會將 SA 持有者權杖附加到主機與 Google 擁有的網域名稱短允許清單(googleapis.comdrive.google.comlh[3-6].googleusercontent.com 等)匹配的 URL。在發出 HTTP 請求前,任何其他主機都會被拒絕,以防止 SSRF 場景中精心設計的事件可能將持有者權杖重定向至 GCE 中繼資料服務。
  • 遮蔽:Service Account 電子郵件、訂閱路徑和主題路徑會被 agent/redact.py 從日誌輸出中移除。除錯信封傾印(GOOGLE_CHAT_DEBUG_RAW=1)會經過相同的遮蔽過濾器並以 DEBUG 級別記錄。
  • 合規性:如果您計畫將此機器人連線至受監管的工作區(任何具有資料駐留或 AI 治理政策的工作區),請在首次安裝前取得批准。
  • 使用者 OAuth 範圍:每使用者附件流程僅請求 chat.messages.create——涵蓋 media.upload 加上後續 messages.create 的最小範圍。權杖以純 JSON 格式持久化於 ~/.hermes/google_chat_user_tokens/<sanitized_email>.json(檔案系統權限是保護機制——與 SA 金鑰檔相同模型)。每個權杖恰好由一個使用者擁有;撤銷限定於該使用者。


LINE