描述問題/錯誤/問題:
我試圖回覆一個已關閉的主題,該主題討論完全相同的問題,但由於其已被鎖定,我創建了新主題。
我無法在 n8n Cloud 中驗證我的 Meta WhatsApp Cloud API Webhook URL。Meta 一直驗證回調 URL 失敗。
錯誤訊息是什麼(如果有的話)?
Meta 開發者控制台在點擊「驗證並儲存」時顯示一般回調驗證失敗錯誤。
請分享您的工作流程:
- Webhook 觸發器 (GET/POST)
- If 節點檢查:hub.mode == subscribe AND hub.verify_token == n8n_property_bot_verify_token
- 回覆 Webhook 節點:以純文字格式返回原始 hub.challenge(HTTP 狀態 200)。
分享最後一個節點返回的輸出:
包含 hub.challenge 值的原始文字,附帶 HTTP 200 標頭。
您的 n8n 設置的相關資訊:
- n8n 版本:最新 Cloud 版本
- 資料庫:Cloud 預設
- 執行 n8n 方式:n8n cloud (aboanada67.app.n8n.cloud)
- 作業系統:Cloud 託管
Hi @Abo_Anad_Abo_Anad 歡迎!
Meta 以 GET 方式傳送驗證,以 POST 方式傳送訊息傳遞,Webhook 節點一次只註冊一個方法,所以位於 POST 上的節點會對驗證請求返回 404,Meta 只會顯示其通用回調失敗。開啟節點「設定」並開啟「允許多個 HTTP 方法」,然後在「HTTP 方法」欄位中保留 GET 和 POST。該節點隨後會為每個方法輸出一個,因此將 GET 輸出執行到您的「如果」節點和「回應 Webhook」節點中,並使用 POST 輸出來處理訊息。
點擊「驗證」並在工作流程已發佈且生產網址貼入 Meta 的情況下儲存,測試網址僅監聽 120 秒。
Hi @Abo_Anad_Abo_Anad
失敗幾乎肯定由以下三個原因之一造成:使用了測試網址而非正式網址、表達式中的JSON 路徑不正確(查詢參數是巢狀的),或回應以 application/json 而非 text/plain 形式傳送。
當你在 Meta 開發者控制臺中點擊「驗證並儲存」時,Meta 會向你的網址傳送一個即時 GET 請求。
- 不要使用測試網址(以
/test 結尾的那個)。測試網址只在你開啟 n8n 編輯器並手動點擊「執行工作流程」時才能運作。Meta 的請求會到達一個已關閉的監聽器並失敗。
- 請使用正式網址(沒有
/test 的那個)。
- 注意:你必須儲存並啟用工作流程,正式網址才會上線。
要通過 Meta 的握手驗證,你的節點必須完全按照以下方式設定:
- HTTP 方法:
GET(注意:如要實際接收訊息,你稍後需要新增 POST,所以將此設為 GET 和 POST)。
- 路徑:(你選擇的路徑,例如
whatsapp-webhook)
- 回應:
使用 'Respond to Webhook' 節點(這是必須的)。
Meta 在查詢字串中傳送參數,而不是在本體中。你的「如果」節點必須檢查 query 物件。
- 條件 1(字串):
{{ $json.query['hub.mode'] }} 等於 subscribe
- 條件 2(字串):
{{ $json.query['hub.verify_token'] }} 等於 your_token_here
這是大多數使用者失敗的地方。Meta 期望的是原始字串,而不是 JSON 物件。
- 回應內容:
文字
- 回應本體:
{{ $json.query['hub.challenge'] }}(使用表達式)
- HTTP 狀態碼:
200
- 回應標題(選用但建議):
- 名稱:
Content-Type
- 值:
text/plain
當 Meta 向你的網址發送請求時,資料結構看起來像這樣:
{
"query": {
"hub.mode": "subscribe",
"hub.verify_token": "n8n_property_bot_verify_token",
"hub.challenge": "123456789"
}
}
你的工作流程必須提取 123456789 並將其作為純文字字串傳回,而不是 {"challenge": "123456789"}。
這有幫助嗎?
繼續討論來自 Meta Whats-app Web hook 驗證在 n8n Cloud 上失敗(GET hub.challenge 回應問題):
這幾乎總是以下兩種情況之一,兩者都容易被忽略。
首先,回應格式。Meta 的驗證呼叫是一個 GET 請求,包含
三個查詢參數:hub.mode、hub.verify_token 和 hub.challenge。
它期望 hub.challenge 以原始純文字形式返回,附帶 200 狀態碼。n8n 的
預設 web hook 回應是 JSON,所以 Meta 會收到類似
{“challenge”:“123”} 的內容,而不是單純的 123,然後拒絕它。
修復方法:
- 在 Web hook 節點上,設定「回應方式」為「使用『回應 Web hook
節點』」
- 新增一個「回應 Web hook」節點
- 設定「回應方式」= 文字
- 回應內文 = {{ $json.query[‘hub.challenge’] }}
文字,不是 JSON。這個單一設定通常就是整個問題所在。
其次,這會影響許多 Cloud 上的使用者:確保你提供給 Meta 的是
生產環境 URL,而不是測試 URL,並且工作流程確實是啟用狀態。測試 URL
只會在你點擊「監聽測試事件」後接聽一次呼叫,
之後就會停止,所以驗證會無聲地失敗,即使編輯器中的
一切看起來都沒有問題。
還有一個細節可以為你節省日後的麻煩:Meta 在同一個
URL 上使用 GET 進行驗證,使用 POST 進行實際的傳入訊息。如果你
不區分這兩者,你的訊息處理邏輯也會在驗證呼叫上執行。在 web hook
之後新增一個 Switch 或 IF,檢查 {{ $json.headers[‘x-forwarded-method’] }} 或
$json.query[‘hub.mode’] 的存在,並將這兩條路徑
分開路由。
值得驗證 hub.verify_token 是否與你在 Meta
儀表板中設定的內容相符,然後再回應,而不是無條件地
回復 challenge。