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<