diff --git a/src/main/java/com/denizenscript/ddiscordbot/commands/DiscordInteractionCommand.java b/src/main/java/com/denizenscript/ddiscordbot/commands/DiscordInteractionCommand.java index ec47853..4617881 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,18 @@ 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. + // '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. // // Slash commands, and replies to interactions, have limitations. See <@link url https://gist.github.com/MinnDevelopment/b883b078fdb69d0e568249cc8bf37fe9>. @@ -62,7 +67,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. @@ -74,9 +79,19 @@ 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, 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 +114,12 @@ public static void autoExecute(ScriptEntry scriptEntry, } yield ((IReplyCallback) interaction.interaction).deferReply(ephemeral); } + case DEFER_UPDATE -> { + if (!(interaction.interaction instanceof IMessageEditCallback editCallback)) { + throw new InvalidArgumentsRuntimeException("Interaction is not a message edit callback!"); + } + yield editCallback.deferEdit(); + } case EDIT -> { AbstractMessageBuilder messageBuilder = DiscordMessageCommand.createMessageBuilder(scriptEntry, true, false, rows, message, embeds, attachFileName, attachFileText, attachFilesMap); InteractionHook hook = ((IDeferrableCallback) interaction.interaction).getHook(); @@ -115,6 +136,13 @@ public static void autoExecute(ScriptEntry scriptEntry, yield replyTo.reply(messageBuilder.build()).setEphemeral(ephemeral); } } + case UPDATE -> { + 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 editCallback.editMessage((MessageEditData) messageBuilder.build()); + } case DELETE -> { yield ((IDeferrableCallback) interaction.interaction).getHook().deleteOriginal(); }