Discord 如何傳遞 Webhook

Interaction 要求在 3 秒內送出初始回應,簽章用 Ed25519 而不是 HMAC。附經驗證的格式與 Web Crypto 驗證程式。

傳遞行為

取自服務商自己的文件,最後檢查於 2026-08-06。服務商沒寫數字的地方,這張表也不填。

回應時限3 秒

Interaction 端點必須在 3 秒內送出初始回應

檢查你的處理程式能否及時回應

重試服務商未公開
放棄服務商未公開
出處https://docs.discord.com/developers/interactions/receiving-and-responding

簽章

用一個經測試套件證明可運作的驗證程式核對過,不是照文件抄來的。最後驗證於 2026-08-20。

演算法Ed25519
簽章內容{timestamp}{body}
編碼hex
標頭x-signature-ed25519 + x-signature-timestamp
容許時間差不強制

驗證簽章

要用原始請求主體(raw body),逐位元組原封不動,並在任何 JSON 解析之前取得。框架只要重新序列化 payload,這頁上的每一種機制就會立刻失效。

// Ed25519, not HMAC: verify with the application's public key (hex).
const hex = (s) => Uint8Array.from(s.match(/../g), (b) => parseInt(b, 16));

const key = await crypto.subtle.importKey(
  "raw",
  hex(publicKey), // Developer Portal → Application → Public Key
  { name: "Ed25519" },
  false,
  ["verify"],
);
const valid = await crypto.subtle.verify(
  "Ed25519",
  key,
  hex(req.headers["x-signature-ed25519"]),
  new TextEncoder().encode(req.headers["x-signature-timestamp"] + rawBody),
);

Discord 會主動用無效的簽章探測端點,只要能通過就拒絕這個網址,所以只做樣子的驗證程式連上線設定都過不了,不只是資安審查的問題。

容易踩的坑

3 秒的時限適用於初始的 interaction 回應。解法是 type 5(deferred):在時限內先確認收到,等真正的工作完成再送後續訊息。

延伸閱讀

AnyHook 架在接收 Discord Webhook 的端點前面:大約 1 秒就回應,伺服器當機時依自己的排程重試,並讓每個事件都能重播。 換一個網址,程式碼不用動。

運作方式 →