diff --git a/packages/discord.js/src/errors/ErrorCodes.js b/packages/discord.js/src/errors/ErrorCodes.js index a161dd285c6aa..7d90c1b39596d 100644 --- a/packages/discord.js/src/errors/ErrorCodes.js +++ b/packages/discord.js/src/errors/ErrorCodes.js @@ -244,8 +244,9 @@ const keys = [ 'ImageSize', 'MessageBulkDeleteType', - 'MessageNonceType', 'MessageContentType', + 'MessageNonceRequired', + 'MessageNonceType', 'SplitMaxLen', diff --git a/packages/discord.js/src/errors/Messages.js b/packages/discord.js/src/errors/Messages.js index 2819f17f71b1c..b3c0514dfa61d 100644 --- a/packages/discord.js/src/errors/Messages.js +++ b/packages/discord.js/src/errors/Messages.js @@ -74,8 +74,9 @@ const Messages = { [DjsErrorCodes.ImageSize]: size => `Invalid image size: ${size}`, [DjsErrorCodes.MessageBulkDeleteType]: 'The messages must be an Array, Collection, or number.', - [DjsErrorCodes.MessageNonceType]: 'Message nonce must be an integer or a string.', [DjsErrorCodes.MessageContentType]: 'Message content must be a string.', + [DjsErrorCodes.MessageNonceRequired]: 'Message nonce is required when enforceNonce is true.', + [DjsErrorCodes.MessageNonceType]: 'Message nonce must be an integer or a string.', [DjsErrorCodes.SplitMaxLen]: 'Chunk exceeds the max length and contains no split characters.', diff --git a/packages/discord.js/src/structures/MessagePayload.js b/packages/discord.js/src/structures/MessagePayload.js index e42d483780a71..7ba9b798d0ae5 100644 --- a/packages/discord.js/src/structures/MessagePayload.js +++ b/packages/discord.js/src/structures/MessagePayload.js @@ -4,7 +4,7 @@ const { Buffer } = require('node:buffer'); const { lazy, isJSONEncodable } = require('@discordjs/util'); const { MessageFlags } = require('discord-api-types/v10'); const ActionRowBuilder = require('./ActionRowBuilder'); -const { DiscordjsRangeError, ErrorCodes } = require('../errors'); +const { DiscordjsError, DiscordjsRangeError, ErrorCodes } = require('../errors'); const { resolveFile } = require('../util/DataResolver'); const MessageFlagsBitField = require('../util/MessageFlagsBitField'); const { basename, verifyString } = require('../util/Util'); @@ -133,6 +133,11 @@ class MessagePayload { } } + const enforce_nonce = Boolean(this.options.enforceNonce); + if (enforce_nonce && nonce === undefined) { + throw new DiscordjsError(ErrorCodes.MessageNonceRequired); + } + const components = this.options.components?.map(component => (isJSONEncodable(component) ? component : new ActionRowBuilder(component)).toJSON(), ); @@ -201,6 +206,7 @@ class MessagePayload { content, tts, nonce, + enforce_nonce, embeds: this.options.embeds?.map(embed => isJSONEncodable(embed) ? embed.toJSON() : this.target.client.options.jsonTransformer(embed), ), diff --git a/packages/discord.js/src/structures/interfaces/TextBasedChannel.js b/packages/discord.js/src/structures/interfaces/TextBasedChannel.js index fd391f5df3a3a..68e2bb863e866 100644 --- a/packages/discord.js/src/structures/interfaces/TextBasedChannel.js +++ b/packages/discord.js/src/structures/interfaces/TextBasedChannel.js @@ -77,7 +77,11 @@ class TextBasedChannel { * The options for sending a message. * @typedef {BaseMessageOptions} BaseMessageCreateOptions * @property {boolean} [tts=false] Whether the message should be spoken aloud - * @property {string} [nonce=''] The nonce for the message + * @property {string} [nonce] The nonce for the message + * This property is required if `enforceNonce` set to `true`. + * @property {boolean} [enforceNonce] Whether the nonce should be checked for uniqueness in the past few minutes + * If another message was created by the same author with the same nonce, + * that message will be returned and no new message will be created * @property {StickerResolvable[]} [stickers=[]] The stickers to send in the message * @property {MessageFlags} [flags] Which flags to set for the message. * Only `MessageFlags.SuppressEmbeds` and `MessageFlags.SuppressNotifications` can be set. diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 92beb12bdae42..31fb8dc508971 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -6223,6 +6223,7 @@ export interface BaseMessageOptions { export interface MessageCreateOptions extends BaseMessageOptions { tts?: boolean; nonce?: string | number; + enforceNonce?: boolean; reply?: ReplyOptions; stickers?: StickerResolvable[]; flags?: BitFieldResolvable<