From aac247cc18a2ff98090fde76ef6a6818340f88b4 Mon Sep 17 00:00:00 2001 From: Almeida Date: Wed, 8 Oct 2025 09:37:02 +0100 Subject: [PATCH] feat: add `{add,remove}GroupDMRecipient methods` (#11135) * feat: add `{add,delete}GroupDMRecipient methods` * fix: requested changes --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- packages/core/scripts/check-routes.mjs | 34 +++++++++++++++ packages/core/src/api/channel.ts | 58 ++++++++++++++++++++++---- 2 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 packages/core/scripts/check-routes.mjs diff --git a/packages/core/scripts/check-routes.mjs b/packages/core/scripts/check-routes.mjs new file mode 100644 index 000000000..1cb08866b --- /dev/null +++ b/packages/core/scripts/check-routes.mjs @@ -0,0 +1,34 @@ +import { Routes } from 'discord-api-types/v10'; +import { glob, readFile } from 'node:fs/promises'; + +const usedRoutes = new Set(); + +const ignoredRoutes = new Set([ + // Deprecated + 'channelPins', + 'channelPin', + 'guilds', + 'guildCurrentMemberNickname', + 'guildMFA', + 'nitroStickerPacks', +]); + +for await (const file of glob('src/api/*.ts')) { + const content = await readFile(file, 'utf-8'); + + const routes = content.matchAll(/Routes\.([\w\d_]+)/g); + for (const route of routes) { + usedRoutes.add(route[1]); + } +} + +const unusedRoutes = Object.keys(Routes).filter((route) => !usedRoutes.has(route) && !ignoredRoutes.has(route)); + +if (unusedRoutes.length > 0) { + console.warn('The following routes are not implemented:'); + for (const route of unusedRoutes) { + console.warn(` - ${route}`); + } +} else { + console.log('No missing routes.'); +} diff --git a/packages/core/src/api/channel.ts b/packages/core/src/api/channel.ts index a25f948e3..89f38d940 100644 --- a/packages/core/src/api/channel.ts +++ b/packages/core/src/api/channel.ts @@ -1,10 +1,9 @@ /* eslint-disable jsdoc/check-param-names */ -import { makeURLSearchParams, type RawFile, type REST, type RequestData } from '@discordjs/rest'; +import { makeURLSearchParams, type RawFile, type RequestData, type REST } from '@discordjs/rest'; import { Routes, - type RESTPostAPIChannelWebhookJSONBody, - type RESTPostAPIChannelWebhookResult, + type APIThreadChannel, type RESTDeleteAPIChannelResult, type RESTGetAPIChannelInvitesResult, type RESTGetAPIChannelMessageReactionUsersQuery, @@ -18,8 +17,8 @@ import { type RESTGetAPIChannelThreadsArchivedQuery, type RESTGetAPIChannelUsersThreadsArchivedResult, type RESTGetAPIChannelWebhooksResult, - type RESTPatchAPIChannelMessageJSONBody, type RESTPatchAPIChannelJSONBody, + type RESTPatchAPIChannelMessageJSONBody, type RESTPatchAPIChannelMessageResult, type RESTPatchAPIChannelResult, type RESTPostAPIChannelFollowersResult, @@ -28,14 +27,16 @@ import { type RESTPostAPIChannelMessageCrosspostResult, type RESTPostAPIChannelMessageJSONBody, type RESTPostAPIChannelMessageResult, - type RESTPutAPIChannelPermissionJSONBody, - type Snowflake, type RESTPostAPIChannelThreadsJSONBody, type RESTPostAPIChannelThreadsResult, - type APIThreadChannel, + type RESTPostAPIChannelWebhookJSONBody, + type RESTPostAPIChannelWebhookResult, type RESTPostAPIGuildForumThreadsJSONBody, - type RESTPostAPISoundboardSendSoundJSONBody, type RESTPostAPISendSoundboardSoundResult, + type RESTPostAPISoundboardSendSoundJSONBody, + type RESTPutAPIChannelPermissionJSONBody, + type RESTPutAPIChannelRecipientJSONBody, + type Snowflake, } from 'discord-api-types/v10'; export interface StartForumThreadOptions extends RESTPostAPIGuildForumThreadsJSONBody { @@ -708,4 +709,45 @@ export class ChannelsAPI { signal, }) as Promise; } + + /** + * Adds a recipient to a group DM channel + * + * @see {@link https://discord.com/developers/docs/resources/channel#group-dm-add-recipient} + * @param channelId - The id of the channel to add the recipient to + * @param userId - The id of the user to add as a recipient + * @param body - The data for adding the recipient + * @param options - The options for adding the recipient + */ + public async addGroupDMRecipient( + channelId: Snowflake, + userId: Snowflake, + body: RESTPutAPIChannelRecipientJSONBody, + { auth, signal }: Pick = {}, + ) { + await this.rest.put(Routes.channelRecipient(channelId, userId), { + auth, + body, + signal, + }); + } + + /** + * Removes a recipient from a group DM channel + * + * @see {@link https://discord.com/developers/docs/resources/channel#group-dm-remove-recipient} + * @param channelId - The id of the channel to remove the recipient from + * @param userId - The id of the user to remove as a recipient + * @param options - The options for removing the recipient + */ + public async removeGroupDMRecipient( + channelId: Snowflake, + userId: Snowflake, + { auth, signal }: Pick = {}, + ) { + await this.rest.delete(Routes.channelRecipient(channelId, userId), { + auth, + signal, + }); + } }