Downgrade to v13
[vi] cảm giác đau khổ
This commit is contained in:
@@ -1,30 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
const { createComponent, Embed } = require('@discordjs/builders');
|
||||
const process = require('node:process');
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { DiscordSnowflake } = require('@sapphire/snowflake');
|
||||
const {
|
||||
InteractionType,
|
||||
ChannelType,
|
||||
MessageType,
|
||||
MessageFlags,
|
||||
PermissionFlagsBits,
|
||||
} = require('discord-api-types/v9');
|
||||
const Base = require('./Base');
|
||||
const BaseMessageComponent = require('./BaseMessageComponent');
|
||||
const ClientApplication = require('./ClientApplication');
|
||||
const InteractionCollector = require('./InteractionCollector');
|
||||
const MessageAttachment = require('./MessageAttachment');
|
||||
const Embed = require('./MessageEmbed');
|
||||
const Mentions = require('./MessageMentions');
|
||||
const MessagePayload = require('./MessagePayload');
|
||||
const ReactionCollector = require('./ReactionCollector');
|
||||
const { Sticker } = require('./Sticker');
|
||||
const { Error } = require('../errors');
|
||||
const ReactionManager = require('../managers/ReactionManager');
|
||||
const { NonSystemMessageTypes } = require('../util/Constants');
|
||||
const MessageFlagsBitField = require('../util/MessageFlagsBitField');
|
||||
const PermissionsBitField = require('../util/PermissionsBitField');
|
||||
const { InteractionTypes, MessageTypes, SystemMessageTypes } = require('../util/Constants');
|
||||
const MessageFlags = require('../util/MessageFlags');
|
||||
const Permissions = require('../util/Permissions');
|
||||
const SnowflakeUtil = require('../util/SnowflakeUtil');
|
||||
const Util = require('../util/Util');
|
||||
|
||||
/**
|
||||
* @type {WeakSet<Message>}
|
||||
* @private
|
||||
* @internal
|
||||
*/
|
||||
const deletedMessages = new WeakSet();
|
||||
let deprecationEmittedForDeleted = false;
|
||||
|
||||
/**
|
||||
* Represents a message on Discord.
|
||||
* @extends {Base}
|
||||
@@ -59,20 +62,20 @@ class Message extends Base {
|
||||
* The timestamp the message was sent at
|
||||
* @type {number}
|
||||
*/
|
||||
this.createdTimestamp = DiscordSnowflake.timestampFrom(this.id);
|
||||
this.createdTimestamp = SnowflakeUtil.timestampFrom(this.id);
|
||||
|
||||
if ('type' in data) {
|
||||
/**
|
||||
* The type of the message
|
||||
* @type {?MessageType}
|
||||
*/
|
||||
this.type = data.type;
|
||||
this.type = MessageTypes[data.type];
|
||||
|
||||
/**
|
||||
* Whether or not this message was sent by Discord, not actually a user (e.g. pin notifications)
|
||||
* @type {?boolean}
|
||||
*/
|
||||
this.system = !NonSystemMessageTypes.includes(this.type);
|
||||
this.system = SystemMessageTypes.includes(this.type);
|
||||
} else {
|
||||
this.system ??= null;
|
||||
this.type ??= null;
|
||||
@@ -133,9 +136,9 @@ class Message extends Base {
|
||||
if ('embeds' in data) {
|
||||
/**
|
||||
* A list of embeds in the message - e.g. YouTube Player
|
||||
* @type {Embed[]}
|
||||
* @type {MessageEmbed[]}
|
||||
*/
|
||||
this.embeds = data.embeds.map(e => new Embed(e));
|
||||
this.embeds = data.embeds.map(e => new Embed(e, true));
|
||||
} else {
|
||||
this.embeds = this.embeds?.slice() ?? [];
|
||||
}
|
||||
@@ -143,9 +146,9 @@ class Message extends Base {
|
||||
if ('components' in data) {
|
||||
/**
|
||||
* A list of MessageActionRows in the message
|
||||
* @type {ActionRow[]}
|
||||
* @type {MessageActionRow[]}
|
||||
*/
|
||||
this.components = data.components.map(c => createComponent(c));
|
||||
this.components = data.components.map(c => BaseMessageComponent.create(c, this.client));
|
||||
} else {
|
||||
this.components = this.components?.slice() ?? [];
|
||||
}
|
||||
@@ -183,7 +186,7 @@ class Message extends Base {
|
||||
* The timestamp the message was last edited at (if applicable)
|
||||
* @type {?number}
|
||||
*/
|
||||
this.editedTimestamp = Date.parse(data.edited_timestamp);
|
||||
this.editedTimestamp = new Date(data.edited_timestamp).getTime();
|
||||
} else {
|
||||
this.editedTimestamp ??= null;
|
||||
}
|
||||
@@ -283,21 +286,21 @@ class Message extends Base {
|
||||
if ('flags' in data) {
|
||||
/**
|
||||
* Flags that are applied to the message
|
||||
* @type {Readonly<MessageFlagsBitField>}
|
||||
* @type {Readonly<MessageFlags>}
|
||||
*/
|
||||
this.flags = new MessageFlagsBitField(data.flags).freeze();
|
||||
this.flags = new MessageFlags(data.flags).freeze();
|
||||
} else {
|
||||
this.flags = new MessageFlagsBitField(this.flags).freeze();
|
||||
this.flags = new MessageFlags(this.flags).freeze();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reference data sent in a message that contains ids identifying the referenced message.
|
||||
* This can be present in the following types of message:
|
||||
* * Crossposted messages (`MessageFlags.Crossposted`)
|
||||
* * {@link MessageType.ChannelFollowAdd}
|
||||
* * {@link MessageType.ChannelPinnedMessage}
|
||||
* * {@link MessageType.Reply}
|
||||
* * {@link MessageType.ThreadStarterMessage}
|
||||
* * Crossposted messages (IS_CROSSPOST {@link MessageFlags.FLAGS message flag})
|
||||
* * CHANNEL_FOLLOW_ADD
|
||||
* * CHANNEL_PINNED_MESSAGE
|
||||
* * REPLY
|
||||
* * THREAD_STARTER_MESSAGE
|
||||
* @see {@link https://discord.com/developers/docs/resources/channel#message-types}
|
||||
* @typedef {Object} MessageReference
|
||||
* @property {Snowflake} channelId The channel's id the message was referenced
|
||||
@@ -339,7 +342,7 @@ class Message extends Base {
|
||||
*/
|
||||
this.interaction = {
|
||||
id: data.interaction.id,
|
||||
type: data.interaction.type,
|
||||
type: InteractionTypes[data.interaction.type],
|
||||
commandName: data.interaction.name,
|
||||
user: this.client.users._add(data.interaction.user),
|
||||
};
|
||||
@@ -348,6 +351,36 @@ class Message extends Base {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the structure has been deleted
|
||||
* @type {boolean}
|
||||
* @deprecated This will be removed in the next major version, see https://github.com/discordjs/discord.js/issues/7091
|
||||
*/
|
||||
get deleted() {
|
||||
if (!deprecationEmittedForDeleted) {
|
||||
deprecationEmittedForDeleted = true;
|
||||
process.emitWarning(
|
||||
'Message#deleted is deprecated, see https://github.com/discordjs/discord.js/issues/7091.',
|
||||
'DeprecationWarning',
|
||||
);
|
||||
}
|
||||
|
||||
return deletedMessages.has(this);
|
||||
}
|
||||
|
||||
set deleted(value) {
|
||||
if (!deprecationEmittedForDeleted) {
|
||||
deprecationEmittedForDeleted = true;
|
||||
process.emitWarning(
|
||||
'Message#deleted is deprecated, see https://github.com/discordjs/discord.js/issues/7091.',
|
||||
'DeprecationWarning',
|
||||
);
|
||||
}
|
||||
|
||||
if (value) deletedMessages.add(this);
|
||||
else deletedMessages.delete(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* The channel that the message was sent in
|
||||
* @type {TextChannel|DMChannel|NewsChannel|ThreadChannel}
|
||||
@@ -391,7 +424,7 @@ class Message extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get editedAt() {
|
||||
return this.editedTimestamp && new Date(this.editedTimestamp);
|
||||
return this.editedTimestamp ? new Date(this.editedTimestamp) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -409,7 +442,7 @@ class Message extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get hasThread() {
|
||||
return this.flags.has(MessageFlags.HasThread);
|
||||
return this.flags.has(MessageFlags.FLAGS.HAS_THREAD);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -488,7 +521,7 @@ class Message extends Base {
|
||||
|
||||
/**
|
||||
* @typedef {CollectorOptions} MessageComponentCollectorOptions
|
||||
* @property {ComponentType} [componentType] The type of component to listen for
|
||||
* @property {MessageComponentType} [componentType] The type of component to listen for
|
||||
* @property {number} [max] The maximum total amount of interactions to collect
|
||||
* @property {number} [maxComponents] The maximum number of components to collect
|
||||
* @property {number} [maxUsers] The maximum number of users to interact
|
||||
@@ -508,7 +541,7 @@ class Message extends Base {
|
||||
createMessageComponentCollector(options = {}) {
|
||||
return new InteractionCollector(this.client, {
|
||||
...options,
|
||||
interactionType: InteractionType.MessageComponent,
|
||||
interactionType: InteractionTypes.MESSAGE_COMPONENT,
|
||||
message: this,
|
||||
});
|
||||
}
|
||||
@@ -518,7 +551,7 @@ class Message extends Base {
|
||||
* @typedef {Object} AwaitMessageComponentOptions
|
||||
* @property {CollectorFilter} [filter] The filter applied to this collector
|
||||
* @property {number} [time] Time to wait for an interaction before rejecting
|
||||
* @property {ComponentType} [componentType] The type of component interaction to collect
|
||||
* @property {MessageComponentType} [componentType] The type of component interaction to collect
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -551,7 +584,9 @@ class Message extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get editable() {
|
||||
const precheck = Boolean(this.author.id === this.client.user.id && (!this.guild || this.channel?.viewable));
|
||||
const precheck = Boolean(
|
||||
this.author.id === this.client.user.id && !deletedMessages.has(this) && (!this.guild || this.channel?.viewable),
|
||||
);
|
||||
// Regardless of permissions thread messages cannot be edited if
|
||||
// the thread is locked.
|
||||
if (this.channel?.isThread()) {
|
||||
@@ -566,6 +601,9 @@ class Message extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get deletable() {
|
||||
if (deletedMessages.has(this)) {
|
||||
return false;
|
||||
}
|
||||
if (!this.guild) {
|
||||
return this.author.id === this.client.user.id;
|
||||
}
|
||||
@@ -577,11 +615,11 @@ class Message extends Base {
|
||||
const permissions = this.channel?.permissionsFor(this.client.user);
|
||||
if (!permissions) return false;
|
||||
// This flag allows deleting even if timed out
|
||||
if (permissions.has(PermissionFlagsBits.Administrator, false)) return true;
|
||||
if (permissions.has(Permissions.FLAGS.ADMINISTRATOR, false)) return true;
|
||||
|
||||
return Boolean(
|
||||
this.author.id === this.client.user.id ||
|
||||
(permissions.has(PermissionFlagsBits.ManageMessages, false) &&
|
||||
(permissions.has(Permissions.FLAGS.MANAGE_MESSAGES, false) &&
|
||||
this.guild.me.communicationDisabledUntilTimestamp < Date.now()),
|
||||
);
|
||||
}
|
||||
@@ -595,9 +633,10 @@ class Message extends Base {
|
||||
const { channel } = this;
|
||||
return Boolean(
|
||||
!this.system &&
|
||||
!deletedMessages.has(this) &&
|
||||
(!this.guild ||
|
||||
(channel?.viewable &&
|
||||
channel?.permissionsFor(this.client.user)?.has(PermissionFlagsBits.ManageMessages, false))),
|
||||
channel?.permissionsFor(this.client.user)?.has(Permissions.FLAGS.MANAGE_MESSAGES, false))),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -621,15 +660,16 @@ class Message extends Base {
|
||||
*/
|
||||
get crosspostable() {
|
||||
const bitfield =
|
||||
PermissionFlagsBits.SendMessages |
|
||||
(this.author.id === this.client.user.id ? PermissionsBitField.defaultBit : PermissionFlagsBits.ManageMessages);
|
||||
Permissions.FLAGS.SEND_MESSAGES |
|
||||
(this.author.id === this.client.user.id ? Permissions.defaultBit : Permissions.FLAGS.MANAGE_MESSAGES);
|
||||
const { channel } = this;
|
||||
return Boolean(
|
||||
channel?.type === ChannelType.GuildNews &&
|
||||
!this.flags.has(MessageFlags.Crossposted) &&
|
||||
this.type === MessageType.Default &&
|
||||
channel?.type === 'GUILD_NEWS' &&
|
||||
!this.flags.has(MessageFlags.FLAGS.CROSSPOSTED) &&
|
||||
this.type === 'DEFAULT' &&
|
||||
channel.viewable &&
|
||||
channel.permissionsFor(this.client.user)?.has(bitfield, false),
|
||||
channel.permissionsFor(this.client.user)?.has(bitfield, false) &&
|
||||
!deletedMessages.has(this),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -637,14 +677,13 @@ class Message extends Base {
|
||||
* Options that can be passed into {@link Message#edit}.
|
||||
* @typedef {Object} MessageEditOptions
|
||||
* @property {?string} [content] Content to be edited
|
||||
* @property {Embed[]|APIEmbed[]} [embeds] Embeds to be added/edited
|
||||
* @property {MessageEmbed[]|APIEmbed[]} [embeds] Embeds to be added/edited
|
||||
* @property {MessageMentionOptions} [allowedMentions] Which mentions should be parsed from the message content
|
||||
* @property {MessageFlags} [flags] Which flags to set for the message.
|
||||
* Only `MessageFlags.SuppressEmbeds` can be edited.
|
||||
* @property {MessageFlags} [flags] Which flags to set for the message. Only `SUPPRESS_EMBEDS` can be edited.
|
||||
* @property {MessageAttachment[]} [attachments] An array of attachments to keep,
|
||||
* all attachments will be kept if omitted
|
||||
* @property {FileOptions[]|BufferResolvable[]|MessageAttachment[]} [files] Files to add to the message
|
||||
* @property {ActionRow[]|ActionRowOptions[]} [components]
|
||||
* @property {MessageActionRow[]|MessageActionRowOptions[]} [components]
|
||||
* Action rows containing interactive components for the message (buttons, select menus)
|
||||
*/
|
||||
|
||||
@@ -668,7 +707,7 @@ class Message extends Base {
|
||||
* @returns {Promise<Message>}
|
||||
* @example
|
||||
* // Crosspost a message
|
||||
* if (message.channel.type === ChannelType.GuildNews) {
|
||||
* if (message.channel.type === 'GUILD_NEWS') {
|
||||
* message.crosspost()
|
||||
* .then(() => console.log('Crossposted message'))
|
||||
* .catch(console.error);
|
||||
@@ -681,7 +720,6 @@ class Message extends Base {
|
||||
|
||||
/**
|
||||
* Pins this message to the channel's pinned messages.
|
||||
* @param {string} [reason] Reason for pinning
|
||||
* @returns {Promise<Message>}
|
||||
* @example
|
||||
* // Pin a message
|
||||
@@ -689,15 +727,14 @@ class Message extends Base {
|
||||
* .then(console.log)
|
||||
* .catch(console.error)
|
||||
*/
|
||||
async pin(reason) {
|
||||
async pin() {
|
||||
if (!this.channel) throw new Error('CHANNEL_NOT_CACHED');
|
||||
await this.channel.messages.pin(this.id, reason);
|
||||
await this.channel.messages.pin(this.id);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpins this message from the channel's pinned messages.
|
||||
* @param {string} [reason] Reason for unpinning
|
||||
* @returns {Promise<Message>}
|
||||
* @example
|
||||
* // Unpin a message
|
||||
@@ -705,9 +742,9 @@ class Message extends Base {
|
||||
* .then(console.log)
|
||||
* .catch(console.error)
|
||||
*/
|
||||
async unpin(reason) {
|
||||
async unpin() {
|
||||
if (!this.channel) throw new Error('CHANNEL_NOT_CACHED');
|
||||
await this.channel.messages.unpin(this.id, reason);
|
||||
await this.channel.messages.unpin(this.id);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -759,8 +796,8 @@ class Message extends Base {
|
||||
/**
|
||||
* Options provided when sending a message as an inline reply.
|
||||
* @typedef {BaseMessageOptions} ReplyMessageOptions
|
||||
* @property {boolean} [failIfNotExists=this.client.options.failIfNotExists] Whether to error if the referenced
|
||||
* message does not exist (creates a standard message in this case when false)
|
||||
* @property {boolean} [failIfNotExists=true] Whether to error if the referenced message
|
||||
* does not exist (creates a standard message in this case when false)
|
||||
* @property {StickerResolvable[]} [stickers=[]] Stickers to send in the message
|
||||
*/
|
||||
|
||||
@@ -820,7 +857,7 @@ class Message extends Base {
|
||||
*/
|
||||
startThread(options = {}) {
|
||||
if (!this.channel) return Promise.reject(new Error('CHANNEL_NOT_CACHED'));
|
||||
if (![ChannelType.GuildText, ChannelType.GuildNews].includes(this.channel.type)) {
|
||||
if (!['GUILD_TEXT', 'GUILD_NEWS'].includes(this.channel.type)) {
|
||||
return Promise.reject(new Error('MESSAGE_THREAD_PARENT'));
|
||||
}
|
||||
if (this.hasThread) return Promise.reject(new Error('MESSAGE_EXISTING_THREAD'));
|
||||
@@ -853,12 +890,12 @@ class Message extends Base {
|
||||
* @returns {Promise<Message>}
|
||||
*/
|
||||
suppressEmbeds(suppress = true) {
|
||||
const flags = new MessageFlagsBitField(this.flags.bitfield);
|
||||
const flags = new MessageFlags(this.flags.bitfield);
|
||||
|
||||
if (suppress) {
|
||||
flags.add(MessageFlags.SuppressEmbeds);
|
||||
flags.add(MessageFlags.FLAGS.SUPPRESS_EMBEDS);
|
||||
} else {
|
||||
flags.remove(MessageFlags.SuppressEmbeds);
|
||||
flags.remove(MessageFlags.FLAGS.SUPPRESS_EMBEDS);
|
||||
}
|
||||
|
||||
return this.edit({ flags });
|
||||
@@ -906,8 +943,8 @@ class Message extends Base {
|
||||
if (equal && rawData) {
|
||||
equal =
|
||||
this.mentions.everyone === message.mentions.everyone &&
|
||||
this.createdTimestamp === Date.parse(rawData.timestamp) &&
|
||||
this.editedTimestamp === Date.parse(rawData.edited_timestamp);
|
||||
this.createdTimestamp === new Date(rawData.timestamp).getTime() &&
|
||||
this.editedTimestamp === new Date(rawData.edited_timestamp).getTime();
|
||||
}
|
||||
|
||||
return equal;
|
||||
@@ -946,3 +983,4 @@ class Message extends Base {
|
||||
}
|
||||
|
||||
exports.Message = Message;
|
||||
exports.deletedMessages = deletedMessages;
|
||||
|
||||
Reference in New Issue
Block a user