Skip to content

Commit e4791af

Browse files
committed
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 a271e9b commit e4791af

File tree

3 files changed

+93
-6
lines changed

3 files changed

+93
-6
lines changed

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

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ const MessagePayload = require('../structures/MessagePayload');
1010
const { MakeCacheOverrideSymbol } = require('../util/Symbols');
1111
const { resolvePartialEmoji } = require('../util/Util');
1212

13+
let deprecationEmittedForFetchPinned = false;
14+
1315
/**
1416
* Manages API methods for Messages and holds their cache.
1517
* @extends {CachedManager}
@@ -116,19 +118,83 @@ class MessageManager extends CachedManager {
116118
return data.reduce((_data, message) => _data.set(message.id, this._add(message, options.cache)), new Collection());
117119
}
118120

121+
/**
122+
* Options used to fetch pinned messages.
123+
*
124+
* @typedef {Object} FetchPinnedMessagesOptions
125+
* @property {DateResolvable} [before] Consider only pinned messages before this time
126+
* @property {number} [limit] The maximum number of pinned messages to return
127+
* @property {boolean} [cache] Whether to cache the pinned messages
128+
*/
129+
130+
/**
131+
* Data returned from fetching pinned messages.
132+
*
133+
* @typedef {Object} FetchPinnedMessagesResponse
134+
* @property {MessagePin[]} items The pinned messages
135+
* @property {boolean} hasMore Whether there are additional pinned messages that require a subsequent call
136+
*/
137+
138+
/**
139+
* Pinned message data returned from fetching pinned messages.
140+
*
141+
* @typedef {Object} MessagePin
142+
* @property {Date} pinnedAt The time the message was pinned at
143+
* @property {number} pinnedTimestamp The timestamp the message was pinned at
144+
* @property {Message} message The pinned message
145+
*/
146+
119147
/**
120148
* Fetches the pinned messages of this channel and returns a collection of them.
121149
* <info>The returned Collection does not contain any reaction data of the messages.
122150
* Those need to be fetched separately.</info>
123-
* @param {boolean} [cache=true] Whether to cache the message(s)
124-
* @returns {Promise<Collection<Snowflake, Message>>}
151+
*
152+
* @param {FetchPinnedMessagesOptions} [options={}] Options for fetching pinned messages
153+
* @returns {Promise<FetchPinnedMessagesResponse>}
125154
* @example
126155
* // Get pinned messages
127-
* channel.messages.fetchPinned()
128-
* .then(messages => console.log(`Received ${messages.size} messages`))
156+
* channel.messages.fetchPins()
157+
* .then(messages => console.log(`Received ${messages.items.length} messages`))
129158
* .catch(console.error);
130159
*/
160+
async fetchPins(options = {}) {
161+
const data = await this.client.rest.get(Routes.channelMessagesPins(this.channel.id), {
162+
query: makeURLSearchParams({
163+
...options,
164+
before: options.before && new Date(options.before).toISOString(),
165+
}),
166+
});
167+
168+
return {
169+
items: data.items.map(item => ({
170+
pinnedTimestamp: Date.parse(item.pinned_at),
171+
get pinnedAt() {
172+
return new Date(this.pinnedTimestamp);
173+
},
174+
message: this._add(item.message, options.cache),
175+
})),
176+
hasMore: data.has_more,
177+
};
178+
}
179+
180+
/**
181+
* Fetches the pinned messages of this channel and returns a collection of them.
182+
* <info>The returned Collection does not contain any reaction data of the messages.
183+
* Those need to be fetched separately.</info>
184+
* @param {boolean} [cache=true] Whether to cache the message(s)
185+
* @deprecated Use {@link MessageManager#fetchPins} instead.
186+
* @returns {Promise<Collection<Snowflake, Message>>}
187+
*/
131188
async fetchPinned(cache = true) {
189+
if (!deprecationEmittedForFetchPinned) {
190+
process.emitWarning(
191+
'The MessageManager#fetchPinned() method is deprecated. Use MessageManager#fetchPins() instead.',
192+
'DeprecationWarning',
193+
);
194+
195+
deprecationEmittedForFetchPinned = true;
196+
}
197+
132198
const data = await this.client.rest.get(Routes.channelPins(this.channel.id));
133199
const messages = new Collection();
134200
for (const message of data) messages.set(message.id, this._add(message, cache));
@@ -219,7 +285,7 @@ class MessageManager extends CachedManager {
219285
message = this.resolveId(message);
220286
if (!message) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
221287

222-
await this.client.rest.put(Routes.channelPin(this.channel.id, message), { reason });
288+
await this.client.rest.put(Routes.channelMessagesPin(this.channel.id, messageId), { reason });
223289
}
224290

225291
/**
@@ -232,7 +298,7 @@ class MessageManager extends CachedManager {
232298
message = this.resolveId(message);
233299
if (!message) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
234300

235-
await this.client.rest.delete(Routes.channelPin(this.channel.id, message), { reason });
301+
await this.client.rest.delete(Routes.channelMessagesPin(this.channel.id, messageId), { reason });
236302
}
237303

238304
/**

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5017,7 +5017,9 @@ export abstract class MessageManager<InGuild extends boolean = boolean> extends
50175017
): Promise<Message<InGuild>>;
50185018
public fetch(options: MessageResolvable | FetchMessageOptions): Promise<Message<InGuild>>;
50195019
public fetch(options?: FetchMessagesOptions): Promise<Collection<Snowflake, Message<InGuild>>>;
5020+
/** @deprecated Use {@link MessageManager.fetchPins} instead. */
50205021
public fetchPinned(cache?: boolean): Promise<Collection<Snowflake, Message<InGuild>>>;
5022+
public fetchPins(options?: FetchPinnedMessagesOptions): Promise<FetchPinnedMessagesResponse<InGuild>>;
50215023
public react(message: MessageResolvable, emoji: EmojiIdentifierResolvable): Promise<void>;
50225024
public pin(message: MessageResolvable, reason?: string): Promise<void>;
50235025
public unpin(message: MessageResolvable, reason?: string): Promise<void>;
@@ -6341,6 +6343,23 @@ export interface FetchMessagesOptions {
63416343
cache?: boolean;
63426344
}
63436345

6346+
export interface FetchPinnedMessagesOptions {
6347+
before?: DateResolvable;
6348+
cache?: boolean;
6349+
limit?: number;
6350+
}
6351+
6352+
export interface FetchPinnedMessagesResponse<InGuild extends boolean = boolean> {
6353+
hasMore: boolean;
6354+
items: readonly MessagePin<InGuild>[];
6355+
}
6356+
6357+
export interface MessagePin<InGuild extends boolean = boolean> {
6358+
message: Message<InGuild>;
6359+
get pinnedAt(): Date;
6360+
pinnedTimestamp: number;
6361+
}
6362+
63446363
export interface FetchReactionUsersOptions {
63456364
type?: ReactionType;
63466365
limit?: number;

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,6 +1690,7 @@ declare const guildChannelManager: GuildChannelManager;
16901690
expectType<Promise<Message<true>>>(messages.edit('1234567890', 'text'));
16911691
expectType<Promise<Message<true>>>(messages.fetch('1234567890'));
16921692
expectType<Promise<Collection<Snowflake, Message<true>>>>(messages.fetchPinned());
1693+
expectType<Promise<FetchPinnedMessagesResponse<true>>>(messages.fetchPins());
16931694
expectType<Guild>(message.guild);
16941695
expectType<Snowflake>(message.guildId);
16951696
expectType<GuildTextBasedChannel>(message.channel.messages.channel);
@@ -1703,6 +1704,7 @@ declare const guildChannelManager: GuildChannelManager;
17031704
expectType<Promise<Message>>(messages.edit('1234567890', 'text'));
17041705
expectType<Promise<Message>>(messages.fetch('1234567890'));
17051706
expectType<Promise<Collection<Snowflake, Message>>>(messages.fetchPinned());
1707+
expectType<Promise<FetchPinnedMessagesResponse>>(messages.fetchPins());
17061708
expectType<Guild | null>(message.guild);
17071709
expectType<Snowflake | null>(message.guildId);
17081710
expectType<DMChannel | PartialGroupDMChannel | GuildTextBasedChannel>(message.channel.messages.channel);

0 commit comments

Comments
 (0)