From ca662b4de82d71bf8931e277544465cb3b66062c Mon Sep 17 00:00:00 2001 From: Synbulat Biishev Date: Fri, 25 Nov 2022 20:36:34 +0300 Subject: [PATCH] feat: add `Message#bulkDeletable` (v13) (#8761) --- src/structures/Message.js | 21 ++++++++++++++++++- src/structures/interfaces/TextBasedChannel.js | 4 ++-- src/util/Constants.js | 7 +++++++ typings/index.d.ts | 2 ++ 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/structures/Message.js b/src/structures/Message.js index d0146c3b5..fd18ec6b1 100644 --- a/src/structures/Message.js +++ b/src/structures/Message.js @@ -14,7 +14,7 @@ const ReactionCollector = require('./ReactionCollector'); const { Sticker } = require('./Sticker'); const { Error } = require('../errors'); const ReactionManager = require('../managers/ReactionManager'); -const { InteractionTypes, MessageTypes, SystemMessageTypes } = require('../util/Constants'); +const { InteractionTypes, MessageTypes, SystemMessageTypes, MaxBulkDeletableMessageAge } = require('../util/Constants'); const MessageFlags = require('../util/MessageFlags'); const Permissions = require('../util/Permissions'); const SnowflakeUtil = require('../util/SnowflakeUtil'); @@ -625,6 +625,25 @@ class Message extends Base { ); } + /** + * Whether the message is bulk deletable by the client user + * @type {boolean} + * @readonly + * @example + * // Filter for bulk deletable messages + * channel.bulkDelete(messages.filter(message => message.bulkDeletable)); + */ + get bulkDeletable() { + const permissions = this.channel?.permissionsFor(this.client.user); + return ( + (this.inGuild() && + Date.now() - this.createdTimestamp < MaxBulkDeletableMessageAge && + this.deletable && + permissions?.has(Permissions.FLAGS.MANAGE_MESSAGES, false)) ?? + false + ); + } + /** * Whether the message is pinnable by the client user * @type {boolean} diff --git a/src/structures/interfaces/TextBasedChannel.js b/src/structures/interfaces/TextBasedChannel.js index b1397c159..bed289cad 100644 --- a/src/structures/interfaces/TextBasedChannel.js +++ b/src/structures/interfaces/TextBasedChannel.js @@ -5,7 +5,7 @@ const MessageCollector = require('../MessageCollector'); const MessagePayload = require('../MessagePayload'); const SnowflakeUtil = require('../../util/SnowflakeUtil'); const { Collection } = require('@discordjs/collection'); -const { InteractionTypes } = require('../../util/Constants'); +const { InteractionTypes, MaxBulkDeletableMessageAge } = require('../../util/Constants'); const { TypeError, Error } = require('../../errors'); const InteractionCollector = require('../InteractionCollector'); @@ -295,7 +295,7 @@ class TextBasedChannel { if (Array.isArray(messages) || messages instanceof Collection) { let messageIds = messages instanceof Collection ? [...messages.keys()] : messages.map(m => m.id ?? m); if (filterOld) { - messageIds = messageIds.filter(id => Date.now() - SnowflakeUtil.timestampFrom(id) < 1_209_600_000); + messageIds = messageIds.filter(id => Date.now() - SnowflakeUtil.timestampFrom(id) < MaxBulkDeletableMessageAge); } if (messageIds.length === 0) return new Collection(); if (messageIds.length === 1) { diff --git a/src/util/Constants.js b/src/util/Constants.js index 6988c1ffa..7db258bab 100644 --- a/src/util/Constants.js +++ b/src/util/Constants.js @@ -4,6 +4,12 @@ const process = require('node:process'); const Package = (exports.Package = require('../../package.json')); const { Error, RangeError, TypeError } = require('../errors'); +/** + * Max bulk deletable message age + * @typedef {number} MaxBulkDeletableMessageAge + */ +exports.MaxBulkDeletableMessageAge = 1_209_600_000; + exports.UserAgent = `DiscordBot (${Package.homepage}, ${Package.version}) Node.js/${process.version}`; /** @@ -1443,6 +1449,7 @@ function createEnum(keys) { * @property {SweeperKey[]} SweeperKeys The name of an item to be swept in Sweepers. * @property {SystemMessageType[]} SystemMessageTypes The types of messages that are `System`. * @property {Object} TextInputStyles The style of a text input component. + * @property {number} MaxBulkDeletableMessageAge Max bulk deletable message age * @property {string} UserAgent The user agent used for requests. * @property {Object} VerificationLevels * The value set for the verification levels for a guild. diff --git a/typings/index.d.ts b/typings/index.d.ts index 43f2bd7c4..caf37f40a 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1555,6 +1555,7 @@ export class Message extends Base { public applicationId: Snowflake | null; public attachments: Collection; public author: User; + public get bulkDeletable(): boolean; public readonly channel: If; public channelId: Snowflake; public readonly cleanContent: string; @@ -2930,6 +2931,7 @@ export const Constants: { devDependencies: Record; [key: string]: unknown; }; + MaxBulkDeletableMessageAge: 1_209_600_000; UserAgent: string; Endpoints: { botGateway: string;