mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-14 02:23:31 +01:00
feat(MessageManager): New pinned messages routes (#10993)
feat(MessageManager)!: New pinned messages routes (#10989) BREAKING CHANGE: `fetchPinned()` has been renamed to `fetchPins()`, which is a paginated endpoint to fetch pinned messages.
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const process = require('node:process');
|
||||||
const { Collection } = require('@discordjs/collection');
|
const { Collection } = require('@discordjs/collection');
|
||||||
const { makeURLSearchParams } = require('@discordjs/rest');
|
const { makeURLSearchParams } = require('@discordjs/rest');
|
||||||
const { Routes } = require('discord-api-types/v10');
|
const { Routes } = require('discord-api-types/v10');
|
||||||
@@ -10,6 +11,8 @@ const MessagePayload = require('../structures/MessagePayload');
|
|||||||
const { MakeCacheOverrideSymbol } = require('../util/Symbols');
|
const { MakeCacheOverrideSymbol } = require('../util/Symbols');
|
||||||
const { resolvePartialEmoji } = require('../util/Util');
|
const { resolvePartialEmoji } = require('../util/Util');
|
||||||
|
|
||||||
|
let deprecationEmittedForFetchPinned = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages API methods for Messages and holds their cache.
|
* Manages API methods for Messages and holds their cache.
|
||||||
* @extends {CachedManager}
|
* @extends {CachedManager}
|
||||||
@@ -116,19 +119,83 @@ class MessageManager extends CachedManager {
|
|||||||
return data.reduce((_data, message) => _data.set(message.id, this._add(message, options.cache)), new Collection());
|
return data.reduce((_data, message) => _data.set(message.id, this._add(message, options.cache)), new Collection());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options used to fetch pinned messages.
|
||||||
|
*
|
||||||
|
* @typedef {Object} FetchPinnedMessagesOptions
|
||||||
|
* @property {DateResolvable} [before] Consider only pinned messages before this time
|
||||||
|
* @property {number} [limit] The maximum number of pinned messages to return
|
||||||
|
* @property {boolean} [cache] Whether to cache the pinned messages
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data returned from fetching pinned messages.
|
||||||
|
*
|
||||||
|
* @typedef {Object} FetchPinnedMessagesResponse
|
||||||
|
* @property {MessagePin[]} items The pinned messages
|
||||||
|
* @property {boolean} hasMore Whether there are additional pinned messages that require a subsequent call
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pinned message data returned from fetching pinned messages.
|
||||||
|
*
|
||||||
|
* @typedef {Object} MessagePin
|
||||||
|
* @property {Date} pinnedAt The time the message was pinned at
|
||||||
|
* @property {number} pinnedTimestamp The timestamp the message was pinned at
|
||||||
|
* @property {Message} message The pinned message
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches the pinned messages of this channel and returns a collection of them.
|
||||||
|
* <info>The returned Collection does not contain any reaction data of the messages.
|
||||||
|
* Those need to be fetched separately.</info>
|
||||||
|
*
|
||||||
|
* @param {FetchPinnedMessagesOptions} [options={}] Options for fetching pinned messages
|
||||||
|
* @returns {Promise<FetchPinnedMessagesResponse>}
|
||||||
|
* @example
|
||||||
|
* // Get pinned messages
|
||||||
|
* channel.messages.fetchPins()
|
||||||
|
* .then(messages => console.log(`Received ${messages.items.length} messages`))
|
||||||
|
* .catch(console.error);
|
||||||
|
*/
|
||||||
|
async fetchPins(options = {}) {
|
||||||
|
const data = await this.client.rest.get(Routes.channelMessagesPins(this.channel.id), {
|
||||||
|
query: makeURLSearchParams({
|
||||||
|
...options,
|
||||||
|
before: options.before && new Date(options.before).toISOString(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
items: data.items.map(item => ({
|
||||||
|
pinnedTimestamp: Date.parse(item.pinned_at),
|
||||||
|
get pinnedAt() {
|
||||||
|
return new Date(this.pinnedTimestamp);
|
||||||
|
},
|
||||||
|
message: this._add(item.message, options.cache),
|
||||||
|
})),
|
||||||
|
hasMore: data.has_more,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches the pinned messages of this channel and returns a collection of them.
|
* Fetches the pinned messages of this channel and returns a collection of them.
|
||||||
* <info>The returned Collection does not contain any reaction data of the messages.
|
* <info>The returned Collection does not contain any reaction data of the messages.
|
||||||
* Those need to be fetched separately.</info>
|
* Those need to be fetched separately.</info>
|
||||||
* @param {boolean} [cache=true] Whether to cache the message(s)
|
* @param {boolean} [cache=true] Whether to cache the message(s)
|
||||||
|
* @deprecated Use {@link MessageManager#fetchPins} instead.
|
||||||
* @returns {Promise<Collection<Snowflake, Message>>}
|
* @returns {Promise<Collection<Snowflake, Message>>}
|
||||||
* @example
|
|
||||||
* // Get pinned messages
|
|
||||||
* channel.messages.fetchPinned()
|
|
||||||
* .then(messages => console.log(`Received ${messages.size} messages`))
|
|
||||||
* .catch(console.error);
|
|
||||||
*/
|
*/
|
||||||
async fetchPinned(cache = true) {
|
async fetchPinned(cache = true) {
|
||||||
|
if (!deprecationEmittedForFetchPinned) {
|
||||||
|
process.emitWarning(
|
||||||
|
'The MessageManager#fetchPinned() method is deprecated. Use MessageManager#fetchPins() instead.',
|
||||||
|
'DeprecationWarning',
|
||||||
|
);
|
||||||
|
|
||||||
|
deprecationEmittedForFetchPinned = true;
|
||||||
|
}
|
||||||
|
|
||||||
const data = await this.client.rest.get(Routes.channelPins(this.channel.id));
|
const data = await this.client.rest.get(Routes.channelPins(this.channel.id));
|
||||||
const messages = new Collection();
|
const messages = new Collection();
|
||||||
for (const message of data) messages.set(message.id, this._add(message, cache));
|
for (const message of data) messages.set(message.id, this._add(message, cache));
|
||||||
@@ -219,7 +286,7 @@ class MessageManager extends CachedManager {
|
|||||||
message = this.resolveId(message);
|
message = this.resolveId(message);
|
||||||
if (!message) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
|
if (!message) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
|
||||||
|
|
||||||
await this.client.rest.put(Routes.channelPin(this.channel.id, message), { reason });
|
await this.client.rest.put(Routes.channelMessagesPin(this.channel.id, message), { reason });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -232,7 +299,7 @@ class MessageManager extends CachedManager {
|
|||||||
message = this.resolveId(message);
|
message = this.resolveId(message);
|
||||||
if (!message) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
|
if (!message) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
|
||||||
|
|
||||||
await this.client.rest.delete(Routes.channelPin(this.channel.id, message), { reason });
|
await this.client.rest.delete(Routes.channelMessagesPin(this.channel.id, message), { reason });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
19
packages/discord.js/typings/index.d.ts
vendored
19
packages/discord.js/typings/index.d.ts
vendored
@@ -5025,7 +5025,9 @@ export abstract class MessageManager<InGuild extends boolean = boolean> extends
|
|||||||
): Promise<Message<InGuild>>;
|
): Promise<Message<InGuild>>;
|
||||||
public fetch(options: MessageResolvable | FetchMessageOptions): Promise<Message<InGuild>>;
|
public fetch(options: MessageResolvable | FetchMessageOptions): Promise<Message<InGuild>>;
|
||||||
public fetch(options?: FetchMessagesOptions): Promise<Collection<Snowflake, Message<InGuild>>>;
|
public fetch(options?: FetchMessagesOptions): Promise<Collection<Snowflake, Message<InGuild>>>;
|
||||||
|
/** @deprecated Use {@link MessageManager.fetchPins} instead. */
|
||||||
public fetchPinned(cache?: boolean): Promise<Collection<Snowflake, Message<InGuild>>>;
|
public fetchPinned(cache?: boolean): Promise<Collection<Snowflake, Message<InGuild>>>;
|
||||||
|
public fetchPins(options?: FetchPinnedMessagesOptions): Promise<FetchPinnedMessagesResponse<InGuild>>;
|
||||||
public react(message: MessageResolvable, emoji: EmojiIdentifierResolvable): Promise<void>;
|
public react(message: MessageResolvable, emoji: EmojiIdentifierResolvable): Promise<void>;
|
||||||
public pin(message: MessageResolvable, reason?: string): Promise<void>;
|
public pin(message: MessageResolvable, reason?: string): Promise<void>;
|
||||||
public unpin(message: MessageResolvable, reason?: string): Promise<void>;
|
public unpin(message: MessageResolvable, reason?: string): Promise<void>;
|
||||||
@@ -6349,6 +6351,23 @@ export interface FetchMessagesOptions {
|
|||||||
cache?: boolean;
|
cache?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface FetchPinnedMessagesOptions {
|
||||||
|
before?: DateResolvable;
|
||||||
|
cache?: boolean;
|
||||||
|
limit?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FetchPinnedMessagesResponse<InGuild extends boolean = boolean> {
|
||||||
|
hasMore: boolean;
|
||||||
|
items: readonly MessagePin<InGuild>[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MessagePin<InGuild extends boolean = boolean> {
|
||||||
|
message: Message<InGuild>;
|
||||||
|
get pinnedAt(): Date;
|
||||||
|
pinnedTimestamp: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface FetchReactionUsersOptions {
|
export interface FetchReactionUsersOptions {
|
||||||
type?: ReactionType;
|
type?: ReactionType;
|
||||||
limit?: number;
|
limit?: number;
|
||||||
|
|||||||
@@ -231,6 +231,7 @@ import {
|
|||||||
FileComponentData,
|
FileComponentData,
|
||||||
ContainerComponentData,
|
ContainerComponentData,
|
||||||
InteractionResponse,
|
InteractionResponse,
|
||||||
|
FetchPinnedMessagesResponse,
|
||||||
} from '.';
|
} from '.';
|
||||||
import {
|
import {
|
||||||
expectAssignable,
|
expectAssignable,
|
||||||
@@ -1690,6 +1691,7 @@ declare const guildChannelManager: GuildChannelManager;
|
|||||||
expectType<Promise<Message<true>>>(messages.edit('1234567890', 'text'));
|
expectType<Promise<Message<true>>>(messages.edit('1234567890', 'text'));
|
||||||
expectType<Promise<Message<true>>>(messages.fetch('1234567890'));
|
expectType<Promise<Message<true>>>(messages.fetch('1234567890'));
|
||||||
expectType<Promise<Collection<Snowflake, Message<true>>>>(messages.fetchPinned());
|
expectType<Promise<Collection<Snowflake, Message<true>>>>(messages.fetchPinned());
|
||||||
|
expectType<Promise<FetchPinnedMessagesResponse<true>>>(messages.fetchPins());
|
||||||
expectType<Guild>(message.guild);
|
expectType<Guild>(message.guild);
|
||||||
expectType<Snowflake>(message.guildId);
|
expectType<Snowflake>(message.guildId);
|
||||||
expectType<GuildTextBasedChannel>(message.channel.messages.channel);
|
expectType<GuildTextBasedChannel>(message.channel.messages.channel);
|
||||||
@@ -1703,6 +1705,7 @@ declare const guildChannelManager: GuildChannelManager;
|
|||||||
expectType<Promise<Message>>(messages.edit('1234567890', 'text'));
|
expectType<Promise<Message>>(messages.edit('1234567890', 'text'));
|
||||||
expectType<Promise<Message>>(messages.fetch('1234567890'));
|
expectType<Promise<Message>>(messages.fetch('1234567890'));
|
||||||
expectType<Promise<Collection<Snowflake, Message>>>(messages.fetchPinned());
|
expectType<Promise<Collection<Snowflake, Message>>>(messages.fetchPinned());
|
||||||
|
expectType<Promise<FetchPinnedMessagesResponse>>(messages.fetchPins());
|
||||||
expectType<Guild | null>(message.guild);
|
expectType<Guild | null>(message.guild);
|
||||||
expectType<Snowflake | null>(message.guildId);
|
expectType<Snowflake | null>(message.guildId);
|
||||||
expectType<DMChannel | PartialGroupDMChannel | GuildTextBasedChannel>(message.channel.messages.channel);
|
expectType<DMChannel | PartialGroupDMChannel | GuildTextBasedChannel>(message.channel.messages.channel);
|
||||||
|
|||||||
Reference in New Issue
Block a user