H繁中版
文件訊息平台whatsapp cloud
<!-- Source: https://hermesbible.com/docs/user-guide/messaging/whatsapp-cloud -->

章節:訊息平台 · 網址:https://hermesbible.com/docs/user-guide/messaging/whatsapp-cloud

WhatsApp Business Cloud API 設定

Hermes 可以透過 Meta 的官方 WhatsApp Business Cloud API 連線到 WhatsApp。這是生產級的路徑:不需要 Node.js bridge 子程序、不需要 QR code、沒有帳號被封的風險。

代價:

  • 你需要一個 Meta Business 帳號(不是個人 WhatsApp)。
  • 機器人使用一個專屬的商業電話號碼運作,不是你的私人號碼。
  • Hermes gateway 需要一個公開的 HTTPS URL,讓 Meta 透過 webhook 傳送訊息給你。
  • 在使用者最後一則訊息後超過 24 小時才回覆的訊息,需要使用預先核准的模板(這是 Meta 的「客服時間窗口」規則,不是 Hermes 的限制)。

如果這些限制不適合你的使用場景,Baileys bridge 整合是另一個選擇——個人帳號、不需要公開 URL,但不是官方的,且有被封的風險。

提示——我該用哪一個?

  • Cloud API(本指南)——在營運真正的商業機器人,需要穩定性,能接受 Meta 驗證 + 模板申請的流程
  • Baileys bridge——個人專案、快速展示、單一使用者設定,願意承擔機器人電話號碼帳號的風險

快速開始

hermes whatsapp-cloud

設定精靈會引導你完成每個憑證的設定,貼上時逐一驗證(抓住最常見的設定陷阱——把電話號碼貼到 Phone Number ID 欄位),並印出需要在精靈之外手動完成的後續步驟(啟動 cloudflared、設定 Meta 的 webhook 後台)。

本頁其餘內容為手動參考說明。


前置需求

  1. 一個 Meta Business 帳號。在 business.facebook.com 建立。
  2. 一個啟用 WhatsApp 的 Meta 應用程式。參見下方「建立 Meta 應用程式」。
  3. 一個將本地連接埠公開到網際網路的方式,並使用 HTTPS。建議使用 Cloudflare Tunnel (cloudflared)——免費、不需要連接埠轉發、不需要網域。ngrok、使用自己的網域搭配反向代理 + TLS、或直接綁定到公開 IP 的 VPS 也都可以運作。
  4. 選擇性但建議安裝:在 PATH 中加入 ffmpeg,這樣外送語音訊息會以原生 WhatsApp 語音備註氣泡(綠色波形)顯示,而不是 MP3 音訊附件。Hermes 在缺少 ffmpeg 時仍能正常運作。

建立 Meta 應用程式

  1. 前往 developers.facebook.com/apps建立應用程式
  2. 選擇使用案例:「透過 WhatsApp 與客戶互動」下一步
  3. 選擇或建立一個商業組合。檢視發布要求。確認 → 建立應用程式
  4. 建立完成後會到達自訂使用案例 → 在 WhatsApp 上連結 → 快速入門。點擊開始使用 API → 你現在在 API 設定頁面。
  5. 確認已連結 WhatsApp Business Account (WABA)。如果你在步驟 3 建立了新的組合,系統會自動建立一個。在 API 設定頁面中確認。

你需要從後台取得以下值——設定精靈會按此順序提示你:

後台位置欄位格式備註
Phone Number IDApp Dashboard → WhatsApp → API Setup → 「From」下拉選單下方數字,15-17 碼不是電話號碼本身。最常見的設定錯誤就是把真實電話號碼貼到這裡。
Access TokenApp Dashboard → WhatsApp → API Setup → 「Generate access token」EAA 開頭,100+ 字元暫時性 token 有效期限為 24 小時——生產環境請見下方「永久 token」。
App SecretApp Dashboard → Settings → Basic → 點擊 App secret 旁邊的「Show」32 個字元的小寫十六進位字串用於驗證 incoming webhook 簽章。沒有它,inbound 會被以 503 拒絕。
App ID(選擇性)App Dashboard → Settings → Basic數字,15-16 碼訊息功能不一定要有,但可用於分析。
WABA ID(選擇性)App Dashboard → WhatsApp → API Setup → 頂部附近數字,15+ 碼訊息功能不一定要有,但可用於分析。

永久 token(生產環境)

暫時性 access token 在 24 小時後過期,意思是今天產生的 token 明天就無法使用。生產環境部署請使用 System User 永久 token

  1. 前往 business.facebook.com/latest/settingsSystem users(左側邊欄)。
  2. 新增 → 命名(例如 hermes-bot)→ 角色:Admin
  3. 選擇新使用者 → Assign Assets
    • 選擇你的應用程式 → 在 Full control 下切換 Manage app
    • 選擇你的 WhatsApp 帳號 → 在 Full control 下切換 Manage WhatsApp Business Accounts
    • 點擊 Assign assets
  4. Generate token 並勾選以下權限:
    • business_management
    • whatsapp_business_messaging
    • whatsapp_business_management
  5. 設定 token expiration: Never
  6. 複製 token → 更新 ~/.hermes/.env 中的 WHATSAPP_CLOUD_ACCESS_TOKEN → 重新啟動 gateway。

System User token 除非你手動撤銷,否則不會過期。


將 Hermes 暴露到網際網路

Cloud API 透過 HTTPS POST 將 inbound 訊息傳送到你的 webhook URL——也就是說 Hermes gateway 必須能從 Meta 的伺服器連線到。有三種常見方式:

Cloudflare Tunnel(建議)

免費、不需要連接埠轉發、適用於 Windows / macOS / Linux。與 gateway 並行運作為獨立程序。

安裝:

# Windows
winget install Cloudflare.cloudflared

# macOS
brew install cloudflared

# Linux
# 從 https://github.com/cloudflare/cloudflared/releases 下載執行檔

執行 quick tunnel(不需要 Cloudflare 帳號——會給你一個 https://<random>.trycloudflare.com 的 URL):

cloudflared tunnel --url http://localhost:8090

記下列印出的 URL——這就是你要給 Meta 的地址。

警告——Quick tunnel 會輪換

免費 quick tunnel 的 URL 在每次重新啟動 cloudflared 時都會改變。要取得穩定的 URL,請使用 cloudflared tunnel login 登入並建立 named tunnel。免費 Cloudflare 帳號可以無限制建立 named tunnel——請參閱 Cloudflare 文件 了解 named tunnel 工作流程。

ngrok

ngrok http 8090

免費版每次重啟都會給不同的 URL。付費版提供穩定的子網域。

自己的網域 + 反向代理

如果你已有伺服器和 TLS 憑證(Caddy、nginx 等),將路由指向 localhost:8090。這是生產環境最穩定的選項,但需要已有的基礎設施。


在 Meta 端設定 webhook

你的 tunnel 運作後:

  1. 記下你的 tunnel 列印出的公開 URL——例如 https://abc123.trycloudflare.com
  2. 產生一個 Verify Token——設定精靈會用 secrets.token_urlsafe(32) 幫你產生;如果手動設定,請執行:
    python -c "import secrets; print(secrets.token_urlsafe(32))"
    
    將它儲存為 ~/.hermes/.env 中的 WHATSAPP_CLOUD_VERIFY_TOKEN
  3. 啟動 Hermes gateway:hermes gateway
  4. 在 Meta App Dashboard → WhatsApp → Configuration(或 Use cases → Customize → Configuration,依 UI 版本而異)→ 點擊 Webhook 區塊的 Edit
  5. 填入:
    • Callback URLhttps://abc123.trycloudflare.com/whatsapp/webhook
    • Verify Token:步驟 2 的字串(必須完全吻合)
  6. 點擊 Verify and save。Meta 會向你的 URL 發送 GET 請求,gateway 回傳 challenge 值,Meta 就會將 webhook 標記為已驗證。
  7. Webhook fields 下方,點擊 Manage → 訂閱 messages 欄位。這會告訴 Meta 將 inbound 訊息實際傳送到你的 webhook。

手動驗證迴圈(從第三個終端):

TUNNEL="https://abc123.trycloudflare.com"
VERIFY="<your verify token>"

# 應該列印出 HTTP 200,body 為 "hello"
curl -i "$TUNNEL/whatsapp/webhook?hub.mode=subscribe&hub.verify_token=$VERIFY&hub.challenge=hello"

# 健康檢查端點——應該顯示 verify_token_configured: true 和 app_secret_configured: true
curl "$TUNNEL/health"

收件者白名單(Meta 端)

在開發模式(應用程式尚未通過 App Review 之前),Meta 會限制你的機器人可以向哪些號碼發送訊息:

  1. App Dashboard → WhatsApp → API Setup → To 下拉選單。
  2. 點擊 Manage phone number list
  3. 加入你想要發送訊息的電話號碼(你的、你的團隊的、友善的測試者)。Meta 會透過 SMS 或 WhatsApp 發送每個號碼一個 6 碼驗證碼。

開發模式最多 5 個號碼。通過 App Review 後就能解除此限制。


允許清單(Hermes 端)

除了 Meta 的收件者白名單外,Hermes 還有自己的平台級允許清單,用來控制agent 處理哪些 inbound 訊息。在 ~/.hermes/.env 中加入:

# 逗號分隔的電話號碼,含國碼,不含 '+' / 空格 / 斷字
WHATSAPP_CLOUD_ALLOWED_USERS=15551234567,15557654321

# 或允許所有人(僅在與 Meta 收件者白名單同時使用時才安全)
# WHATSAPP_CLOUD_ALLOW_ALL_USERS=true

設定精靈會在步驟 6 中設定此值。若沒有允許清單,所有 inbound 訊息都會被拒絕——這是刻意設計的,確保即使收件者白名單被放寬,機器人也不會被隨機號碼呼叫。


美化你的機器人 WhatsApp 個人資料

WhatsApp 會在聊天頁面的標題和聯絡人清單中顯示你的機器人名稱和頭像。這些無法透過 Cloud API 設定——它們在 Meta 的 Business Manager 中管理。

機器人運作後,前往 business.facebook.com/wa/manage/phone-numbers,點擊你的電話號碼,你會看到:

項目位置備註
顯示名稱電話號碼頁面頂部更改需經過 Meta 的名稱審核流程(約 24–48 小時)。
頭像圖片電話號碼頁面頂部正方形圖片,建議 ≥640×640px。更新後立即生效。
關於 / 描述 / 網站 / 電子信箱 / 營業時間 / 分類「Edit profile」按鈕使用者點擊機器人名稱時會在資訊面板中顯示。屬於裝飾性設定。
已驗證徽章(綠色勾勾)Business Manager → Security Center → Start Verification需要 Meta 獨立的商業驗證流程。

hermes whatsapp-cloud 設定精靈會在設定結束時印出這些連結。這些都不是機器人運作所必需的——純粹是為了讓機器人對使用者呈現更好的外觀。


設定參考

所有設定都在 ~/.hermes/.env 中。必填值以粗體標示。

變數預設值說明
WHATSAPP_CLOUD_PHONE_NUMBER_IDAPI 設定中的 15-17 碼 ID。不是電話號碼。
WHATSAPP_CLOUD_ACCESS_TOKENMeta access token(以 EAA 開頭)。暫時性 24 小時或 System User 永久。
WHATSAPP_CLOUD_APP_SECRET32 碼十六進位字串,從 Settings → Basic 取得。沒有它,inbound 會被以 503 拒絕。
WHATSAPP_CLOUD_VERIFY_TOKENGET 握手用的共享密鑰。設定精靈會自動產生。
WHATSAPP_CLOUD_ALLOWED_USERS逗號分隔的 wa_id,允許這些號碼傳訊息給機器人。
WHATSAPP_CLOUD_ALLOW_ALL_USERSfalse設為 true 可繞過允許清單。
WHATSAPP_CLOUD_APP_ID選擇性,用於未來的分析整合。
WHATSAPP_CLOUD_WABA_ID選擇性,用於未來的分析整合。
WHATSAPP_CLOUD_WEBHOOK_HOST0.0.0.0webhook 伺服器綁定的網路介面。
WHATSAPP_CLOUD_WEBHOOK_PORT8090webhook 伺服器綁定的連接埠。必須與你的 tunnel 轉發的連接埠一致。
WHATSAPP_CLOUD_WEBHOOK_PATH/whatsapp/webhookMeta POST 的 URL 路徑。
WHATSAPP_CLOUD_API_VERSIONv20.0Meta Graph API 版本。僅在 Meta 文件建議使用較新版本時才覆寫。
WHATSAPP_CLOUD_HOME_CHANNEL用於作為機器人主頻道的 wa_id(用於排程任務等)。

你可以同時啟用 Baileys (whatsapp) 和 Cloud (whatsapp_cloud) 適配器,分別指向不同的電話號碼。


功能

Inbound

  • 文字訊息——直接傳遞給 agent。
  • 圖片——自動下載並附加到 agent 的輸入中。具有原生視覺能力的模型(Claude、GPT-4o、Gemini 等)直接讀取圖片;非視覺模型會收到自動產生的文字描述。
  • 語音備註——自動下載為 .ogg,透過你設定的 STT 供應商(本地 faster-whisper、OpenAI/Nous、Groq 等)轉錄,然後以文字形式交給 agent。
  • 文件——自動下載。小型可讀文字檔案(.txt.md.json.py.csv 等)在 100KB 以內會直接嵌入 agent 的輸入中,讓 agent 不需要透過工具呼叫就能讀取。較大的檔案會在本地快取,供 agent 的其他工具存取。
  • 按鈕點擊——當使用者點擊機器人先前傳送的按鈕(澄清選擇、指令核准、斜線指令確認)時,點擊會直接路由到對應的處理器。過期的點擊會降級為一般文字輸入。
  • 回覆上下文——當使用者回覆先前的機器人訊息時,agent 會看到原始訊息作為上下文。

Outbound

  • 文字——markdown 會自動轉換為 WhatsApp 的格式語法(**粗體***粗體*~~刪除線~~~刪除線~、標題 → 粗體、[連結](url)連結 (url))。長訊息會在 4096 字元處分割。
  • 圖片——支援 agent 產生的圖片和本地图像檔案,以原生相片附件形式傳送。
  • 語音訊息——文字轉語音輸出透過 ffmpeg 轉換為原生 WhatsApp 語音備註氣泡(綠色波形)。未安裝 ffmpeg 時會降級為 MP3 音訊附件。詳見下方「語音訊息」。
  • 影片 / 文件——都支援,以原生附件形式傳送。

互動式 UX

當 agent 呼叫這些流程時,Hermes 使用 WhatsApp 的原生互動式訊息——點擊回答按鈕取代「輸入數字回覆」的提示:

  • clarify 工具——多選問題會渲染為快速回覆按鈕(1–3 個選項)或可點擊展開的列表面板(4+ 個選項)。選擇「✏️ Other」可讓使用者輸入自由文字回答,agent 會收到該回答作為解答。
  • 危險指令核准——當 agent 的終端 / 程式碼執行碰到需要核准的指令時,使用者會看到 ✅ Approve / ❌ Deny 按鈕,而不需要手動輸入 /approve/deny
  • 斜線指令確認——特权指令如 /reload-mcp 會顯示 ✅ Approve Once / 🔒 Always / ❌ Cancel 按鈕。

所有互動式提示在按鈕無法渲染時(例如舊版 WhatsApp 客戶端)都會優雅降級為純文字。

已讀回條與輸入指示器

Hermes 會立即確認收到 inbound 訊息:

  • 你的訊息在 gateway 收到後會顯示藍色雙勾勾
  • 機器人在你的 WhatsApp 聊天中會顯示**「輸入中…」**,在 agent 準備回覆期間。
  • 輸入指示器會在機器人的第一則回覆訊息送出時自動消失。

這讓你清楚知道機器人已經看到你的訊息,以及它正在處理回覆的狀態。

語音訊息

WhatsApp 會區分「語音備註」(綠色波形氣泡)和一般音訊檔案附件。差異純粹在於編碼格式:語音備註必須是 audio/ogg 並使用 opus 編碼。

Hermes TTS 產生 MP3。有兩種路徑:

  • PATH 中有安裝 ffmpeg(建議)——外送 TTS 會被轉換並以正確的語音備註形式到達。安裝方式:
    • Windows:winget install Gyan.FFmpeg
    • macOS:brew install ffmpeg
    • Linux:套件管理器
  • 沒有安裝 ffmpeg——外送 TTS 會以 MP3 音訊附件形式到達。播放正常,只是看起來不像是語音備註。gateway 日誌中會發出一次性警告讓你知道。

你可以透過健康檢查端點確認 gateway 是否找到 ffmpeg:

curl http://localhost:8090/health
# 尋找 "ffmpeg_present": true

已知限制

24 小時對話窗口

Meta 僅允許在使用者最後一則 inbound 訊息後的 24 小時窗口內傳送自由格式訊息。超過此窗口後,Meta 的 API 只接受預先核准的訊息模板

實際意義:

  • 回應式聊天(使用者私訊 → 機器人在 24 小時內回覆 → 使用者回覆 → ...)可以永遠運作。這涵蓋了超過 95% 的正常機器人使用場景。
  • 在間隔超過 24 小時後透過 WhatsApp 傳送的排程任務會失敗,並帶有 Graph 錯誤碼 131047(「重新互動訊息」)。
  • 長時間運行的 delegate_task 非同步結果若超過 24 小時,會以同樣方式失敗。
  • Webhook 訂閱者若將外部事件路由到 WhatsApp,在使用者最近沒有私訊機器人的情況下會失敗。

Hermes 會在 system prompt 中提醒 agent 這個窗口的限制,讓模型在安排延遲訊息時知道要提及它。

Hermes 尚未實作訊息模板支援(這是逾時窗口外發送的替代方案)。如果你需要此功能,請提交 issue——已納入計畫但等待明確的需求訊號。

群組聊天

Cloud API 的群組支援有限(依 Meta 的功能等級限制)。Hermes 的 whatsapp_cloud 適配器在 v1 中目前僅處理直接訊息。如果你需要群組聊天功能,請使用 Baileys bridge。

外送速率限制

Meta 的預設吞吐量為每個商業電話號碼每秒 80 則訊息,可付費升級。Hermes 目前不在用戶端強制此限制——極高量的發送可能會觸及 Meta 的限制。


疑難排解

設定驗證失敗(「URL couldn't be validated」)在 Meta 後台

幾乎都是以下原因之一:

  • Tunnel URL 錯誤或過期——cloudflared quick tunnel 會輪換。取得新的 URL 並同時更新 .env 和 Meta 後台。
  • Verify token 不吻合——~/.hermes/.env 中的 WHATSAPP_CLOUD_VERIFY_TOKEN 必須與你在 Meta 後台輸入的完全一致。先用上述的 curl 探測確認 gateway 的 verify 握手在本地運作正常。
  • Gateway 未運行——確認 hermes gateway 已啟動。
  • App Secret 未設定——沒有它,Hermes 會以 503 拒絕 inbound POST。Meta 會將此解讀為「無法驗證」。

graph error 100:Object with ID '...' does not exist

你把電話號碼(10-11 碼)貼到了 WHATSAPP_CLOUD_PHONE_NUMBER_ID,而不是 Phone Number ID(Meta 的 15-17 碼內部 ID)。請重新檢查 API 設定頁面——Phone Number ID 顯示在「From」下拉選單的下方

設定精靈現在已加入驗證器來抓出此錯誤,但如果你是手動設定,了解這點仍然有幫助。

graph error 190:Authentication Error

你的 access token 無效。子代碼:

  • subcode 463——token 過期。暫時性 token 有效期 24 小時。重新產生,或改用 System User 永久 token(見上方)。
  • subcode 467——token 已失效(被撤銷或密碼已變更)。
  • 其他 190——token 在產生時缺少所需的權限。確認三個權限(business_managementwhatsapp_business_messagingwhatsapp_business_management)都已選取。

graph error 131047:Re-engagement message

24 小時對話窗口已過期(見「已知限制」)。你可以:

  • 請求使用者先私訊機器人以重新開啟窗口。
  • 等待 Hermes 實作模板支援。

Inbound 訊息:media metadata fetch failed (status=401)

與外送相同的 401 根本原因(graph error 190)——access token 無效或已過期。修正 token。

機器人回覆顯示為原始 JSON / 工具呼叫洩漏

常見原因:為 whatsapp_cloud 設定的工具集中缺少 agent 想要呼叫的工具。檢查 hermes tools list 並確認平台使用的是 hermes-whatsapp(預設的 Cloud 適配器工具集,與 Baileys 相同)。

如果模型產生工具呼叫格式的文字而非結構化呼叫,通常表示工具集實際上是空的。請參閱 hermes_cli/platforms.py 了解平台對應的預設工具集。

STT(語音備註轉錄)回傳空白 / "could not transcribe"

預設的 stt.provider: local 需要 pip install faster-whisper。如果你是 Nous 訂閱者,可以改用 Meta 的託管音訊閘道來處理 STT:

hermes config set stt.provider openai
hermes config set stt.use_gateway true
hermes gateway restart

這會使用你的 Nous Portal access token,而不需要單獨的 OpenAI 金鑰。


安全事項

  • 將 App Secret 視為密碼——任何取得它的人都能偽造 webhook 負載,而 Hermes 會將其視為真實。
  • Verify token 是共享密鑰——洩漏的風險較低(最壞情況是有人可以將 Meta 的 webhook 重新訂閱到他們自己的 URL),但仍應避免提交到版本控制。
  • Access token 是你機器人的身份——System User token 等同於長期有效的 API 金鑰。如果部署遭到入侵,請立即輪換。
  • Webhook 端點在設定 WHATSAPP_CLOUD_APP_SECRET 後僅接受已簽署的請求——即使在開發環境中也請保持設定。沒有它,gateway 會以 HTTP 503 拒絕 inbound 傳送。
  • /health 端點無需驗證——它是安全的,因為只回報設定是否存在(布林值),不回報實際值。但如果你不想暴露它,請在反向代理 / tunnel 層限制存取。

與 Baileys bridge 的比較

Baileys (hermes whatsapp)Cloud API (hermes whatsapp-cloud)
帳號類型個人商業
設定方式QR code 掃描Meta 應用程式 + WABA + token
相依性Node.js + npm純 Python(httpx + aiohttp)
程序受管理的 Node 子程序aiohttp webhook 伺服器
需要公開 URL?
帳號被封風險有(非官方 API)無(官方支援)
Inbound輪詢 Node bridgeMeta 的 Webhook POST
Outbound本地 bridge → BaileysHTTPS 連線到 graph.facebook.com
群組完整支援僅直接訊息(v1)
24 小時窗口無限制硬性限制——逾時後需要模板
語音備註(外送)原生有 ffmpeg 時原生,否則降級為 MP3
已讀回條有(藍色雙勾勾)
輸入指示器有(回覆時自動消失)
互動式按鈕僅文字降級原生(澄清、核准、斜線確認)
生產環境使用有風險(Meta 可能封號)專為此設計

大部分在個人專案中使用 Hermes 的使用者偏好 Baileys。大部分在營運面向客戶的機器人的使用者偏好 Cloud API。


另請參閱



Yuanbao