ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

@discordjs/rest 使用指南:用模块化 REST 客户端稳定对接 Discord API

@discordjs/rest 使用指南:用模块化 REST 客户端稳定对接 Discord API discordjs/rest 使用指南用模块化 REST 客户端稳定对接 Discord API【免费下载链接】discord.jsA powerful JavaScript library for interacting with the Discord API项目地址: https://gitcode.com/gh_mirrors/di/discord.jsdiscordjs/rest是 discord.js 生态中负责向 Discord API 发起 REST 请求的独立模块它封装了鉴权、限流队列、重试、超时、文件上传等底层细节让开发者只需关注“调哪个接口、传什么参数”。本文以 packages/rest/README.md 为主体结合packages/rest/src下的源码实现从安装、三个官方示例出发深入讲解 REST 实例的完整配置项、请求数据结构、桶bucket与限流处理机制、错误处理与事件体系以及 CDN 链接构建等实战能力。读完本文你将能够独立使用discordjs/rest编写可靠的 Discord Bot REST 调用代码并理解其内部如何在各种限流下保证请求稳定。模块定位专注 REST职责单一discordjs/rest的设计目标非常明确让你可以轻松地向 Discord API 发起 REST 请求。它不负责 Gateway 长连接、不负责消息缓存只把发请求这件事做到位自动处理Authorization鉴权头Bot 或 Bearer自动解析并遵守 Discord 的速率限制rate limit响应头内置请求队列串行化同一限流桶内的请求支持超时中断、5xx 自动重试、文件上传multipart/form-data同时面向 Node.js 与边缘环境如 Cloudflare Workers提供可用的构建产物。从 package.json 的exports字段可以看到该包针对node条件导出dist/index.js/dist/index.mjs而对其他环境默认导出dist/web.js/dist/web.mjs并在 src/index.ts 中根据运行环境自动选择全局fetch还是 undici 的makeRequest作为底层请求策略。这意味着同一个 API 可以无缝运行在 Node 与边缘运行时上。安装与环境要求安装非常简单支持主流包管理器见 READMEnpm install discordjs/rest yarn add discordjs/rest pnpm add discordjs/rest bun add discordjs/rest运行环境要求Node.js 24.17.0 或更高版本。这一约束同时体现在 package.json 的engines字段node: 24.17.0中低版本 Node 将无法安装或运行。由于discordjs/rest本身不包含 Discord API 的路由定义日常使用还需要搭配类型库discord-api-types来获得类型安全的路由Routes与请求/响应类型npm install discordjs/rest discord-api-types yarn add discordjs/rest discord-api-types pnpm add discordjs/rest discord-api-types bun add discordjs/rest discord-api-types示例一发送一条基础消息官方 README 给出的第一个示例展示了最核心的调用方式创建REST实例 → 设置 Token → 调用rest.post()源码示例import { REST } from discordjs/rest; import { Routes } from discord-api-types/v10; const rest new REST({ version: 10 }).setToken(TOKEN); try { await rest.post(Routes.channelMessages(CHANNEL_ID), { body: { content: A message via REST!, }, }); } catch (error) { console.error(error); }这段代码有几个要点值得展开new REST({ version: 10 })指定使用 Discord API v10。version选项会拼接进请求 URL形如https://discord.com/api/v10/...该过程在 REST.ts 的resolveRequest中完成URL 由api基础地址、可选版本段、fullRoute与查询串拼接而成。.setToken(TOKEN)将鉴权令牌保存在实例内部见 REST.ts后续每次请求会自动携带Authorization: Bot TOKEN头默认前缀为Bot见下文authPrefix选项。Routes.channelMessages(CHANNEL_ID)来自discord-api-types返回/channels/{id}/messages形式的路径字符串rest.post会把body序列化为 JSON并自动设置Content-Type: application/json。调用rest.post返回的 Promise 解析为响应体解析后的数据如果响应的Content-Type是 JSON 则返回解析后的对象否则返回ArrayBuffer见 utils.ts 的parseResponse。示例二从已有消息创建线程第二个官方示例展示了如何传递非 content 字段的请求体并演示了 REST 调用中常见的创建资源并设置归档策略场景源码示例import { REST } from discordjs/rest; import { Routes } from discord-api-types/v10; const rest new REST({ version: 10 }).setToken(TOKEN); try { await rest.post(Routes.threads(CHANNEL_ID, MESSAGE_ID), { body: { name: Thread, auto_archive_duration: 60, }, }); } catch (error) { console.error(error); }这里Routes.threads(CHANNEL_ID, MESSAGE_ID)会构造/channels/{channelId}/messages/{messageId}/threads路由body中name指定线程名称auto_archive_duration: 60表示线程在 60 分钟不活跃后自动归档。该请求体同样会被 JSON 序列化并附带Content-Type: application/json头见 REST.ts。示例三在边缘环境Edge中发送消息discordjs/rest的一大特色是可在边缘运行时使用。官方示例通过makeRequest: fetch让模块改用全局fetch而非 Node 的 undici 客户端源码示例import { REST } from discordjs/rest; import { Routes } from discord-api-types/v10; const rest new REST({ version: 10, makeRequest: fetch }).setToken(TOKEN); try { await rest.post(Routes.channelMessages(CHANNEL_ID), { body: { content: A message via REST from the edge!, }, }); } catch (error) { console.error(error); }makeRequest是RESTOptions中可自定义的底层 HTTP 执行函数类型为(url: string, init: RequestInit) PromiseResponseLike见 types.ts。默认实现来自 environment.ts 中保存的策略Node 环境优先使用全局fetch通过discordjs/util的shouldUseGlobalFetchAndWebSocket判断否则回退到 undici 的makeRequest见 index.ts。如果你部署在 Cloudflare Workers、Vercel Edge 等环境只需像示例一样显式传入fetch即可让 REST 模块脱离 Node 特有的依赖运行。REST 实例的完整配置项REST构造函数接收一个PartialRESTOptions其所有字段、默认值与语义定义在 constants.ts 的DefaultRestOptions与 types.ts 的RESTOptions接口中。下表整理了完整配置配置项默认值说明apihttps://discord.com/apiAPI 基础地址不含版本号version10API 版本会拼入 URL 形成/v10段authPrefixBot鉴权前缀可改为Bearer以支持 bearer tokencdnhttps://cdn.discordapp.comCDN 资源基础地址mediaProxyhttps://media.discordapp.net媒体代理地址用于 sticker gif 等场景agentnull全局 undici Dispatcher/Agentheaders{}附加到所有请求的额外请求头userAgentAppendix运行时生成的附加信息追加到 User-Agent 的字符串timeout15_000单请求超时毫秒数可为函数retries35xx 或超时请求的重试次数retryBackoff0重试前的退避毫秒数可为函数指数递增globalRequestsPerSecond50每秒全局请求数上限可设为Infinityoffset50限流等待的额外偏移毫秒数保险缓冲可为函数rejectOnRateLimitnull命中限流时是否抛RateLimitError可为函数或路由前缀数组invalidRequestWarningInterval0每 N 次无效请求401/403/429发出一次警告0 表示关闭hashSweepInterval14_400_0004 小时桶哈希清扫间隔hashLifetime86_400_00024 小时桶哈希最长空闲存活时间handlerSweepInterval3_600_0001 小时请求处理器清扫间隔makeRequest默认策略底层实际发起 HTTP 请求的函数几个配置项在源码中的具体影响offset在 utils.ts 的normalizeRateLimitOffset中被统一为Math.max(0, offset)可传数字或按路由返回数字的函数用于在服务端限流时间上增加保险余量避免因时钟偏差撞上限流。retries/retryBackoff对 5xx 与超时请求生效。数字形式的退避会按Math.max(0, backoff) * (1 retryCount)指数递增函数形式则返回null表示放弃重试直接抛错见 utils.ts。rejectOnRateLimit传字符串数组时按路由前缀匹配如/channels会匹配/channels/:id/messages传函数时可根据完整的RateLimitData决定是否抛错见 utils.ts。清扫器构造函数会启动两个定时器分别清扫过期桶哈希与空闲请求处理器间隔超过 4 小时14_400_000ms会被拒绝见 REST.ts并可通过clearHashSweeper()/clearHandlerSweeper()手动停止。请求方法、路由与请求体选项REST类为每个 HTTP 动词提供了同名便捷方法全部收敛到底层request()见 REST.tsrest.get(fullRoute, options)rest.delete(fullRoute, options)rest.post(fullRoute, options)rest.put(fullRoute, options)rest.patch(fullRoute, options)其中fullRoute类型为/${string}见 types.ts。每个方法都接受可选的RequestData其字段定义于 types.ts包括字段说明body请求体传BodyInit时需配合passThroughBodypassThroughBody为true时把body原样透传给底层fetch仅在无files时生效files附加文件RawFile[]存在时请求自动转为 multipart/form-dataappendToFormData有文件时把 JSON body 的每个字段直接 append 到 formData 而非使用payload_jsonqueryURLSearchParams形式的查询参数reason审计日志原因会写入X-Audit-Log-Reason头URL 编码auth本次请求独立的鉴权数据{ prefix?, token }或false关闭鉴权头headers追加到本次请求的额外请求头dispatcher本次请求专用的 undici AgentsignalAbortSignal用于取消排队或进行中的请求versioned是否拼入 API 版本段默认true这些字段在 REST.ts 的resolveRequest中被逐一加工成最终的fetch选项查询串被序列化、User-Agent与Authorization头被组装、reason被编码进审计头、文件数组被转为FormData并通过magic-bytes.js自动推断文件 MIME 类型见 REST.ts。此外GET/HEAD请求的 body 会被置为null避免与 fetch 规范行为不一致。关于auth还有一个实用细节当请求打到含 token 的路由如 interactions 或 webhook时文档建议设置auth: false以免 401 时实例误清空全局 token见 types.ts 注释。源码深处的限流处理桶、major parameter 与请求处理器REST 模块最核心的价值在于限流管理其实现横跨三个文件REST.queueRequest→SequentialHandler/BurstHandler→Shared.makeNetworkRequest。第一步路由泛化与桶哈希定位。每次请求进入 queueRequest 时会调用静态方法generateRouteData见 REST.ts把原始端点泛化将端点中的 17~19 位 Snowflake ID 替换为:id将 reaction 子路径统一为:reaction将 webhook token 部分统一为:token提取major parameter如/channels/{id}、/guilds/{id}、/webhooks/{id}/{token}中的 id 或 idtoken没有则为global对DELETE /channels/:id/messages/:id有硬编码例外若目标消息超过 14 天则追加/Delete Old Message例外因为删除 14 天前的消息属于不同限流桶对应 discord-api-docs#1295 的已知行为对/interactions/{id}/{token}/callback这类交互回调路由直接标记 major parameter 为burst见 REST.ts。第二步选择请求处理器。根据哈希值与 major parametercreateHandler见 REST.ts会创建两类处理器SequentialHandlerSequentialHandler.ts默认处理器。每个处理器内部维护一个基于sapphire/async-queue的异步队列同一桶内的请求严格串行它会跟踪X-RateLimit-Limit/X-RateLimit-Remaining/X-RateLimit-Reset-After/X-RateLimit-Bucket/Retry-After等响应头见 SequentialHandler.ts在命中限流时自动sleep等待并支持全局限流globalRemaining/globalReset与子限流sublimit如 10 分钟内改 2 次频道名的分离队列处理。BurstHandlerBurstHandler.ts用于交互回调等无常规限流的路由不做排队与预判限流但遇到意外的 429 仍会尊重Retry-After并等待后重试。第三步网络请求、超时与重试。Shared.makeNetworkRequest见 Shared.ts为每次请求创建AbortController并绑定超时定时器同时将用户的AbortSignal桥接过来遇到AbortError或ECONNRESET时按retries次数重试见 utils.ts 的shouldRetry。响应到达后还会统计无效请求数401/403/429 会被计入按 IP 维度统计的 10 分钟窗口计数器达到invalidRequestWarningInterval倍数时发出invalidRequestWarning事件见 Shared.ts。第四步错误分类。handleErrors见 Shared.ts对非 429 状态码做分类5xx 按退避策略重试重试耗尽后抛HTTPError4xx 解析 Discord 错误负载并抛DiscordAPIError其中 401 且auth true时还会自动清空实例 token 并输出一次性警告提醒调用方为含 token 路由设置auth: false。三类错误类分别定义在 errors 目录下DiscordAPIError、HTTPError、RateLimitError。事件体系监听限流与响应REST继承自AsyncEventEmitter可通过 constants.ts 中的RESTEvents枚举订阅以下事件事件签名见 types.ts事件触发时机restDebug输出内部调试信息桶哈希更新、限流等待、清扫等rateLimited命中限流携带完整的RateLimitDataglobal、hash、limit、retryAfter、scope、sublimitTimeout 等字段见 types.tsresponse每次请求收到响应时触发附带请求信息与响应副本invalidRequestWarning无效请求计数达到设定间隔handlerSweep/hashSweep清扫器移除空闲处理器 / 过期桶哈希时触发rateLimited事件是排查限流问题最直接的抓手RateLimitData中scope区分user按客户端、global全局与shared按资源共享majorParameter标明该桶绑定的资源 IDsublimitTimeout仅在命中子限流时非 0。附带能力CDN 链接构建器REST实例还暴露一个只读的cdn属性rest.cdn它是 CDN.ts 中CDN类的实例用于构建 Discord CDN 资源的 URL。支持的方法覆盖头像avatar、横幅banner、服务器图标icon、emojiemoji、贴纸sticker、角色图标roleIcon、默认头像defaultAvatar等十余类资源。它内部统一处理扩展名校验允许webp/png/jpg/jpeg/gif贴纸限定png/json/gif尺寸校验仅允许16/32/64/128/256/512/1024/2048/4096动图检测hash 以a_开头且未强制forceStatic时自动追加animatedtrue参数贴纸 gif 走mediaProxy而非 CDN 基础地址。例如rest.cdn.avatar(userId, avatarHash, { size: 512 })会生成形如https://cdn.discordapp.com/avatars/{userId}/{hash}.webp?size512的 URL。非法扩展名或尺寸会抛出带明确提示的RangeError。更多资源与参与方式模块完整 API 文档由docs脚本生成pnpm run build:docs api-extractor run见 package.json当前版本为2.5.0许可证为 Apache-2.0。仓库中与 REST 相关的可读材料模块 README、包配置、单元测试覆盖REST、RequestManager、RequestHandler、BurstHandler、CDN、DiscordAPIError等核心行为。若想了解该模块在完整 discord.js 库中的使用方式可查看 packages/discord.js 及 packages/core 中对 REST 的集成代码。提交 Issue 前请先确认问题未被报告过并核对 packages/rest/README.md 中指向的文档若想提交 PR请遵循仓库的贡献规范见仓库根目录的 CONTRIBUTING 相关文档。小结discordjs/rest用约十个文件就完整覆盖了 Discord REST API 客户端所需的全部能力从REST实例的六大 HTTP 方法与完整配置项到SequentialHandler/BurstHandler两套限流队列再到错误分类、事件监听与 CDN 链接构建。当你需要脱离完整 discord.js 框架、仅用最轻量的方式调用 Discord API尤其是部署到边缘环境时它就是最直接的答案三个官方示例覆盖了消息发送、线程创建与边缘部署三大高频场景而源码层面的桶哈希、major parameter 与子限流处理则保证了请求在复杂限流规则下的稳定性。【免费下载链接】discord.jsA powerful JavaScript library for interacting with the Discord API项目地址: https://gitcode.com/gh_mirrors/di/discord.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表