訊息 Webhook
對話平台每收到一則客戶訊息、或每送出一則回覆,MaiAgent 都可以把該則訊息推送到你指定的網址。本篇說明 Incoming/Outgoing 的差別、後台與 API 設定方式、推送內容、來源驗證,以及失敗時不重試的行為
在對話平台(Inbox)設定訊息 Webhook 後,每一則訊息都會由 MaiAgent 主動推送到你的系統,不需要輪詢。常見用途:在自己的系統顯示「有新訊息」、把客戶留言同步到 CRM、把 AI 回覆記錄到資料倉儲。
一個對話平台可以設定多組訊息 Webhook,每組各自選擇類型、網址與格式,彼此獨立推送。
類型:Incoming 與 Outgoing
類型
何時推送
payload 的 type
Incoming
對話平台每收到一則客戶(聯絡人)訊息
incoming
Outgoing
每送出一則回覆到客戶所在的對話平台,包括 AI 自動回覆與真人客服的回覆
outgoing
後台
Incoming選項的說明文字是「接收外部請求」,但實際行為是把每則客戶訊息推送到你設定的網址。同一個選單中的
Receive用途相反:由外部平台把訊息送進 MaiAgent,不屬於本篇的推送範圍。經由Receive送進來的訊息不會觸發同一對話平台的Incoming/Outgoing推送,避免訊息在兩個系統之間來回循環。需要同時知道客戶訊息與回覆時,請各設一組
Incoming與Outgoing,可以指向同一個網址,再以 payload 的type區分。
設定方式
在後台設定
後台 → 客服對話 → 對話平台 → 選擇對話平台 → Webhook 設定 → 新增 Webhook
填寫 名稱,類型選 Incoming 或 Outgoing,填入 Webhook URL,選擇 HTTP Method(預設
POST)。(建議)在 Headers 新增一組驗證用的標頭,例如
Authorization: Bearer <你產生的隨機字串>,接收端據此確認請求來自 MaiAgent(見驗證推送來源)。Payload 格式選 MaiAgent Standard(見推送內容);需要自訂欄位時選 自訂範本。
確認 啟用狀態 已開啟後儲存。關閉啟用狀態即暫停推送,設定會保留。
WhatsApp 對話平台的設定頁目前沒有 Webhook 設定 分頁,請改用下方的 API 設定。
以 API 設定
訊息 Webhook 掛在對話平台(Inbox)之下:
列出
GET /api/v1/inboxes/{inbox_id}/webhooks/
新增
POST /api/v1/inboxes/{inbox_id}/webhooks/
查詢單筆
GET /api/v1/inboxes/{inbox_id}/webhooks/{id}/
修改
PATCH /api/v1/inboxes/{inbox_id}/webhooks/{id}/(只送要改的欄位)
刪除
DELETE /api/v1/inboxes/{inbox_id}/webhooks/{id}/
API 金鑰擁有者需能管理該對話平台,詳見 API 認證 → API 金鑰的權限範圍。
name
是
名稱,方便辨識
direction
是
incoming 或 outgoing
url
是
接收推送的網址,必須可從網際網路連線(建議 https://);指向內部網段或本機位址的網址會被拒送
method
否
POST(預設)、PUT 或 PATCH
headers
否
每次推送都會帶上的自訂標頭,JSON 物件,例如 {"Authorization": "Bearer ..."}
templatePreset
否
maiagent_standard(預設)、custom,或串接 Genesys Cloud 用的 genesys_cloud
customTemplate
custom 時必填
Jinja2 範本,渲染結果必須是 JSON;儲存時會先試算一次,格式錯誤會回 400
secretToken
否
推送時放在 X-Webhook-Secret 標頭的驗證字串;只能寫入,查詢時不會回傳
isEnabled
否
是否啟用,預設 true
成功回 201 與該筆設定(不含 secretToken)。要再收回覆,以 "direction": "outgoing" 再新增一筆。
推送內容
每則訊息以一個 HTTP 請求推送:
標頭:
Content-Type: application/json、你設定的自訂標頭,以及有設定secretToken時的X-Webhook-Secret。內容:依 Payload 格式 產生的 JSON。
MaiAgent Standard 格式
欄位一律為 snake_case(與 API 回應的 camelCase 不同)。以下是一則 Outgoing(AI 回覆)的推送內容:
id
訊息 id,可用來去重,也可用於訊息 API 查詢
type
incoming(客戶訊息)或 outgoing(回覆);判斷方向請用這個欄位
content
訊息文字
created_at
訊息建立時間(ISO 8601,UTC)
conversation
所屬對話。progress_status 為 human_serving 表示目前由真人客服處理;assignee 是被指派的客服 { "id", "name" },未指派時為 null
inbox
對話平台 { "id", "name", "channel_type" },channel_type 例如 web、line、messenger
contact
客戶(聯絡人);email、phone_number 沒有資料時為 null
sender
發話者,type 為 contact(客戶)、chatbot(Agent)或 user(組織成員,例如真人客服;以 API 金鑰代客戶送出的訊息也會是 user)
attachments
附件陣列,每筆含 id、type(image/video/audio/sticker/other)、filename、source_url
metadata
訊息的附加資訊,內容依對話平台而異
自訂範本
自訂範本(API 為 templatePreset: "custom")以 Jinja2 語法組出你要的 JSON。可用變數:message(id、type、content、created_at、metadata)、conversation、inbox、contact、sender、sender_type(contact/chatbot/user)、attachments、now。字串請用 tojson 過濾器輸出,避免引號或換行破壞 JSON:
推送當下範本渲染失敗時,該則訊息不會送出。
驗證推送來源
訊息 Webhook 沒有 HMAC 簽章(這點與轉真人 Webhook 不同),請用下列任一種方式確認請求來自 MaiAgent,並在比對時使用固定時間比較(例如 Python 的 hmac.compare_digest):
自訂標頭
後台 Headers,或 API 的 headers
你設定的標頭與值,例如 Authorization: Bearer <隨機字串>
secretToken
僅限 API(後台的 Secret Token 欄位只出現在 Receive 類型)
X-Webhook-Secret 標頭等於你設定的字串
headers的值在查詢 Webhook 設定時會原樣回傳,能查看該對話平台設定的組織成員都看得到;secretToken只能寫入、不會回傳。驗證字串請用夠長的隨機值,並透過 HTTPS 接收,避免在傳輸中被看到。
回應與重試
訊息寫入後才在背景推送,通常數秒內送達;不同訊息各自送出,不保證到達順序,請以
created_at排序、以id去重。接收端請在 30 秒內回應 2xx。逾時、連線失敗或非 2xx 都視為失敗。
失敗不會重試:該則訊息對這組 Webhook 只推送一次,失敗即不再補送。接收端建議先回 2xx、再把耗時處理放到背景。
訊息 Webhook 不保證送達。偵測新訊息的輪詢做法可以低頻補查客戶訊息(Incoming);AI 或客服的回覆(Outgoing)常在客戶訊息之後才產生,輪詢範例不一定會再讀到,不能靠它補回推送失敗的回覆。要找出推送失敗的訊息,請查下方的傳送紀錄:
statusCode不是 2xx 或為空(逾時、連線失敗)的就是失敗的推送,requestBody是當時推送的內容(MaiAgent Standard 格式內有訊息id與conversation.id),再讀該對話訊息列表的第一頁補上。每次推送的網址、內容、回應狀態碼會留下傳送紀錄,可用
GET /api/v1/chatbots/{chatbot_id}/webhook-records/查詢(需具備該 Agent 的編輯權限;chatbot_id為對話平台綁定的 Agent)。注意此 API 的回應同樣轉為 camelCase,實際推送的內容是 snake_case。推送失敗不影響訊息本身的收發與 AI 回覆。
接收端最小範例
以下是一支可直接啟動的 Python(Flask)接收端:驗證 X-Webhook-Secret、以訊息 id 去重、依 type 分流,先回 2xx 再處理。把 MESSAGE_WEBHOOK_SECRET 換成你設定的 secretToken;若改用自訂標頭驗證,改讀對應的標頭即可。
本機測試可用下列指令模擬一筆推送:
最後更新於
這有幫助嗎?