投递行为
取自该平台的官方文档,最近核对于 2026-08-06。平台没有给出数字的地方,这张表也不填。
| 响应时限 | 3 秒 交互端点必须在 3 秒内发出初始响应 |
|---|---|
| 重试 | 平台未公布 |
| 放弃 | 平台未公布 |
| 出处 | https://docs.discord.com/developers/interactions/receiving-and-responding |
签名
用一个经测试套件证明的可运行验证器核对,不是照着文档读来的。最近核对于 2026-08-20。
| 算法 | Ed25519 |
|---|---|
| 待签名串 | {timestamp}{body} |
| 编码 | hex |
| 请求头 | x-signature-ed25519 + x-signature-timestamp |
| 时间容差 | 无强制要求 |
验证签名
要用原始请求体,逐字节一致,并且在任何 JSON 解析之前。框架一旦重新序列化请求体,本页的每一种方案都会失效。
// 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 会主动用无效签名探测端点,如果验证通过,就拒绝这个 URL。所以一个空壳验证器过不了接入流程,而不只是过不了安全审查。
容易踩的坑
3 秒的时限针对的是初始交互响应。退路是 type 5(deferred):在时限内先应答,等实际工作完成后再发送后续消息。
延伸阅读
AnyHook 挡在接收 Discord Webhook 的端点前面:约 1 秒应答,你的服务器宕机时按自己的计划重试,并且每个事件都可以重放。 只改一个 URL,代码不用动。