Skip to content

Commit d03cacb

Browse files
authored
feat(MessageManager)!: New pinned messages routes (#10989)
BREAKING CHANGE: `fetchPinned()` has been renamed to `fetchPins()`, which is a paginated endpoint to fetch pinned messages.
1 parent 5a611be commit d03cacb

File tree

3 files changed

+71
-14
lines changed

3 files changed

+71
-14
lines changed

packages/discord.js/src/managers/MessageManager.js

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -123,24 +123,63 @@ class MessageManager extends CachedManager {
123123
return data.reduce((_data, message) => _data.set(message.id, this._add(message, options.cache)), new Collection());
124124
}
125125

126+
/**
127+
* Options used to fetch pinned messages.
128+
*
129+
* @typedef {Object} FetchPinnedMessagesOptions
130+
* @property {DateResolvable} [before] Consider only pinned messages before this time
131+
* @property {number} [limit] The maximum number of pinned messages to return
132+
* @property {boolean} [cache] Whether to cache the pinned messages
133+
*/
134+
135+
/**
136+
* Data returned from fetching pinned messages.
137+
*
138+
* @typedef {Object} FetchPinnedMessagesResponse
139+
* @property {MessagePin[]} items The pinned messages
140+
* @property {boolean} hasMore Whether there are additional pinned messages that require a subsequent call
141+
*/
142+
143+
/**
144+
* Pinned message data returned from fetching pinned messages.
145+
*
146+
* @typedef {Object} MessagePin
147+
* @property {Date} pinnedAt The time the message was pinned at
148+
* @property {number} pinnedTimestamp The timestamp the message was pinned at
149+
* @property {Message} message The pinned message
150+
*/
151+
126152
/**
127153
* Fetches the pinned messages of this channel and returns a collection of them.
128154
* <info>The returned Collection does not contain any reaction data of the messages.
129155
* Those need to be fetched separately.</info>
130156
*
131-
* @param {boolean} [cache=true] Whether to cache the message(s)
132-
* @returns {Promise<Collection<Snowflake, Message>>}
157+
* @param {FetchPinnedMessagesOptions} [options={}] Options for fetching pinned messages
158+
* @returns {Promise<FetchPinnedMessagesResponse>}
133159
* @example
134160
* // Get pinned messages
135-
* channel.messages.fetchPinned()
136-
* .then(messages => console.log(`Received ${messages.size} messages`))
161+
* channel.messages.fetchPins()
162+
* .then(messages => console.log(`Received ${messages.items.length} messages`))
137163
* .catch(console.error);
138164
*/
139-
async fetchPinned(cache = true) {
140-
const data = await this.client.rest.get(Routes.channelPins(this.channel.id));
141-
const messages = new Collection();
142-
for (const message of data) messages.set(message.id, this._add(message, cache));
143-
return messages;
165+
async fetchPins(options = {}) {
166+
const data = await this.client.rest.get(Routes.channelMessagesPins(this.channel.id), {
167+
query: makeURLSearchParams({
168+
...options,
169+
before: options.before && new Date(options.before).toISOString(),
170+
}),
171+
});
172+
173+
return {
174+
items: data.items.map(item => ({
175+
pinnedTimestamp: Date.parse(item.pinned_at),
176+
get pinnedAt() {
177+
return new Date(this.pinnedTimestamp);
178+
},
179+
message: this._add(item.message, options.cache),
180+
})),
181+
hasMore: data.has_more,
182+
};
144183
}
145184

146185
/**
@@ -221,7 +260,7 @@ class MessageManager extends CachedManager {
221260
const messageId = this.resolveId(message);
222261
if (!messageId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
223262

224-
await this.client.rest.put(Routes.channelPin(this.channel.id, messageId), { reason });
263+
await this.client.rest.put(Routes.channelMessagesPin(this.channel.id, messageId), { reason });
225264
}
226265

227266
/**
@@ -235,7 +274,7 @@ class MessageManager extends CachedManager {
235274
const messageId = this.resolveId(message);
236275
if (!messageId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
237276

238-
await this.client.rest.delete(Routes.channelPin(this.channel.id, messageId), { reason });
277+
await this.client.rest.delete(Routes.channelMessagesPin(this.channel.id, messageId), { reason });
239278
}
240279

241280
/**

packages/discord.js/typings/index.d.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4516,7 +4516,7 @@ export abstract class MessageManager<InGuild extends boolean = boolean> extends
45164516
): Promise<Message<InGuild>>;
45174517
public fetch(options: FetchMessageOptions | MessageResolvable): Promise<Message<InGuild>>;
45184518
public fetch(options?: FetchMessagesOptions): Promise<Collection<Snowflake, Message<InGuild>>>;
4519-
public fetchPinned(cache?: boolean): Promise<Collection<Snowflake, Message<InGuild>>>;
4519+
public fetchPins(options?: FetchPinnedMessagesOptions): Promise<FetchPinnedMessagesResponse<InGuild>>;
45204520
public react(message: MessageResolvable, emoji: EmojiIdentifierResolvable): Promise<void>;
45214521
public pin(message: MessageResolvable, reason?: string): Promise<void>;
45224522
public unpin(message: MessageResolvable, reason?: string): Promise<void>;
@@ -5800,6 +5800,23 @@ export interface FetchMessagesOptions {
58005800
limit?: number;
58015801
}
58025802

5803+
export interface FetchPinnedMessagesOptions {
5804+
before?: DateResolvable;
5805+
cache?: boolean;
5806+
limit?: number;
5807+
}
5808+
5809+
export interface FetchPinnedMessagesResponse<InGuild extends boolean = boolean> {
5810+
hasMore: boolean;
5811+
items: readonly MessagePin<InGuild>[];
5812+
}
5813+
5814+
export interface MessagePin<InGuild extends boolean = boolean> {
5815+
message: Message<InGuild>;
5816+
get pinnedAt(): Date;
5817+
pinnedTimestamp: number;
5818+
}
5819+
58035820
export interface FetchReactionUsersOptions {
58045821
after?: Snowflake;
58055822
limit?: number;

packages/discord.js/typings/index.test-d.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ import type {
9999
Entitlement,
100100
FetchedThreads,
101101
FetchedThreadsMore,
102+
FetchPinnedMessagesResponse,
102103
FileComponentData,
103104
ForumChannel,
104105
Guild,
@@ -1756,7 +1757,7 @@ declare const guildChannelManager: GuildChannelManager;
17561757
expectType<Promise<Message<true>>>(messages.crosspost('1234567890'));
17571758
expectType<Promise<Message<true>>>(messages.edit('1234567890', 'text'));
17581759
expectType<Promise<Message<true>>>(messages.fetch('1234567890'));
1759-
expectType<Promise<Collection<Snowflake, Message<true>>>>(messages.fetchPinned());
1760+
expectType<Promise<FetchPinnedMessagesResponse<true>>>(messages.fetchPins());
17601761
expectType<Guild>(message.guild);
17611762
expectType<Snowflake>(message.guildId);
17621763
expectType<GuildTextBasedChannel>(message.channel.messages.channel);
@@ -1769,7 +1770,7 @@ declare const guildChannelManager: GuildChannelManager;
17691770
expectType<DMMessageManager>(messages);
17701771
expectType<Promise<Message>>(messages.edit('1234567890', 'text'));
17711772
expectType<Promise<Message>>(messages.fetch('1234567890'));
1772-
expectType<Promise<Collection<Snowflake, Message>>>(messages.fetchPinned());
1773+
expectType<Promise<FetchPinnedMessagesResponse>>(messages.fetchPins());
17731774
expectType<Guild | null>(message.guild);
17741775
expectType<Snowflake | null>(message.guildId);
17751776
expectType<DMChannel | GuildTextBasedChannel | PartialGroupDMChannel>(message.channel.messages.channel);

0 commit comments

Comments
 (0)