diff --git a/src/errors/Messages.js b/src/errors/Messages.js index c9d7983fea8a..2b5beaf5c5f9 100644 --- a/src/errors/Messages.js +++ b/src/errors/Messages.js @@ -115,6 +115,8 @@ const Messages = { "or from a guild's application command manager.", INTERACTION_ALREADY_REPLIED: 'This interaction has already been deferred or replied to.', + INTERACTION_NOT_REPLIED: 'This interaction has not been deferred or replied to.', + INTERACTION_EPHEMERAL_REPLIED: 'Ephemeral responses cannot be fetched or deleted.', }; for (const [name, message] of Object.entries(Messages)) register(name, message); diff --git a/src/structures/CommandInteraction.js b/src/structures/CommandInteraction.js index f5218ccf1bb2..0f4c6672e9c7 100644 --- a/src/structures/CommandInteraction.js +++ b/src/structures/CommandInteraction.js @@ -58,6 +58,12 @@ class CommandInteraction extends Interaction { */ this.replied = false; + /** + * Whether the reply to this interaction is ephemeral + * @type {?boolean} + */ + this.ephemeral = null; + /** * An associated interaction webhook, can be used to further interact with this interaction * @type {InteractionWebhook} diff --git a/src/structures/MessageComponentInteraction.js b/src/structures/MessageComponentInteraction.js index a0714e1252c0..ffb13caab3a0 100644 --- a/src/structures/MessageComponentInteraction.js +++ b/src/structures/MessageComponentInteraction.js @@ -38,6 +38,12 @@ class MessageComponentInteraction extends Interaction { */ this.deferred = false; + /** + * Whether the reply to this interaction is ephemeral + * @type {?boolean} + */ + this.ephemeral = null; + /** * Whether this interaction has already been replied to * @type {boolean} diff --git a/src/structures/interfaces/InteractionResponses.js b/src/structures/interfaces/InteractionResponses.js index da23b726eced..ea899a8f68db 100644 --- a/src/structures/interfaces/InteractionResponses.js +++ b/src/structures/interfaces/InteractionResponses.js @@ -39,6 +39,7 @@ class InteractionResponses { */ async defer({ ephemeral } = {}) { if (this.deferred || this.replied) throw new Error('INTERACTION_ALREADY_REPLIED'); + this.ephemeral = ephemeral ?? false; await this.client.api.interactions(this.id, this.token).callback.post({ data: { type: InteractionResponseTypes.DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE, @@ -69,6 +70,7 @@ class InteractionResponses { */ async reply(options) { if (this.deferred || this.replied) throw new Error('INTERACTION_ALREADY_REPLIED'); + this.ephemeral = options.ephemeral ?? false; let apiMessage; if (options instanceof APIMessage) apiMessage = options; @@ -97,6 +99,7 @@ class InteractionResponses { * .catch(console.error); */ fetchReply() { + if (this.ephemeral) throw new Error('INTERACTION_EPHEMERAL_REPLIED'); return this.webhook.fetchMessage('@original'); } @@ -112,6 +115,7 @@ class InteractionResponses { * .catch(console.error); */ editReply(options) { + if (!this.deferred && !this.replied) throw new Error('INTERACTION_NOT_REPLIED'); return this.webhook.editMessage('@original', options); } @@ -126,6 +130,7 @@ class InteractionResponses { * .catch(console.error); */ async deleteReply() { + if (this.ephemeral) throw new Error('INTERACTION_EPHEMERAL_REPLIED'); await this.webhook.deleteMessage('@original'); } diff --git a/typings/index.d.ts b/typings/index.d.ts index b6b30b1d5b04..26b1b21b99e1 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -509,6 +509,7 @@ declare module 'discord.js' { public commandID: Snowflake; public commandName: string; public deferred: boolean; + public ephemeral: boolean | null; public options: Collection; public replied: boolean; public webhook: InteractionWebhook; @@ -1368,6 +1369,7 @@ declare module 'discord.js' { public componentType: MessageComponentType; public customID: string; public deferred: boolean; + public ephemeral: boolean | null; public message: Message | RawMessage; public replied: boolean; public webhook: InteractionWebhook;