Meta WhatsApp Webhook 驗證在 n8n Cloud 上失敗(GET hub.challenge 回應問題)

描述問題/錯誤/問題:
我試圖回覆一個已關閉的主題,該主題討論完全相同的問題,但由於其已被鎖定,我創建了新主題。
我無法在 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,所以將此設為 GETPOST)。
  • 路徑:(你選擇的路徑,例如 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,然後拒絕它。

修復方法:

  1. 在 Web hook 節點上,設定「回應方式」為「使用『回應 Web hook
    節點』」
  2. 新增一個「回應 Web hook」節點
  3. 設定「回應方式」= 文字
  4. 回應內文 = {{ $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。