diff --git a/packages/bot/src/helpers.ts b/packages/bot/src/helpers.ts index 0cc2e0d52..e1a828424 100644 --- a/packages/bot/src/helpers.ts +++ b/packages/bot/src/helpers.ts @@ -74,6 +74,7 @@ import type { GetReactions, GetScheduledEventUsers, GetScheduledEvents, + GetThreadMember, GetUserGuilds, GetWebhookMessageOptions, InteractionCallbackData, @@ -82,6 +83,7 @@ import type { ListArchivedThreads, ListGuildMembers, ListSkuSubscriptionsOptions, + ListThreadMembers, MfaLevels, ModifyApplicationEmoji, ModifyChannel, @@ -489,11 +491,11 @@ export function createBotHelpers { return bot.transformers.sticker(bot, snakelize(await bot.rest.getSticker(stickerId))) }, - getThreadMember: async (channelId, userId) => { - return bot.transformers.threadMember(bot, snakelize(await bot.rest.getThreadMember(channelId, userId))) + getThreadMember: async (channelId, userId, options) => { + return bot.transformers.threadMember(bot, snakelize(await bot.rest.getThreadMember(channelId, userId, options))) }, - getThreadMembers: async (channelId) => { - return (await bot.rest.getThreadMembers(channelId)).map((res) => bot.transformers.threadMember(bot, snakelize(res))) + getThreadMembers: async (channelId, options) => { + return (await bot.rest.getThreadMembers(channelId, options)).map((res) => bot.transformers.threadMember(bot, snakelize(res))) }, getReactions: async (channelId, messageId, reaction, options) => { return (await bot.rest.getReactions(channelId, messageId, reaction, options)).map((res) => bot.transformers.user(bot, snakelize(res))) @@ -1003,8 +1005,8 @@ export type BotHelpers Promise> getUserVoiceState: (guildId: BigString, userId: BigString) => Promise> getSticker: (stickerId: BigString) => Promise> - getThreadMember: (channelId: BigString, userId: BigString) => Promise - getThreadMembers: (channelId: BigString) => Promise + getThreadMember: (channelId: BigString, userId: BigString, options?: GetThreadMember) => Promise + getThreadMembers: (channelId: BigString, options?: ListThreadMembers) => Promise getReactions: ( channelId: BigString, messageId: BigString, diff --git a/packages/bot/src/transformers.ts b/packages/bot/src/transformers.ts index 31a258cbd..41c1d26d2 100644 --- a/packages/bot/src/transformers.ts +++ b/packages/bot/src/transformers.ts @@ -470,7 +470,12 @@ export type Transformers, payload: DiscordInviteStageInstance & { guildId: BigString }, ) => SetupDesiredProps - member: (bot: Bot, payload: DiscordMember, guildId: BigString, userId: BigString) => SetupDesiredProps + member: ( + bot: Bot, + payload: DiscordMember, + guildId: BigString | undefined, + userId: BigString, + ) => SetupDesiredProps message: (bot: Bot, payload: { message: DiscordMessage; shardId: number }) => SetupDesiredProps messageCall: (bot: Bot, payload: DiscordMessageCall) => SetupDesiredProps messageInteractionMetadata: ( diff --git a/packages/bot/src/transformers/threadMember.ts b/packages/bot/src/transformers/threadMember.ts index 3fa70f48a..cd3e3a2a5 100644 --- a/packages/bot/src/transformers/threadMember.ts +++ b/packages/bot/src/transformers/threadMember.ts @@ -7,6 +7,7 @@ export function transformThreadMember(bot: Bot, payload: DiscordThreadMember): T userId: payload.user_id ? bot.transformers.snowflake(payload.user_id) : undefined, joinTimestamp: Date.parse(payload.join_timestamp), flags: payload.flags, + member: payload.member ? bot.transformers.member(bot, payload.member, undefined, bot.transformers.snowflake(payload.user_id)) : undefined, } as ThreadMember return bot.transformers.customizers.threadMember(bot, payload, threadMember) diff --git a/packages/bot/src/transformers/types.ts b/packages/bot/src/transformers/types.ts index feb1c8751..d7eb3e39a 100644 --- a/packages/bot/src/transformers/types.ts +++ b/packages/bot/src/transformers/types.ts @@ -1033,8 +1033,13 @@ export interface Member { id: bigint /** The compressed form of all the boolean values on this user. */ toggles?: MemberToggles - /** The guild id where this member is. */ - guildId: bigint + /** + * The guild id where this member is. + * + * @remarks + * This will always be present unless the member object is from thread member object. + * */ + guildId?: bigint /** The user this guild member represents */ user?: User /** This user's guild nickname */ diff --git a/packages/rest/src/manager.ts b/packages/rest/src/manager.ts index 7b5c4aadb..0851c9bda 100644 --- a/packages/rest/src/manager.ts +++ b/packages/rest/src/manager.ts @@ -1395,12 +1395,12 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage return await rest.get(rest.routes.guilds.stickers(guildId)) }, - async getThreadMember(channelId, userId) { - return await rest.get(rest.routes.channels.threads.user(channelId, userId)) + async getThreadMember(channelId, userId, options) { + return await rest.get(rest.routes.channels.threads.getUser(channelId, userId, options)) }, - async getThreadMembers(channelId) { - return await rest.get(rest.routes.channels.threads.members(channelId)) + async getThreadMembers(channelId, options) { + return await rest.get(rest.routes.channels.threads.members(channelId, options)) }, async getReactions(channelId, messageId, reaction, options) { diff --git a/packages/rest/src/routes.ts b/packages/rest/src/routes.ts index 828def86e..f3fd594ca 100644 --- a/packages/rest/src/routes.ts +++ b/packages/rest/src/routes.ts @@ -161,12 +161,29 @@ export function createRoutes(): RestRoutes { active: (guildId) => { return `/guilds/${guildId}/threads/active` }, - members: (channelId) => { - return `/channels/${channelId}/thread-members` + members: (channelId, options) => { + let url = `/channels/${channelId}/thread-members?` + + if (options) { + if (options.withMember) url += `with_member=${options.withMember}` + if (options.limit) url += `&limit=${options.limit}` + if (options.after) url += `&after=${options.after}` + } + + return url }, me: (channelId) => { return `/channels/${channelId}/thread-members/@me` }, + getUser(channelId, userId, options) { + let url = `/channels/${channelId}/thread-members/${userId}?` + + if (options) { + if (options.withMember) url += `with_member=${options.withMember}` + } + + return url + }, user: (channelId, userId) => { return `/channels/${channelId}/thread-members/${userId}` }, diff --git a/packages/rest/src/types.ts b/packages/rest/src/types.ts index b73e6ae12..4266727dc 100644 --- a/packages/rest/src/types.ts +++ b/packages/rest/src/types.ts @@ -108,6 +108,7 @@ import type { GetReactions, GetScheduledEventUsers, GetScheduledEvents, + GetThreadMember, GetUserGuilds, GetWebhookMessageOptions, InteractionCallbackData, @@ -116,6 +117,7 @@ import type { ListArchivedThreads, ListGuildMembers, ListSkuSubscriptionsOptions, + ListThreadMembers, MfaLevels, ModifyApplicationEmoji, ModifyChannel, @@ -2265,15 +2267,17 @@ export interface RestManager { * * @param channelId - The ID of the thread to get the thread member of. * @param userId - The user ID of the thread member to get. + * @param options - The parameters for the fetching of the thread member. * @returns An instance of {@link DiscordThreadMember}. * * @see {@link https://discord.com/developers/docs/resources/channel#get-thread-member} */ - getThreadMember: (channelId: BigString, userId: BigString) => Promise> + getThreadMember: (channelId: BigString, userId: BigString, options?: GetThreadMember) => Promise> /** * Gets the list of thread members for a thread. * * @param channelId - The ID of the thread to get the thread members of. + * @param options - The parameters for the fetching of the thread members. * @returns A collection of {@link DiscordThreadMember} assorted by user ID. * * @remarks @@ -2281,7 +2285,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#list-thread-members} */ - getThreadMembers: (channelId: BigString) => Promise[]> + getThreadMembers: (channelId: BigString, options?: ListThreadMembers) => Promise[]> /** * Gets the list of users that reacted with an emoji to a message. * diff --git a/packages/rest/src/typings/routes.ts b/packages/rest/src/typings/routes.ts index 5853a8932..2f0ce595d 100644 --- a/packages/rest/src/typings/routes.ts +++ b/packages/rest/src/typings/routes.ts @@ -9,11 +9,13 @@ import type { GetPollAnswerVotes, GetReactions, GetScheduledEventUsers, + GetThreadMember, GetUserGuilds, InteractionCallbackOptions, ListArchivedThreads, ListGuildMembers, ListSkuSubscriptionsOptions, + ListThreadMembers, } from '@discordeno/types' export interface RestRoutes { @@ -78,10 +80,12 @@ export interface RestRoutes { /** Route for active threads. */ active: (guildId: BigString) => string /** Route for members in a thread. */ - members: (channelId: BigString) => string + members: (channelId: BigString, options?: ListThreadMembers) => string /** Route for the bot member in a thread. */ me: (channelId: BigString) => string - /** Route for a specific member in a thread. */ + /** Route for getting a specific member in a thread. */ + getUser: (channelId: BigString, userId: BigString, options?: GetThreadMember) => string + /** Route for a specific member in a thread apart from the route for getting the member. */ user: (channelId: BigString, userId: BigString) => string /** Route for handling archived threads. */ archived: (channelId: BigString) => string diff --git a/packages/types/src/discord/channel.ts b/packages/types/src/discord/channel.ts index 5db153f3a..03c1f906c 100644 --- a/packages/types/src/discord/channel.ts +++ b/packages/types/src/discord/channel.ts @@ -1,5 +1,6 @@ /** Types for: https://discord.com/developers/docs/resources/channel */ +import type { DiscordMember } from './guild.js' import type { DiscordMessageComponents } from './interactions.js' import type { DiscordAllowedMentions, DiscordAttachment, DiscordEmbed, MessageFlags } from './message.js' import type { DiscordUser } from './user.js' @@ -199,6 +200,8 @@ export interface DiscordThreadMember { user_id: string /** The time the current user last joined the thread */ join_timestamp: string + /** The member object of the user */ + member?: DiscordMember } /** https://discord.com/developers/docs/resources/channel#thread-member-object-thread-member-structure, the first asterisk */ diff --git a/packages/types/src/discordeno.ts b/packages/types/src/discordeno.ts index 2550ebf5a..e40a7425a 100644 --- a/packages/types/src/discordeno.ts +++ b/packages/types/src/discordeno.ts @@ -384,6 +384,22 @@ export interface ListArchivedThreads { limit?: number } +/** https://discord.com/developers/docs/resources/channel#get-thread-member-query-string-params */ +export interface GetThreadMember { + /** Whether to include a guild member object for the thread member */ + withMember?: boolean +} + +/** https://discord.com/developers/docs/resources/channel#list-thread-members-query-string-params */ +export interface ListThreadMembers { + /** Whether to include a guild member object for the thread member */ + withMember?: boolean + /** Get thread members after this user ID */ + after?: BigString + /** Max number of thread members to return (1-100). Defaults to 100. */ + limit?: BigString +} + /** https://discord.com/developers/docs/resources/audit-log#get-guild-audit-log-query-string-parameters */ export interface GetGuildAuditLog { /** Entries from a specific user ID */