Cách Discord gửi webhook

Interaction cần phản hồi đầu tiên trong 3 giây, ký bằng Ed25519 thay vì HMAC. Định dạng đã kiểm chứng và code xác minh bằng Web Crypto.

Hành vi gửi

Lấy từ tài liệu của chính hãng, kiểm tra lần cuối 2026-08-06. Hãng không nêu con số nào thì bảng này cũng không ghi.

Thời hạn phản hồi3 giây

Endpoint nhận interaction phải gửi phản hồi đầu tiên trong vòng 3 giây

Kiểm tra handler của bạn có phản hồi kịp không

Thử lạihãng không công bố
Ngừng gửihãng không công bố
Nguồnhttps://docs.discord.com/developers/interactions/receiving-and-responding

Chữ ký

Kiểm chứng bằng một bộ xác minh chạy thật, có bộ test chứng minh, chứ không đọc từ tài liệu. Kiểm chứng lần cuối 2026-08-20.

Thuật toánEd25519
Payload được ký{timestamp}{body}
Encodinghex
Headerx-signature-ed25519 + x-signature-timestamp
Dung saikhông quy định

Xác minh

Dùng raw body của request, đúng từng byte, trước mọi bước parse JSON. Mọi cơ chế trên trang này đều hỏng ngay khi framework serialize lại 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 chủ động thăm dò endpoint bằng chữ ký không hợp lệ và từ chối URL nếu chúng lọt qua, nên một bộ xác minh viết tạm sẽ trượt ngay ở bước thiết lập, chứ không chỉ khi review bảo mật.

Những chỗ dễ vấp

Thời hạn 3 giây áp dụng cho phản hồi interaction đầu tiên. Lối thoát là type 5 (deferred): xác nhận trong thời hạn đó, rồi gửi follow-up khi xử lý xong việc thật.

Đọc thêm

AnyHook đứng trước các endpoint nhận webhook từ Discord: trả lời sau khoảng 1 giây, tự thử lại theo lịch riêng khi server của bạn ngừng hoạt động, và giữ mọi sự kiện để bạn phát lại được. Đổi một URL, giữ nguyên code.

Cách hoạt động →