章節:訊息平台 · 網址:https://hermesbible.com/docs/user-guide/messaging/wecom
將 Hermes 連接到 WeCom(企業微信),這是騰訊的企業訊息平台。此適配器使用 WeCom 的 AI Bot WebSocket 閘道進行即時雙向通訊——無需公開端點或 webhook。
另請參閱:WeCom Callback 了解入站 webhook 設定。
前置需求
- 一個企業微信組織帳號
- 在企業微信管理後台建立的 AI Bot(AI 機器人)
- 從機器人憑證頁面取得的 Bot ID 和 Secret
- Python 套件:
aiohttp和httpx
設定
步驟 1:建立 AI Bot
推薦方式:掃描建立(一條指令)
hermes gateway setup
選擇 WeCom,然後用企業微信手機版掃描 QR code。Hermes 會自動建立具有正確權限的機器人應用程式,並儲存憑證。
設定精靈將會:
- 在終端機顯示 QR code
- 等待你用企業微信手機版掃描
- 自動取得 Bot ID 和 Secret
- 引導你完成存取控制設定
替代方式:手動設定
如果掃描建立不可用,精靈會退回到手動輸入:
- 登入 企業微信管理後台
- 前往 應用程式 → 建立應用程式 → AI Bot
- 設定機器人名稱和描述
- 從憑證頁面複製 Bot ID 和 Secret
- 執行
hermes gateway setup,選擇 WeCom,並在提示時輸入憑證
警告
請妥善保管 Bot Secret。任何取得它的人都可以冒充你的機器人。
步驟 2:設定 Hermes
選項 A:互動式設定(推薦)
hermes gateway setup
選擇 WeCom 並按照提示操作。精靈將引導你完成:
- 機器人憑證(透過掃描或手動輸入)
- 存取控制設定(允許清單、配對模式或開放存取)
- 用於通知的主頻道
選項 B:手動設定
在 ~/.hermes/.env 中加入以下內容:
WECOM_BOT_ID=your-bot-id
WECOM_SECRET=your-secret
# 選用:限制存取權限
WECOM_ALLOWED_USERS=user_id_1,user_id_2
# 選用:用於排程/通知的主頻道
WECOM_HOME_CHANNEL=chat_id
步驟 3:啟動閘道
hermes gateway
功能
- WebSocket 傳輸 — 持久連線,無需公開端點
- 私人訊息和群組訊息 — 可設定的存取策略
- 每個群組的傳送者允許清單 — 細粒度控制每個群組中誰可以互動
- 媒體支援 — 圖片、檔案、語音、影片的上傳和下載
- AES 加密媒體 — 入站附件自動解密
- 引用訊息上下文 — 保留回覆串接
- Markdown 渲染 — 富文字回應
- 回應關聯 — 回應與入站訊息上下文關聯
- 自動重連 — 連線中斷時使用指數退避重試
備註 — 串流與輸入指示器
WeCom 適配器將每個回應作為單一完整訊息傳送——它不會逐 token 串流回應,也不會顯示輸入指示器。下方的「回應關聯」僅將回應串接到對應的入站請求;它不是即時串流。
設定選項
在 config.yaml 的 platforms.wecom.extra 下設定:
| 鍵值 | 預設值 | 說明 |
|---|---|---|
bot_id | — | WeCom AI Bot ID(必填) |
secret | — | WeCom AI Bot Secret(必填) |
websocket_url | wss://openws.work.weixin.qq.com | WebSocket 閘道 URL |
dm_policy | open | 私訊存取:open、allowlist、disabled、pairing |
group_policy | open | 群組存取:open、allowlist、disabled |
allow_from | [] | 允許發送私訊的使用者 ID(當 dm_policy=allowlist 時) |
group_allow_from | [] | 允許的群組 ID(當 group_policy=allowlist 時) |
groups | {} | 每個群組的個別設定(見下方) |
存取策略
私訊策略
控制誰可以向機器人發送私人訊息:
| 值 | 行為 |
|---|---|
open | 任何人都可以私訊機器人(預設) |
allowlist | 只有 allow_from 中的使用者 ID 可以私訊 |
disabled | 所有私訊都會被忽略 |
pairing | 配對模式(用於初始設定) |
WECOM_DM_POLICY=allowlist
群組策略
控制機器人在哪些群組中回應:
| 值 | 行為 |
|---|---|
open | 機器人在所有群組中回應(預設) |
allowlist | 機器人只在 group_allow_from 列出的群組 ID 中回應 |
disabled | 所有群組訊息都會被忽略 |
WECOM_GROUP_POLICY=allowlist
每個群組的傳送者允許清單
為了進行更細粒度的控制,你可以限制特定群組中哪些使用者可以與機器人互動。這在 config.yaml 中設定:
platforms:
wecom:
enabled: true
extra:
bot_id: "your-bot-id"
secret: "your-secret"
group_policy: "allowlist"
group_allow_from:
- "group_id_1"
- "group_id_2"
groups:
group_id_1:
allow_from:
- "user_alice"
- "user_bob"
group_id_2:
allow_from:
- "user_charlie"
"*":
allow_from:
- "user_admin"
運作方式:
group_policy和group_allow_from控制決定某個群組是否被允許。- 如果群組通過了頂層檢查,
groups.<group_id>.allow_from列表(如果存在)會進一步限制該群組中哪些傳送者可以與機器人互動。 - 萬用字元
"*"群組條目作為未明確列出的群組的預設值。 - 允許清單條目支援
*萬用字元以允許所有使用者,且條目不區分大小寫。 - 條目可以選擇性地使用
wecom:user:或wecom:group:前綴格式——前綴會被自動去除。
如果某個群組沒有設定 allow_from,則該群組中的所有使用者都被允許(假設該群組本身通過了頂層策略檢查)。
媒體支援
入站(接收)
適配器從使用者接收媒體附件,並在本地快取以供代理程式處理:
| 類型 | 處理方式 |
|---|---|
| 圖片 | 下載並在本地快取。支援基於 URL 和 base64 編碼的圖片。 |
| 檔案 | 下載並快取。原始訊息中的檔名會被保留。 |
| 語音 | 如果可用,會提取語音訊息的文字逐字稿。 |
| 混合訊息 | WeCom 的混合類型訊息(文字 + 圖片)會被解析,所有元件都會被提取。 |
引用訊息: 引用(回覆)訊息中的媒體也會被提取,讓代理程式了解使用者正在回覆什麼內容。
AES 加密媒體解密
WeCom 使用 AES-256-CBC 加密部分入站媒體附件。適配器會自動處理:
- 當入站媒體項目包含
aeskey欄位時,適配器會下載加密的位元組並使用 AES-256-CBC 與 PKCS#7 填充進行解密。 - AES 金鑰是
aeskey欄位的 base64 解碼值(必須正好是 32 位元組)。 - IV 從金鑰的前 16 位元組衍生。
- 這需要
cryptographyPython 套件(pip install cryptography)。
無需額外設定——收到加密媒體時解密會透明地發生。
出站(傳送)
| 方法 | 傳送內容 | 大小限制 |
|---|---|---|
send | Markdown 文字訊息 | 4000 字元 |
send_image / send_image_file | 原生圖片訊息 | 10 MB |
send_document | 檔案附件 | 20 MB |
send_voice | 語音訊息(原生語音僅支援 AMR 格式) | 2 MB |
send_video | 影片訊息 | 10 MB |
分塊上傳: 檔案透過三步驟協定以 512 KB 為單位分塊上傳(init → chunks → finish)。適配器會自動處理。
自動降級: 當媒體超過原生類型的大小限制但在絕對的 20 MB 檔案限制內時,會自動降級為通用檔案附件傳送:
- 圖片 > 10 MB → 以檔案方式傳送
- 影片 > 10 MB → 以檔案方式傳送
- 語音 > 2 MB → 以檔案方式傳送
- 非 AMR 音訊 → 以檔案方式傳送(WeCom 原生語音僅支援 AMR)
超過絕對 20 MB 限制的檔案會被拒絕,並向聊天室傳送提示訊息。
回覆模式回應
當機器人透過 WeCom callback 收到訊息時,適配器會記住入站請求 ID。如果在請求上下文仍然有效時傳送回應,適配器會使用 WeCom 的回覆模式(aibot_respond_msg)將回應直接關聯到入站訊息。這在 WeCom 用戶端中提供了更自然的對話體驗。
完整的回應會作為單一訊息傳送——適配器不會逐步串流 token。如果入站請求上下文已過期或不可用,適配器會退回到透過 aibot_send_msg 主動傳送訊息。
回覆模式也適用於媒體:上傳的媒體可以作為原始訊息的回覆傳送。
連線與重連
適配器維持與 WeCom 閘道在 wss://openws.work.weixin.qq.com 的持久 WebSocket 連線。
連線生命週期
- 連線: 開啟 WebSocket 連線,並發送包含 bot_id 和 secret 的
aibot_subscribe認證框架。 - 心跳: 每 30 秒發送應用層級的 ping 框架以保持連線。
- 監聽: 持續讀取入站框架並派發訊息回調。
重連行為
連線中斷時,適配器使用指數退避進行重連:
| 嘗試 | 延遲 |
|---|---|
| 第 1 次重試 | 2 秒 |
| 第 2 次重試 | 5 秒 |
| 第 3 次重試 | 10 秒 |
| 第 4 次重試 | 30 秒 |
| 第 5 次以上重試 | 60 秒 |
每次成功重連後,退避計數器會重設為零。所有待處理的請求 future 都會在斷線時失敗,以免呼叫端無限等待。
去重
入站訊息使用訊息 ID 進行去重,時間窗口為 5 分鐘,最大快取為 1000 筆。這可以防止在重連或網路波動期間重複處理訊息。
所有環境變數
| 變數 | 必填 | 預設值 | 說明 |
|---|---|---|---|
WECOM_BOT_ID | ✅ | — | WeCom AI Bot ID |
WECOM_SECRET | ✅ | — | WeCom AI Bot Secret |
WECOM_ALLOWED_USERS | — | (空) | 以逗號分隔的使用者 ID,用於閘道層級的允許清單 |
WECOM_HOME_CHANNEL | — | — | 用於排程/通知輸出的聊天 ID |
WECOM_WEBSOCKET_URL | — | wss://openws.work.weixin.qq.com | WebSocket 閘道 URL |
WECOM_DM_POLICY | — | open | 私訊存取策略 |
WECOM_GROUP_POLICY | — | open | 群組存取策略 |
疑難排解
| 問題 | 解決方案 |
|---|---|
WECOM_BOT_ID and WECOM_SECRET are required | 設定兩個環境變數,或在設定精靈中設定 |
WeCom startup failed: aiohttp not installed | 安裝 aiohttp:pip install aiohttp |
WeCom startup failed: httpx not installed | 安裝 httpx:pip install httpx |
invalid secret (errcode=40013) | 確認 secret 與你的機器人憑證相符 |
Timed out waiting for subscribe acknowledgement | 檢查到 openws.work.weixin.qq.com 的網路連線 |
| 機器人在群組中沒有回應 | 檢查 group_policy 設定,並確保群組 ID 在 group_allow_from 中 |
| 機器人忽略群組中的特定使用者 | 檢查 groups 設定區段中的每個群組 allow_from 列表 |
| 媒體解密失敗 | 安裝 cryptography:pip install cryptography |
cryptography is required for WeCom media decryption | 入站媒體使用 AES 加密。安裝:pip install cryptography |
| 語音訊息以檔案方式傳送 | WeCom 原生語音僅支援 AMR 格式。其他格式會自動降級為檔案。 |
File too large 錯誤 | WeCom 對所有檔案上傳有 20 MB 的絕對限制。請壓縮或分割檔案。 |
| 圖片以檔案方式傳送 | 圖片 > 10 MB 超過原生圖片限制,會自動降級為檔案附件。 |
Timeout sending message to WeCom | WebSocket 可能已斷線。請檢查日誌中的重連訊息。 |
WeCom websocket closed during authentication | 網路問題或憑證不正確。請驗證 bot_id 和 secret。 |