From 5c897871dc5254b1057514e7353ad54b3f79b1dd Mon Sep 17 00:00:00 2001 From: Jiralite <33201955+Jiralite@users.noreply.github.com> Date: Tue, 22 Oct 2024 07:10:30 +0100 Subject: [PATCH 1/4] refactor(InteractionResponses): deprecate `ephemeral` response option --- .../src/structures/MessagePayload.js | 1 + .../interfaces/InteractionResponses.js | 32 ++++++++++++------- .../src/util/MessageFlagsBitField.js | 9 ++++++ packages/discord.js/typings/index.d.ts | 13 ++++++-- 4 files changed, 41 insertions(+), 14 deletions(-) diff --git a/packages/discord.js/src/structures/MessagePayload.js b/packages/discord.js/src/structures/MessagePayload.js index dad8ffedb026..48519d0a5682 100644 --- a/packages/discord.js/src/structures/MessagePayload.js +++ b/packages/discord.js/src/structures/MessagePayload.js @@ -92,6 +92,7 @@ class MessagePayload { * Whether or not the target is an {@link BaseInteraction} or an {@link InteractionWebhook} * @type {boolean} * @readonly + * @deprecated This will no longer serve a purpose in the next major version. */ get isInteraction() { const BaseInteraction = getBaseInteraction(); diff --git a/packages/discord.js/src/structures/interfaces/InteractionResponses.js b/packages/discord.js/src/structures/interfaces/InteractionResponses.js index 440242a34e56..67779a31e4f6 100644 --- a/packages/discord.js/src/structures/interfaces/InteractionResponses.js +++ b/packages/discord.js/src/structures/interfaces/InteractionResponses.js @@ -4,7 +4,6 @@ const { deprecate } = require('node:util'); const { isJSONEncodable } = require('@discordjs/util'); const { InteractionResponseType, MessageFlags, Routes, InteractionType } = require('discord-api-types/v10'); const { DiscordjsError, ErrorCodes } = require('../../errors'); -const MessageFlagsBitField = require('../../util/MessageFlagsBitField'); const InteractionCollector = require('../InteractionCollector'); const InteractionResponse = require('../InteractionResponse'); const MessagePayload = require('../MessagePayload'); @@ -24,7 +23,10 @@ class InteractionResponses { /** * Options for deferring the reply to an {@link BaseInteraction}. * @typedef {Object} InteractionDeferReplyOptions - * @property {boolean} [ephemeral] Whether the reply should be ephemeral + * @property {boolean} [ephemeral] Whether the reply should be ephemeral. + * This option is deprecated. Use `flags` instead. + * @property {MessageFlagsResolvable} [flags] Flags for the reply. + * Only `MessageFlags.Ephemeral` can be set. * @property {boolean} [fetchReply] Whether to fetch the reply */ @@ -37,10 +39,11 @@ class InteractionResponses { /** * Options for a reply to a {@link BaseInteraction}. * @typedef {BaseMessageOptionsWithPoll} InteractionReplyOptions + * @property {boolean} [ephemeral] Whether the reply should be ephemeral. + * This option is deprecated. Use `flags` instead. * @property {boolean} [tts=false] Whether the message should be spoken aloud - * @property {boolean} [ephemeral] Whether the reply should be ephemeral * @property {boolean} [fetchReply] Whether to fetch the reply - * @property {MessageFlags} [flags] Which flags to set for the message. + * @property {MessageFlagsResolvable} [flags] Which flags to set for the message. * Only `MessageFlags.Ephemeral`, `MessageFlags.SuppressEmbeds`, and `MessageFlags.SuppressNotifications` * can be set. */ @@ -62,24 +65,30 @@ class InteractionResponses { * .catch(console.error) * @example * // Defer to send an ephemeral reply later - * interaction.deferReply({ ephemeral: true }) + * interaction.deferReply({ flags: MessageFlags.Ephemeral }) * .then(console.log) * .catch(console.error); */ async deferReply(options = {}) { if (this.deferred || this.replied) throw new DiscordjsError(ErrorCodes.InteractionAlreadyReplied); - this.ephemeral = options.ephemeral ?? false; + let { flags } = options; + + if (options.ephemeral) { + flags |= MessageFlags.Ephemeral; + } + await this.client.rest.post(Routes.interactionCallback(this.id, this.token), { body: { type: InteractionResponseType.DeferredChannelMessageWithSource, data: { - flags: options.ephemeral ? MessageFlags.Ephemeral : undefined, + flags, }, }, auth: false, }); - this.deferred = true; + this.deferred = true; + this.ephemeral = Boolean(flags & MessageFlags.Ephemeral); return options.fetchReply ? this.fetchReply() : new InteractionResponse(this); } @@ -97,7 +106,7 @@ class InteractionResponses { * // Create an ephemeral reply with an embed * const embed = new EmbedBuilder().setDescription('Pong!'); * - * interaction.reply({ embeds: [embed], ephemeral: true }) + * interaction.reply({ embeds: [embed], flags: MessageFlags.Ephemeral }) * .then(() => console.log('Reply sent.')) * .catch(console.error); */ @@ -110,8 +119,6 @@ class InteractionResponses { const { body: data, files } = await messagePayload.resolveBody().resolveFiles(); - this.ephemeral = new MessageFlagsBitField(data.flags).has(MessageFlags.Ephemeral); - await this.client.rest.post(Routes.interactionCallback(this.id, this.token), { body: { type: InteractionResponseType.ChannelMessageWithSource, @@ -120,8 +127,9 @@ class InteractionResponses { files, auth: false, }); - this.replied = true; + this.ephemeral = Boolean(data.flags & MessageFlags.Ephemeral); + this.replied = true; return options.fetchReply ? this.fetchReply() : new InteractionResponse(this); } diff --git a/packages/discord.js/src/util/MessageFlagsBitField.js b/packages/discord.js/src/util/MessageFlagsBitField.js index 71f1fd6c5c08..e6764b2fd791 100644 --- a/packages/discord.js/src/util/MessageFlagsBitField.js +++ b/packages/discord.js/src/util/MessageFlagsBitField.js @@ -23,6 +23,15 @@ class MessageFlagsBitField extends BitField { * @param {BitFieldResolvable} [bits=0] Bit(s) to read from */ +/** + * Data that can be resolved to give a message flags bit field. This can be: + * * A string (see {@link MessageFlagsBitField.Flags}) + * * A message flag + * * An instance of {@link MessageFlagsBitField} + * * An array of `MessageFlagsResolvable` + * @typedef {string|number|MessageFlagsBitField|MessageFlagsResolvable[]} MessageFlagsResolvable + */ + /** * Bitfield of the packed bits * @type {number} diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 8f7da19e47bc..70d9bd0a3e3c 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -2441,6 +2441,7 @@ export class MessagePayload { public get isWebhook(): boolean; public get isMessage(): boolean; public get isMessageManager(): boolean; + /** @deprecated This will no longer serve a purpose in the next major version. */ public get isInteraction(): boolean; public files: RawFile[] | null; public options: MessagePayloadOption; @@ -6351,15 +6352,23 @@ export interface InteractionCollectorOptions< } export interface InteractionDeferReplyOptions { + /** @deprecated Use {@link InteractionDeferReplyOptions.flags} instead. */ ephemeral?: boolean; + flags?: BitFieldResolvable< + Extract, + MessageFlags.Ephemeral | MessageFlags.SuppressEmbeds | MessageFlags.SuppressNotifications + >; fetchReply?: boolean; } -export interface InteractionDeferUpdateOptions extends Omit {} +export interface InteractionDeferUpdateOptions { + fetchReply?: boolean; +} export interface InteractionReplyOptions extends BaseMessageOptionsWithPoll { - tts?: boolean; + /** @deprecated Use {@link InteractionDeferReplyOptions.flags} instead. */ ephemeral?: boolean; + tts?: boolean; fetchReply?: boolean; flags?: BitFieldResolvable< Extract, From b4c0ca3f001034e44c3ace117aad91a2401ced7b Mon Sep 17 00:00:00 2001 From: Jiralite <33201955+Jiralite@users.noreply.github.com> Date: Wed, 23 Oct 2024 10:50:15 +0100 Subject: [PATCH 2/4] refactor: add runtime deprecations --- .../interfaces/InteractionResponses.js | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/packages/discord.js/src/structures/interfaces/InteractionResponses.js b/packages/discord.js/src/structures/interfaces/InteractionResponses.js index 67779a31e4f6..dac44bf01597 100644 --- a/packages/discord.js/src/structures/interfaces/InteractionResponses.js +++ b/packages/discord.js/src/structures/interfaces/InteractionResponses.js @@ -1,5 +1,6 @@ 'use strict'; +const process = require('node:process'); const { deprecate } = require('node:util'); const { isJSONEncodable } = require('@discordjs/util'); const { InteractionResponseType, MessageFlags, Routes, InteractionType } = require('discord-api-types/v10'); @@ -8,6 +9,8 @@ const InteractionCollector = require('../InteractionCollector'); const InteractionResponse = require('../InteractionResponse'); const MessagePayload = require('../MessagePayload'); +let deprecationEmittedForEphemeralOption = false; + /** * @typedef {Object} ModalComponentData * @property {string} title The title of the modal @@ -71,6 +74,17 @@ class InteractionResponses { */ async deferReply(options = {}) { if (this.deferred || this.replied) throw new DiscordjsError(ErrorCodes.InteractionAlreadyReplied); + + if ('ephemeral' in options) { + if (!deprecationEmittedForEphemeralOption) { + process.emitWarning( + `Supplying "ephemeral" for interaction response options is deprecated. Utilize flags instead.`, + ); + + deprecationEmittedForEphemeralOption = true; + } + } + let { flags } = options; if (options.ephemeral) { @@ -113,6 +127,16 @@ class InteractionResponses { async reply(options) { if (this.deferred || this.replied) throw new DiscordjsError(ErrorCodes.InteractionAlreadyReplied); + if ('ephemeral' in options) { + if (!deprecationEmittedForEphemeralOption) { + process.emitWarning( + `Supplying "ephemeral" for interaction response options is deprecated. Utilize flags instead.`, + ); + + deprecationEmittedForEphemeralOption = true; + } + } + let messagePayload; if (options instanceof MessagePayload) messagePayload = options; else messagePayload = MessagePayload.create(this, options); From a5136b92737f8ebe8b39798b3edc0b9e43bb89e5 Mon Sep 17 00:00:00 2001 From: Jiralite <33201955+Jiralite@users.noreply.github.com> Date: Thu, 24 Oct 2024 11:23:59 +0100 Subject: [PATCH 3/4] docs: fix reference Co-authored-by: Almeida --- packages/discord.js/typings/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 70d9bd0a3e3c..f9d09dab5093 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -6366,7 +6366,7 @@ export interface InteractionDeferUpdateOptions { } export interface InteractionReplyOptions extends BaseMessageOptionsWithPoll { - /** @deprecated Use {@link InteractionDeferReplyOptions.flags} instead. */ + /** @deprecated Use {@link InteractionReplyOptions.flags} instead. */ ephemeral?: boolean; tts?: boolean; fetchReply?: boolean; From 57b97f73f2bb06933470ed79e72a8d83efc5d7a6 Mon Sep 17 00:00:00 2001 From: Jiralite <33201955+Jiralite@users.noreply.github.com> Date: Thu, 24 Oct 2024 11:29:28 +0100 Subject: [PATCH 4/4] types: add `MessageFlagsResolvable` --- packages/discord.js/typings/index.d.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index f9d09dab5093..e9982abc2013 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -2389,9 +2389,11 @@ export type MessageFlagsString = keyof typeof MessageFlags; export class MessageFlagsBitField extends BitField { public static Flags: typeof MessageFlags; - public static resolve(bit?: BitFieldResolvable): number; + public static resolve(bit?: MessageFlagsResolvable): number; } +export type MessageFlagsResolvable = BitFieldResolvable; + export class MessageMentions { private constructor( message: Message,