From 584d7b1322e2b62e6f6c611405a76148c32dc44e Mon Sep 17 00:00:00 2001 From: BehrRiley Date: Fri, 4 Sep 2026 14:49:24 -0400 Subject: [PATCH 1/3] add `deter_update` and `update` instructions to `discordinteraction` - add `defer_update` to acknowledge a component interaction without a loading state - add `update` to immediately edit the original message of a component interaction - require `IMessageEditCallback` validation for the new instructions - update meta to clarify differences between `defer`, `defer_update`, `edit`, and `update` - add meta usage examples for the new instructions --- .../commands/DiscordInteractionCommand.java | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/denizenscript/ddiscordbot/commands/DiscordInteractionCommand.java b/src/main/java/com/denizenscript/ddiscordbot/commands/DiscordInteractionCommand.java index ec47853..2d711c9 100644 --- a/src/main/java/com/denizenscript/ddiscordbot/commands/DiscordInteractionCommand.java +++ b/src/main/java/com/denizenscript/ddiscordbot/commands/DiscordInteractionCommand.java @@ -12,6 +12,7 @@ import com.denizenscript.denizencore.scripts.commands.generator.*; import net.dv8tion.jda.api.interactions.InteractionHook; import net.dv8tion.jda.api.interactions.callbacks.IDeferrableCallback; +import net.dv8tion.jda.api.interactions.callbacks.IMessageEditCallback; import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback; import net.dv8tion.jda.api.requests.RestAction; import net.dv8tion.jda.api.utils.messages.*; @@ -22,7 +23,7 @@ public class DiscordInteractionCommand extends AbstractCommand implements Holdab public DiscordInteractionCommand() { setName("discordinteraction"); - setSyntax("discordinteraction [defer/reply/edit/delete] [interaction:] (ephemeral) (rows:) () (embed:|...) (attach_files:)"); + setSyntax("discordinteraction [defer/defer_update/reply/update/edit/delete] [interaction:] (ephemeral) (rows:) () (embed:|...) (attach_files:)"); setRequiredArguments(2, 7); isProcedural = false; autoCompile(); @@ -30,7 +31,7 @@ public DiscordInteractionCommand() { // <--[command] // @Name discordinteraction - // @Syntax discordinteraction [defer/reply/delete] [interaction:] (ephemeral) (rows:) () (embed:|...) (attach_files:) + // @Syntax discordinteraction [defer/defer_update/reply/update/edit/delete] [interaction:] (ephemeral) (rows:) () (embed:|...) (attach_files:) // @Required 2 // @Maximum 7 // @Short Manages Discord interactions. @@ -41,14 +42,17 @@ public DiscordInteractionCommand() { // @Description // Manages Discord interactions. // - // You can defer, reply to, edit, or delete an interaction. These instructions all require the "interaction" argument. + // You can defer, defer_update, reply to, update, edit, or delete an interaction. These instructions all require the 'interaction' argument. // - // The "ephemeral" argument can be used to have the reply message be visible to that one user. + // The 'ephemeral' argument can be used to have the reply message be visible to that one user. // - // You can defer an interaction before replying, which is useful if your reply may take more than a few seconds to be selected. + // 'defer' acknowledges an interaction with the normal 'Thinking...' state before a later reply, which is useful if your reply may take more than a few seconds to be selected. // If you defer, the 'ephemeral' option can only be set by the defer - you cannot change it with the later reply. - // Replying to an interaction uses similar logic to normal messaging. See <@link command discordmessage>. - // If you deferred without using 'ephemeral', the 'delete' option will delete the "Thinking..." message. + // 'defer_update' acknowledges a component interaction without a loading state, allowing its original message to be edited later. + // 'reply' provides the initial interaction response, or sends a followup after the interaction has been acknowledged. It uses similar logic to normal messaging. See <@link command discordmessage>. + // 'update' immediately updates the message associated with a component interaction as its initial response. + // 'edit' edits the interaction's original response through its interaction hook, and 'delete' deletes that original response. + // If you deferred without using 'ephemeral', the 'delete' option will delete the 'Thinking...' message. // Ephemeral replies cannot have files. // // Slash commands, and replies to interactions, have limitations. See <@link url https://gist.github.com/MinnDevelopment/b883b078fdb69d0e568249cc8bf37fe9>. @@ -62,7 +66,7 @@ public DiscordInteractionCommand() { // // @Usage // Use to quickly reply to a slash command interaction. - // - discordinteraction reply interaction: "hello!" + // - discordinteraction reply interaction: hello! // // @Usage // Use to defer and reply to a slash command interaction. @@ -76,7 +80,7 @@ public DiscordInteractionCommand() { // // --> - public enum DiscordInteractionInstruction { DEFER, REPLY, EDIT, DELETE } + public enum DiscordInteractionInstruction { DEFER, DEFER_UPDATE, REPLY, UPDATE, EDIT, DELETE } public static void autoExecute(ScriptEntry scriptEntry, @ArgName("instruction") DiscordInteractionInstruction instruction, @@ -99,6 +103,12 @@ public static void autoExecute(ScriptEntry scriptEntry, } yield ((IReplyCallback) interaction.interaction).deferReply(ephemeral); } + case DEFER_UPDATE -> { + if (!(interaction.interaction instanceof IMessageEditCallback)) { + throw new InvalidArgumentsRuntimeException("Interaction is not a message edit callback!"); + } + yield ((IMessageEditCallback) interaction.interaction).deferEdit(); + } case EDIT -> { AbstractMessageBuilder messageBuilder = DiscordMessageCommand.createMessageBuilder(scriptEntry, true, false, rows, message, embeds, attachFileName, attachFileText, attachFilesMap); InteractionHook hook = ((IDeferrableCallback) interaction.interaction).getHook(); @@ -115,6 +125,13 @@ public static void autoExecute(ScriptEntry scriptEntry, yield replyTo.reply(messageBuilder.build()).setEphemeral(ephemeral); } } + case UPDATE -> { + if (!(interaction.interaction instanceof IMessageEditCallback)) { + throw new InvalidArgumentsRuntimeException("Interaction is not a message edit callback!"); + } + AbstractMessageBuilder messageBuilder = DiscordMessageCommand.createMessageBuilder(scriptEntry, true, false, rows, message, embeds, attachFileName, attachFileText, attachFilesMap); + yield ((IMessageEditCallback) interaction.interaction).editMessage((MessageEditData) messageBuilder.build()); + } case DELETE -> { yield ((IDeferrableCallback) interaction.interaction).getHook().deleteOriginal(); } From 87b6a98101d0da880c241d291f816b80d67086a4 Mon Sep 17 00:00:00 2001 From: BehrRiley Date: Fri, 4 Sep 2026 16:06:27 -0400 Subject: [PATCH 2/3] add component interaction update callbacks - apply review feedback for component interaction updates - use pattern matching for message edit callbacks, clarify the individual interaction instructions, and document update and deferred-update usage meta --- .../commands/DiscordInteractionCommand.java | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/denizenscript/ddiscordbot/commands/DiscordInteractionCommand.java b/src/main/java/com/denizenscript/ddiscordbot/commands/DiscordInteractionCommand.java index 2d711c9..3d136a2 100644 --- a/src/main/java/com/denizenscript/ddiscordbot/commands/DiscordInteractionCommand.java +++ b/src/main/java/com/denizenscript/ddiscordbot/commands/DiscordInteractionCommand.java @@ -51,7 +51,8 @@ public DiscordInteractionCommand() { // 'defer_update' acknowledges a component interaction without a loading state, allowing its original message to be edited later. // 'reply' provides the initial interaction response, or sends a followup after the interaction has been acknowledged. It uses similar logic to normal messaging. See <@link command discordmessage>. // 'update' immediately updates the message associated with a component interaction as its initial response. - // 'edit' edits the interaction's original response through its interaction hook, and 'delete' deletes that original response. + // 'edit' edits the interaction's original response through its interaction hook. + // 'delete' deletes the interaction's original response through its interaction hook. // If you deferred without using 'ephemeral', the 'delete' option will delete the 'Thinking...' message. // Ephemeral replies cannot have files. // @@ -78,6 +79,16 @@ public DiscordInteractionCommand() { // - ~discordinteraction defer interaction: ephemeral:true // - discordinteraction reply interaction: "Shh, don't tell anyone!" // + // @Usage + // Use to immediately update the message associated with a component interaction. + // - discordinteraction update interaction: Updated! + // + // @Usage + // Use to silently acknowledge a component interaction, then update its original message later. + // - ~discordinteraction defer_update interaction: + // - wait 2s + // - discordinteraction edit interaction: Updated after processing. + // // --> public enum DiscordInteractionInstruction { DEFER, DEFER_UPDATE, REPLY, UPDATE, EDIT, DELETE } @@ -104,10 +115,10 @@ public static void autoExecute(ScriptEntry scriptEntry, yield ((IReplyCallback) interaction.interaction).deferReply(ephemeral); } case DEFER_UPDATE -> { - if (!(interaction.interaction instanceof IMessageEditCallback)) { + if (!(interaction.interaction instanceof IMessageEditCallback editCallback)) { throw new InvalidArgumentsRuntimeException("Interaction is not a message edit callback!"); } - yield ((IMessageEditCallback) interaction.interaction).deferEdit(); + yield editCallback.deferEdit(); } case EDIT -> { AbstractMessageBuilder messageBuilder = DiscordMessageCommand.createMessageBuilder(scriptEntry, true, false, rows, message, embeds, attachFileName, attachFileText, attachFilesMap); @@ -126,11 +137,11 @@ public static void autoExecute(ScriptEntry scriptEntry, } } case UPDATE -> { - if (!(interaction.interaction instanceof IMessageEditCallback)) { + if (!(interaction.interaction instanceof IMessageEditCallback editCallback)) { throw new InvalidArgumentsRuntimeException("Interaction is not a message edit callback!"); } AbstractMessageBuilder messageBuilder = DiscordMessageCommand.createMessageBuilder(scriptEntry, true, false, rows, message, embeds, attachFileName, attachFileText, attachFilesMap); - yield ((IMessageEditCallback) interaction.interaction).editMessage((MessageEditData) messageBuilder.build()); + yield editCallback.editMessage((MessageEditData) messageBuilder.build()); } case DELETE -> { yield ((IDeferrableCallback) interaction.interaction).getHook().deleteOriginal(); From ece6357530fac5f5249e6812400ab688558f45d7 Mon Sep 17 00:00:00 2001 From: BehrRiley Date: Fri, 4 Sep 2026 16:10:47 -0400 Subject: [PATCH 3/3] correct DenizenScript syntax --- .../ddiscordbot/commands/DiscordInteractionCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/denizenscript/ddiscordbot/commands/DiscordInteractionCommand.java b/src/main/java/com/denizenscript/ddiscordbot/commands/DiscordInteractionCommand.java index 3d136a2..4617881 100644 --- a/src/main/java/com/denizenscript/ddiscordbot/commands/DiscordInteractionCommand.java +++ b/src/main/java/com/denizenscript/ddiscordbot/commands/DiscordInteractionCommand.java @@ -87,7 +87,7 @@ public DiscordInteractionCommand() { // Use to silently acknowledge a component interaction, then update its original message later. // - ~discordinteraction defer_update interaction: // - wait 2s - // - discordinteraction edit interaction: Updated after processing. + // - discordinteraction edit interaction: "Updated after processing." // // -->