Skip to content

Releases: Kaktushose/jda-commands

v4.0.0-beta.2 | Static Interactions and QoL changes

19 Apr 10:00
Compare
Choose a tag to compare

Overview

This release introduces many small QoL features as well as lots of bug fixes.

Static Interactions

You can now disable the request-scoped instances by annotating the interaction class with StaticInstance. This will create one instance of the class that will be used until jda-commands shuts down.

In the following example every global counter command will use the same counter variable. Thus, if you have 2 commands active, pressing the button on the first command will also increase the count for the second command.

@Interaction
@StaticInstance
public class StaticTest {

    private int counter;

    @SlashCommand("global counter")
    public void onCommand(CommandEvent event) {
        event.withButtons("onButton").reply("Global counter");
    }

    @Button("click me")
    public void onButton(ComponentEvent event) {
        counter++;
        event.reply("counter: " + counter);
    }
}

MessageBuilder Components

In the past components were only usable in combination with commands. However, sometimes you want to add a component to a MessageBuilder.

From now on you can use JDACommands#getButton(String id) or respectively JDACommands#getSelectMenu(String id) to access a component outside of commands. The component can be defined anywhere inside the project. The id consists of the simple class name and the method name, e.g. VoteButtons.onUpvote.

Example:

@Interaction
@StaticInstance
public class ComponentAPITest extends ListenerAdapter {

    @Override
    public void onMessageReceived(@NotNull MessageReceivedEvent event) {
        if (!event.getMessage().getContentDisplay().startsWith("!greet")) {
            return;
        }

        var builder = new MessageCreateBuilder().setContent("Hello").addActionRow(jdaCommands.getButton("ComponentAPITest.onButton"));

        event.getChannel().sendMessage(builder.build()).queue();
    }

    @Button("Greet me!")
    public void onButton(ComponentEvent event) {
        event.editReply(false).reply("Hello %s", event.getUser());
    }
}

Please note that the onButton method doesn't need to be defined in the same class it is referred in. This was only done here to keep the example short and sweet. Also be aware that the keepComponents feature doesn't work in this case, because it requires request-scoped instances. Thus you'd need to reattach the button if you set editReply to true.

1) New Features

  • added the skipIndexing boolean to @Produces annotation. If set to true jda-commands will ignore this producer method at indexing. This is useful if you wish to register your dependency providers manually by calling DependencyInjector#registerProvider(Object).

  • Implemented a simple KeyValueStore that can be accessed from every event class by calling kv()

2) Changes

  • jda-commands will now ignore any incoming component or modal events that weren't created by jda-commands. However, foreign commands will still create a error message.

  • when starting jda-commands you can now provide your own DependencyInjector implementation

3) Bug Fixes

  • fixed that Constraints didn't get applied to parameters
  • fixed that using an EmbedDTO to reply overwrote components
  • fixed incorrect parameter name sanitation
  • fixed that root commands didn't adopt the configuration of their subcommands
  • fixed a bug where Modals sometimes didn't get executed

4) Internal changes

  • the SlashCommandUpdater now uses the GuildReadyEvent for initial command setup
  • made the DependencyInjector class an interface and added a default implementation
  • changed the naming scheme of internal ids for defintions and runtimes

You can find the complete changelog here.

Also, checkout the Wiki or the JavaDoc.

Maven

<repository>
    <id>jitpack.io</id>
    <url>https://jitpack.io</url>
</repository>
<dependency>
    <groupId>com.github.Kaktushose</groupId>
    <artifactId>jda-commands</artifactId>
    <version>v4.0.0-beta.2</version>
</dependency>

Gradle

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}
dependencies {
    implementation 'com.github.Kaktushose:jda-commands:v4.0.0-beta.2'
}

v4.0.0-beta.1 | Middleware API

25 Nov 17:30
Compare
Choose a tag to compare

Overview

This release comes in with a rework of the Filter API and some minor bug fixes. But most importantly: with this release we were also finally able to end the alpha period and slowly but surely move into a constant and more stable development 🎉

Middleware API

In previous jda-commands versions you were able to add Filters to apply certain business rules on your command executions. The Filter API got removed in the last release and now there is a replacement in the form of middlewares. Essentially, they do the same thing as Filters but with a more generalized approach.

The Filter implementations for cooldowns, permissions and validators were migrated to the new Middleware API. However the UserMuteFilter and DirectMessageFilter were obsolte and thus removed.

Middlewares are always executed just before the interaction method will be called. This ensures that definition binding, type adapting and runtime resolving is already done.

Middlewares can choose one of four priorities always running in that order:

  1. PERMISSIONS (ensures that the PermissionsMiddleware is always executed first)
  2. HIGH
  3. NORMAL (default)
  4. LOW

Here is a quick example on how to add your own middlewares. Let's say we want to prevent all users named Kaktushose from executing interactions:

@Implementation(priority = Priority.HIGH)
public class KakutsFilter implements Middleware {

    @Override
    public void execute(Context context) {
        if (context.getEvent().getUser().getEffectiveName().equals("Kaktushose")) {
            context.setCancelled(MessageCreateData.fromContent("Users named Kaktushose aren't allowed to execute interactions!"));
        }
    }

}

1) New Features

  • Permissions got simplified. Muting users now also works via the PermissionsProvider. Furthermore, you can now apply permissions to all types of interactions, not only slash commands.

2) Changes

  • Updated a lot of the Javadocs, the Wiki will be updated soon as well. For the moment please refer to the release notes
  • Context#setCancelled(true) got changed to Context#setCancelled(MessageCreateData). This ensures that there is always an error message to display. Thus, Context#setErrorMessage got removed and Context#setUncancelled got introduced to undo the cancelation

3) Bug Fixes

  • fixed that other interaction types besides of slash commands had an incorrect display name in error messages
  • fixed localization not working for sub commands and sub command groups
  • fixed that failing events (e.g. unknown button) couldn't send an error message
  • fixed that despite editReply set to true a new message was always sent

4) Internal changes

  • Introduced GenericComponentDefinition to remove the type parameters for CommandEvent und ComponentEvent

You can find the complete changelog here.

Also, checkout the Wiki or the JavaDoc.

Maven

<repository>
    <id>jitpack.io</id>
    <url>https://jitpack.io</url>
</repository>
<dependency>
    <groupId>com.github.Kaktushose</groupId>
    <artifactId>jda-commands</artifactId>
    <version>v4.0.0-beta.1</version>
</dependency>

Gradle

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}
dependencies {
    implementation 'com.github.Kaktushose:jda-commands:v4.0.0-beta.1'
}

v4.0.0-alpha.5 | Modals & Context Menus

31 Oct 15:17
Compare
Choose a tag to compare

Overview

This release brings in the last two missing interaction types as well as some major internal refactoring, which comes at the cost of some breaking changes.

Modals

Modals are another way of replying to a command event. They will open a popup on the target user's Discord client. You build Modals just like any other interaction, but instead of attaching them to your response like you would do with components, you have to use a seperate reply method:

@Interaction
public class ModalTest {

    @SlashCommand(value = "modmail")
    public void onCommand(CommandEvent event) {
        event.replyModal("onModal");

    }

    @Modal("Modmail")
    public void onModal(ModalEvent event, 
    @TextInput(label = "Subject of this ticket", style = TextInputStyle.SHORT) String subject, 
    @TextInput(label = "Your concerns go here") String body) {
        createSupportTicket(subject, body);
        event.reply("Thanks for your request!");
    }
}

Context Menus

Context Menus are a special type of commands that can be invoked on a user or message by right-clicking on them. In jda-commands you use them just like normal slash commands:

@Interaction
public class ContextMenuTest {

    @ContextCommand(value = "Count words", type = Command.Type.MESSAGE)
    public void onMessageCommand(CommandEvent event, Message message) {
        event.reply("Words: " + message.getContentRaw().split("\\s+").length);
    }

    @ContextCommand(value = "Get user avatar", type = Command.Type.USER)
    public void onUserCommand(CommandEvent event, User user) {
        event.reply("Avatar: " + user.getEffectiveAvatarUrl());
    }
}

1) New Features

  • AutoComplete handlers now also accept the top level command name and don't require a full command path anymore

2) Changes

Important

Temporarely removed Filter functionality. This is due to internal changes and preperation of the upcoming Filter API rewrite


  • Merged ButtonEvent and SelectMenuEvent into ComponentEvent

Note

CommandEvent and ComponentEvent are currently parameterized classes. This can be ignored and will change with the next release


  • Removed the @Optional annotation. Instead you pass the default value now directly to the @Param annotation
  • Events are now only acknowledegd when they passed the execution chain as well as your code completelty
  • Added access to the RuntimeSupversior via the JDACommands instance
  • Renamed GenericContext to Context and removed all of its subtypes except for slash command interactions
  • Removed key store value functionality from GenericEvent
  • Added access to the success callback and failure callback directly through the event class

3) Bug Fixes

  • Fixed a bug where auto complete listeners didn't get registered

4) Internal changes

  • Merged ParserSupervisor into DispatcherSupervisor and thus removed GenericParser and it's subtypes
  • Merged ButtonDispatcher and SelectMenuDispatcher into ComponentDispatcher
  • Renamed:
    • CommandDefinition -> SlashCommandDefinition
    • GenericContext -> Context
    • Context#getInteraction -> Context#getInteractionDefinition
    • ControllerDefinition -> InteractionControllerDefinition
    • EphemeralInteraction -> EphemeralInteractionDefinition
    • GenericInteraction -> GenericInteractionDefinition
  • Made GenericEvent a subtype of GenericInteractionCreateEvent and removed method overload
  • Added static instance creation to the RuntimeSupervisor
  • Implemented a default implementation of the reply method inside the Replyable interface

You can find the complete changelog here.

Also, checkout the Wiki or the JavaDoc.

Maven

<repository>
    <id>jitpack.io</id>
    <url>https://jitpack.io</url>
</repository>
<dependency>
    <groupId>com.github.Kaktushose</groupId>
    <artifactId>jda-commands</artifactId>
    <version>v4.0.0-alpha.5</version>
</dependency>

Gradle

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}
dependencies {
    implementation 'com.github.Kaktushose:jda-commands:v4.0.0-alpha.5'
}

v4.0.0-alpha.4 | Select Menus & Auto Complete

15 Oct 12:32
Compare
Choose a tag to compare

Overview

This release complements the component api with the implementation of Select Menus. Furthermore, autocomplete can now be used as an alternative to Command Choices.

Select Menus

SelectMenus work in the same way as Buttons do. Please refer to the 4.0.0-alpha.3 release notes for further explanation. Below are two brief examples of the use of select menus:

EntitySelectMenus

@Interaction
public class MenuTest {

    @SlashCommand("select")
    public void onCommand(CommandEvent event) {
        event.withSelectMenus("onUserSelect").reply("Select menu demonstration");
    }

    @EntitySelectMenu(value = SelectTarget.USER, placeholder = "Please select a user")
    public void onUserSelect(SelectMenuEvent event, Mentions mentions) {
        event.reply("You selected %s", mentions.getMembers().get(0).getAsMention());
    }

StringSelectMenus

@Interaction
public class MenuTest {

    @SlashCommand("select")
    public void onCommand(CommandEvent event) {
        event.withSelectMenus("onStringSelect").reply("Select menu demonstration");
    }

    @StringSelectMenu("What's your favourite food?")
    @SelectOption(value = "pizza", label = "Pizza", description = "Who doesn't like pizza?")
    @SelectOption(value = "hamburger", label = "Hamburger", description = "yummy.", emoji = "\uD83C\uDF54")
    @SelectOption(value = "fries", label = "Fries", description = "quick and good.", isDefault = true)
    public void onStringSelect(SelectMenuEvent event, List<String> values) {
        event.keepComponents(false).reply("You've selected %s", values.get(0));
    }

AutoComplete

When having parameters you can specify up to 25 predefined choices. But sometimes that isn't enough. That's where AutoComplete comes in handy. See the following example for a quick overview over this feature:

@Interaction
public class AutoCompleteTest {

    private final String[] words = new String[]{"apple", "apricot", "banana", "cherry", "coconut", "cranberry"};

    @SlashCommand("fruit")
    public void onCommand(CommandEvent event, @Param("fruit to find") String name) {
        event.reply("You selected %s", name);
    }

    @AutoComplete("fruit")
    public void onAutoComplete(AutoCompleteEvent event) {
        event.replyChoices(Stream.of(words)
                .filter(word -> word.startsWith(event.getValue()))
                .map(word -> new Command.Choice(word, word))
                .collect(Collectors.toList())
        );
    }
}

GIF 13-10-2023 14-24-01

Note, that you can have the same AutoCompleteDefintion assigned to multiple commands but not multiple AutoCompleteDefintions assigned to the same command.

1) New Features

  • see above

2) Changes

  • moved dispatching/commands|buttons|menus|autocomplete to dispatching/interactions
  • moved components to dispatching/reply/components

3) Bug Fixes

  • Buttons now adopt the ephemeral settings of the controller class

4) Internal changes

  • added static instance creation to the RuntimeSupervisor
  • implemented a default implementation of the reply method inside the Replyable interface

You can find the complete changelog here.

Also, checkout the Wiki or the JavaDoc.

Maven

<repository>
    <id>jitpack.io</id>
    <url>https://jitpack.io</url>
</repository>
<dependency>
    <groupId>com.github.Kaktushose</groupId>
    <artifactId>jda-commands</artifactId>
    <version>v4.0.0-alpha.4</version>
</dependency>

Gradle

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}
dependencies {
    implementation 'com.github.Kaktushose:jda-commands:v4.0.0-alpha.4'
}

v4.0.0-alpha.3 | Buttons & Localization

01 Oct 14:30
Compare
Choose a tag to compare

Overview

This release brings in Buttons, Localization and some minor changes and improvements.

Buttons

Writing Buttons

Buttons are defined in the same way as Slash Commands are:

@Button("Click Me!")
public void clickMe(ButtonEvent event) {
    event.reply("You clicked the button!");
}

As you can see above, you can respond to ButtonEvents in the same way as to CommandEvents. Use event#editReply(boolean) to decide if you want to send a new message or edit the previous one. By default, this is set to true.

The @Button annotation has the following fields:

  • value (for to the label)
  • style (default ButtonStyle.PRIMARY)
  • emoji
  • link
  • ephemeral (identical to @SlashCommand)

Buttons will work for up to 15 mins, after that users cannot interact with the Button anymore. This is an arbitrary time period and might change in the future.

Using Buttons

To attach a button just refer the method name inside the event#withButtons(name) method.

@Interaction
public class ButtonExample {

    private int count;

    @SlashCommand(value = "hello", desc = "says hello")
    public void onCommand(CommandEvent event) {
        event.withButtons("clickMe").reply("Hello World!");
    }

    @Button(value = "Click Me!", style = ButtonStyle.PRIMARY)
    public void clickMe(ButtonEvent event) {
        count++;
        event.reply("You' ve clicked me %s time(s)", count);
    }
}

Notice that we can just store the count inside the class. This is due to the request-scoped instances that got introduced with release v4.0.0-alpha.1.

GIF 01-10-2023 16-05-05

event#withButtons will always enable the button. Use event#with(Buttons#disabled(name)) to attach a disabled button.

Localization

You can integrate Localization with jda-commands by passing a ResourceBundleLocalizationFunction to the start method of jda-commands:

JDACommands.start(jda, Main.class, ResourceBundleLocalizationFunction.fromBundles("Commands", DiscordLocale.GERMAN).build());

See the JDA example for details on how to use localization.

1) New Features

2) Changes

3) Bug Fixes

  • fixed a type adapting bug resulting in IndexOutOfBoundsException [#124]
  • fixed a bug where response request exceptions got omitted

4) Internal changes

  • generified ReplyContext in order to make it work with all type of events
  • generified getCommandExecutionFailedMessage in order to make it work with all type of events

You can find the complete changelog here.

Also, checkout the Wiki or the JavaDoc.

Maven

<repository>
    <id>jitpack.io</id>
    <url>https://jitpack.io</url>
</repository>
<dependency>
    <groupId>com.github.Kaktushose</groupId>
    <artifactId>jda-commands</artifactId>
    <version>v4.0.0-alpha.3</version>
</dependency>

Gradle

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}
dependencies {
    implementation 'com.github.Kaktushose:jda-commands:v4.0.0-alpha.3'
}

v4.0.0-alpha.2 | Improvements & Bug Fixes

31 May 21:33
Compare
Choose a tag to compare

Overview

This is a small followup release that brings in some bug fixes and smaller improvements.

1) New Features

N/A

2) Changes


Instead of:

event.getReplyContext().getBuilder().setFiles(myFile).setContent("My message");
event.getReplyContext().setConsumer((m) -> myFile.delete());
event.reply();

you can now do:

event.getReplyContext().getBuilder().setFiles(myFile).setContent("My message");
event.reply((m) -> myFile.delete());

  • slighlty adjusted the error message of the CooldownFilter:
    • changed color from red to orange
    • made time unit more human readable

image

3) Bug Fixes

  • reimplemented the CooldownFilter [#118]
  • fixed a bug that didn't reset the callback consumers of a reply, which resulted in deadlocks

4) Internal changes

N/A

You can find the complete changelog here.

Also, checkout the Wiki or the JavaDoc.

Maven

<repository>
    <id>jitpack.io</id>
    <url>https://jitpack.io</url>
</repository>
<dependency>
    <groupId>com.github.Kaktushose</groupId>
    <artifactId>jda-commands</artifactId>
    <version>v4.0.0-alpha.2</version>
</dependency>

Gradle

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}
dependencies {
    implementation 'com.github.Kaktushose:jda-commands:v4.0.0-alpha.2'
}

v4.0.0-alpha.1 | Slash Commands and Restructuring

26 Apr 20:24
Compare
Choose a tag to compare

Overview

This is the first alpha release of the upcoming version 4. As mentioned in the previous release, version 4 will discontinue support for text commands. Thus, in this release all text related components have been removed and many things have been restructured to fit interactions.

Writing Slash Commands

@Interaction
public class SlashCommandExample {

    @SlashCommand(value = "hello", desc = "say hello to the bot", isGuildOnly = true, isNSFW = false, ephemeral = true, enabledFor = Permission.ADMINISTRATOR)
    public void onPing(CommandEvent event) {
        event.reply("Hello human!");
    }
}

Some used fields are optional, but were added to this example to show the whole bandwidth of the new @SlashCommand annotation.

As you can see the core concepts of jda-commands haven't changed. Nevertheless, some changes were necessary, which will be explained in the following

Global and Guild scoped Commands

By default, all commands are registered globally. You can make a command guild scoped like this:

@Interaction
public class SlashCommandExample {

    @SlashCommand(value = "hello", desc = "say hello to the bot", scope = CommandScope.GUILD)
    public void onPing(CommandEvent event) {
        event.reply("Hello human!");
    }
}

Then you need to implement the GuildScopeProvider interface to tell jda-commands which guilds you wish your command to be registered for.

@Component
public class CustomGuildScopeProvider implements GuildScopeProvider {

    @Override
    public Set<Long> getGuildsForCommand(CommandData commandData) {
        return new HashSet<>() {{
            add(0123456789L);
        }};
    }
}

Permissions

The new permission system might be confusing, so here is a quick overview:

Bot side features (since version 2)

Mute

You can mute users which will reject any command interaction even before the execution chain has started. Use the PermissionsProvider interface for this.

Permissions (Bot side check)

Annotate commands with @Permission and use the PermissionsProvider interface to implement your own permissions system.

Discord side feature (since version 4)

Use the @SlashCommand(enabledFor) field to tell Discord which permission is needed to execute the command.

⚠ This can be overwritten by discord moderators and admins at any time. Do not rely on this permission check for critical commands like ban or eval.

1) New Features

Request-scoped Instances

For every command execution a new instance of the controller class is created. Subsequent executions of components are
executed in the same instance.
This allows you to store stateful objects, like the target of a ban command, inside the controller class.

ReplyContext

The MessageSender and ReplyCallback got replaced by the ReplyContext.

You can access the ReplyContext by calling event#getReplyContext. Then, you can edit flags like ephemeral, edit reply, remove components, etc., which is however also possible directly via the event object. The important change is that you can also access the MessageCreateBuilder that is used for constructing the reply, allowing you to do crazy things like attaching files.

The Reply API didn't changed fundamentally, however the method overloads for ephemeral replies got removed. Instead, you need to call event#setEphemeral() directly or use the @SlashCommand annotation.

Example

    @SlashCommand(value = "cat", desc = "sends a photo of lovely cat", ephemeral=true)
    public void onCommand(CommandEvent event) {
        event.getReplyContext().getBuilder().setFiles(lovelyCatFile);
        event.reply(); // no args call equals to calling event.getReplyContext().queue()
    }

@Param Annotation

The @Param annotation got introduced to supply the metadata of command options. The following fields are available:

  • value (description)
  • name

Parameter Name Auto Detection

jda-commands can now resolve the name of your parameters from the method signature. In order to enable this feature you need to compile your code with the -parameters flag

IntelliJ

Settings > Build, Execution, Deployment > Compiler > Java Compiler > Javac Options

image

Maven

<configuration>
    <compilerArgs>
        <arg>-parameters</arg>
    </compilerArgs>
</configuration>

Gradle

compileJava {
    options.compilerArgs += "-parameters"
}

JDAContext

Added the JDAContext as a bridge between JDA and ShardManager objects.

2) Changes

  • The following features got changed/removed because they are now natively supported by slash commands:

    • Optional parameter now longer needs to be at the end of a command

    • SyntaxErrorMessage got renamed to TypeAdaptingFailedMessage

    • Removed help commands and embeds

    • Removed @Conact annotation

    • Removed CommandList and MarkdownGenerator

    • Removed GuildSettings

    • Removed Repository, JsonRepository, GuildSettingsRepository

  • DependencyInjector can now resolve static fields

  • Added default mappings for primitive optionals

  • Added type adapters for all new channel types

Annotations

  • Renamed annotations:

    • @Controller -> @Interaction
    • @Command -> @SlashCommand
    • @Permission -> @Permissions
  • Renamed the following attributes from @SlashCommand (former @Command):

    • isDM -> isGuildOnly
    • label -> name
  • Removed the following attributes from @SlashCommand (former @Command):

    • help
    • category
    • usage
    • isSuper

3) Bug Fixes

  • Custom filters in the FilterRegistry are now registered correctly

4) Internal changes

  • Introduced CommandTree class, which generates a valid command tree respecting subcommand groups and subcommands

  • The CommandContext and CommandDispatcher got abstracted, similar to the CommandParser

  • Reimplementation of the GenericEvent class

  • Introduced the RuntimeSupervisor that takes care of the request-scoped instances

  • Removed CommandRouter


You can find the complete changelog here.

Also, checkout the Wiki or the JavaDoc.

Maven

<repository>
    <id>jitpack.io</id>
    <url>https://jitpack.io</url>
</repository>
<dependency>
    <groupId>com.github.Kaktushose</groupId>
    <artifactId>jda-commands</artifactId>
    <version>v4.0.0-alpha.1</version>
</dependency>

Gradle

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}
dependencies {
    implementation 'com.github.Kaktushose:jda-commands:v4.0.0-alpha.1'
}

3.0.0

20 Dec 15:03
Compare
Choose a tag to compare

Overview

This release marks a breaking point in the development of jda-commands.

The past work on version 2.3.0 (and respectively the first two alpha releases) tried to combine both systems: text input based commands and the new interaction based commands. Keeping backwards- and cross-compatibility was a desirable but ambitious goal from the very beginning. However, with JDA 5 adding more and more breaking changes and new interaction types like Modals, this task became nearly impossible. Thus, I've decided to split things up:

  • This and future v3 releases are based on jda-commands 2.2.0 and will only add longterm support for JDA 5. There will be no new features added.

  • At the same time I'll be working on v4, which will drop support for text commands and will only be based on interactions.

  • 2.3.0-alpha.2 will be left untouched in its current state.

1) New Features

N/A

2) Changes

  • Added type adapters for new channel types ( AudioChannel, GuildChannel, GuildMessageChannel, NewsChannel, StageChannel, ThreadChannel, VoiceChannel)

  • changed Message to MessageCreateData in the following interfaces or classes:

    • MessageSender and DefaultMessageSender
    • ErrorMessageFactory, DefaultErrorMessageFactory and JsonErrorMessageFactory
    • HelpMessageFactory, DefaultHelpMessageFactory and JsonHelpMessageFactory
    • CommandEvent
    • CommandContext
  • EmbedDTO#toMessage has been deprectated and replaced by EmbedDTO#toMessageCreateData()

3) Bug Fixes

N/A

4) Internal changes

N/A


You can find the complete changelog here.

Also checkout the Wiki or the JavaDoc.

Maven

<repository>
    <id>jitpack.io</id>
    <url>https://jitpack.io</url>
</repository>
<dependency>
    <groupId>com.github.Kaktushose</groupId>
    <artifactId>jda-commands</artifactId>
    <version>v3.0.0</version>
</dependency>

Gradle

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}
dependencies {
    implementation 'com.github.Kaktushose:jda-commands:v3.0.0'
}

2.3.0-alpha.2

04 Jul 09:59
Compare
Choose a tag to compare

Overview

This is a follow-up release bringing in some bug fixes and minor changes.

1) New Features

  • Parameter names will be automatically transformed into snake_case, e.g. int delDays -> del_days #67

  • You can now use EmbedDTO#injectFormat(Object...) to format all fields of an EmbedDTO #69

  • Added JDACommandsSlashBuilder#enableHelp(boolean). If set to false no help commands will be auto generated. Default value is true, which also represents the behavior prior to this update.

  • StateSection now has methods to clear or remove entries. Furthermore you can now define a time to live:

    StateSection section = new StateSection(1, TimeUnit.MINUTES);

2) Changes

  • The EmbedCache no automatically loads all embeds when the object gets created #58. Thus:

    • EmbedCache#loadEmbedsToCache() got deprecated

    • EmbedCache#loadEmbeds() got introduced as an alternative which has the same functionality

  • Deleting ephemeral messages will replace the message with deleted and will remove all embeds or components instead of throwing an exception #71

3) Bug Fixes

  • Illegal values for SlashCommandData will no longer result in a crash #68

  • fixed that String arguments weren't concatenated #72

  • The type adapters for Integer and Long can now also handle floating point numbers

  • The contextual prefix is now also used in error embeds

  • fixed that Buttons didn't always have the correct order in an ActionRow

4) Internal changes

N/A


You can find the complete changelog here.

JavaDoc for the new classes is currently not available but the wiki will be updated soon:tm:

Maven

<repository>
    <id>jitpack.io</id>
    <url>https://jitpack.io</url>
</repository>
<dependency>
    <groupId>com.github.Kaktushose</groupId>
    <artifactId>jda-commands</artifactId>
    <version>v2.3.0-alpha.2</version>
</dependency>

Gradle

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}
dependencies {
    implementation 'com.github.Kaktushose:jda-commands:v2.3.0-alpha.2'
}

2.3.0-alpha.1

01 Jul 15:01
Compare
Choose a tag to compare

Overview

This release updates jda-commands to JDA 5 and brings in first implementations for interactions. No breaking changes were made, this is completely backwards compatible to v2.2.0!

Please note that this is the first release and will still contain some bugs

Slash Commands

This release adds support for slash commands. They will work out of the box, which means that you don't have to change your command classes to make slash commands work.

Enabling Slash Commands

In order to get started with slash commands, you need to build jda-commands a little bit different.

JDACommands.slash(jda, Main.class).startGlobal();

This will register all CommandDefinitions as global commands. Registering guild commands looks similar:

JDACommands.slash(jda, Main.class).guilds(0123456789L).startGuild();

CommandRegistrationPolicy

By calling registrationPolicy(CommandRegistrationPolicy) you can define the operation mode of your bot. You can choose between text, slash, text and slash or migrating where the bot will inform the user that text commands aren't available anymore.

Replying

The bot will always acknowledge incoming interaction events first to prevent time outs when your response building takes longer.

The reply methods of the CommandEvent have been integrated to work with slash commands. So again, no changes needed. To send ephemeral replies there are two ways:

  • Pass it to the reply method:

    event.reply("test", true);
  • Set it as default

    @Command(value = "greet", ephemeral = true)
    public void greet(CommandEvent event) {
        event.reply("Hello");
    }

Parameters

Slash command parameters need a name and a description when being registered. To accomplish that a new annotation has been introduced.

@Command("greet")
public void greet(CommandEvent event, @Param(name = "member", value = "The member to greet") Member member) {
    event.reply("Hello %s", member.getAsMention());
}

The name can be omitted when you compile with the -parameters flag. This will make the method parameter name readable for jda-commands at runtime.

If you also omit the description "empty description" will be used by default.

Choices

Slash command parameters can also have a limited set of choices. This was also achieved by introducing a new annotation.

@Command("food")
public void chooseFood(CommandEvent event, @Choices({"Apples", "Burger", "Pizza"}) String food) {
    event.reply("You chose %s", food);
}

Buttons

Buttons are one of the new components Discord has introduced. They are arranged in so called ActionRows and can either be enabled or disabled.

Defining Buttons

Buttons are defined the same way as commands are:

@Button(label = "Click me!", style = ButtonStyle.DANGER)
public void onButton(ButtonEvent event) {
  event.reply("You clicked me!");
}

Adding Buttons to Messages

Buttons have ids, by default this id is equal to the method name. However you can use your own id by passing it to the @Button annotation.

Buttons can be added to messages by either calling event#with or event#withButtons with the id of the button you want to add. We will discuss the difference in a second. However, each call to a with method will create a new ActionRow.

Have a look at this first simple example:

@Button(label = "Click me!", style = ButtonStyle.DANGER)
public void onButton(ButtonEvent event) {
  event.reply("You clicked me!");
}

@Command("greet")
public void greet(CommandEvent event) {
    event.withButtons("onButton").reply("Hello!");
}

Sometimes we don't want a button to be active all the time. event#withButtons will always enable buttons but by calling event#with you can change this behavior.

@Command("leaderboard")
public void onLeaderboard(CommandEvent event) {
    event.with(Buttons.disabled("onLeft"), Buttons.enabled("onRight")).reply("Page 1");
}

Replying

You can reply to buttons exactly like you reply to commands. Alternatively you can edit the original message (the message the button is attached to) by calling event#edit.

Additional methods are event#clearComponents and event#editComponents.

1) New Features

  • Slash Command and Buttons support

  • @Param and @Choices annotation for parameters

  • compile with -parameters flag and jda-commands will automatically set the parameter name

  • the prefix in help messages will either be the actual prefix or / depending on the execution context

  • Automatically generated command usage in the format prefix command <args> (optional args)

  • new class JDAContext as a bridge between JDA and ShardManager

  • New type adapters for all channel types

  • StateSection as a simple key value storage

2) Changes

  • commands can no longer have empty labels

  • JDACommands#getJda and CommandDispatcher#getJda have been deprecated. Use #getJDAContext instead

  • removed JDACommands#getRouter and JDACommands#setRouter

  • removed CommandDispatcher#getRouter and CommandDispatcher#setRouter

3) Bug Fixes

  • fix Levenshtein distance calculation for multiple labels #52

4) Internal changes

  • added isSlash and OptionMapping to CommandContext

  • new class GenericEvent as a bridge between text and interaction events

  • new parser implementations for interactions

  • new data structure classes CommandTree and TreeNode to generate valid slash command paths

  • reply methods have been extracted to a ReplyAction and ReplyCallback interface with their respective implementations for text and interactions commands.

  • added toCommandData and toSubCommandData methods to CommandDefinition

  • new reflection class ButtonDefinition


You can find the complete changelog here.

JavaDoc for the new classes is currently not available but the wiki will be updated soon:tm:

Maven

<repository>
    <id>jitpack.io</id>
    <url>https://jitpack.io</url>
</repository>
<dependency>
    <groupId>com.github.Kaktushose</groupId>
    <artifactId>jda-commands</artifactId>
    <version>v2.3.0-alpha.1</version>
</dependency>

Gradle

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}
dependencies {
    implementation 'com.github.Kaktushose:jda-commands:v2.3.0-alpha.1'
}