Releases: Kaktushose/jda-commands
v4.0.0-beta.2 | Static Interactions and QoL changes
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 totrue
jda-commands will ignore this producer method at indexing. This is useful if you wish to register your dependency providers manually by callingDependencyInjector#registerProvider(Object)
. -
Implemented a simple
KeyValueStore
that can be accessed from every event class by callingkv()
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 theGuildReadyEvent
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
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:
- PERMISSIONS (ensures that the PermissionsMiddleware is always executed first)
- HIGH
- NORMAL (default)
- 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 toContext#setCancelled(MessageCreateData)
. This ensures that there is always an error message to display. Thus,Context#setErrorMessage
got removed andContext#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 totrue
a new message was always sent
4) Internal changes
- Introduced
GenericComponentDefinition
to remove the type parameters forCommandEvent
undComponentEvent
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
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
andSelectMenuEvent
intoComponentEvent
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 theJDACommands
instance - Renamed
GenericContext
toContext
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
intoDispatcherSupervisor
and thus removed GenericParser and it's subtypes - Merged
ButtonDispatcher
andSelectMenuDispatcher
intoComponentDispatcher
- Renamed:
CommandDefinition
->SlashCommandDefinition
GenericContext
->Context
Context#getInteraction
->Context#getInteractionDefinition
ControllerDefinition
->InteractionControllerDefinition
EphemeralInteraction
->EphemeralInteractionDefinition
GenericInteraction
->GenericInteractionDefinition
- Made
GenericEvent
a subtype ofGenericInteractionCreateEvent
and removed method overload - Added static instance creation to the
RuntimeSupervisor
- Implemented a default implementation of the
reply
method inside theReplyable
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
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())
);
}
}
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
todispatching/interactions
- moved
components
todispatching/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 theReplyable
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
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.
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
-
you can now use
event#keepComponents(boolean)
to decide whether the reply should keep all components that are attached to the previous message. The default value istrue
-
event#removeComponents()
has been added to remove all components from the last message that was sent. This will only work witheditReply(boolean)
set totrue
2) Changes
- added
getUnknownInteractionMessage
toErrorMessageFactory
which replaces the previous placeholder response
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
Overview
This is a small followup release that brings in some bug fixes and smaller improvements.
1) New Features
N/A
2) Changes
- the
setConsumer(Consumer<Message>)
method has been split into two seperate methods: [#117]
- added a
reply(Consumer<Message>)
andreply(Consumer<Message>, Consumer<Throwable>
method [#114]
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
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
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
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
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
toMessageCreateData
in the following interfaces or classes:MessageSender
andDefaultMessageSender
ErrorMessageFactory
,DefaultErrorMessageFactory
andJsonErrorMessageFactory
HelpMessageFactory
,DefaultHelpMessageFactory
andJsonHelpMessageFactory
CommandEvent
CommandContext
-
EmbedDTO#toMessage
has been deprectated and replaced byEmbedDTO#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
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 tofalse
no help commands will be auto generated. Default value istrue
, 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
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
andCommandDispatcher#getJda
have been deprecated. Use#getJDAContext instead
-
removed
JDACommands#getRouter
andJDACommands#setRouter
-
removed
CommandDispatcher#getRouter
andCommandDispatcher#setRouter
3) Bug Fixes
- fix Levenshtein distance calculation for multiple labels #52
4) Internal changes
-
added
isSlash
andOptionMapping
toCommandContext
-
new class
GenericEvent
as a bridge between text and interaction events -
new parser implementations for interactions
-
new data structure classes
CommandTree
andTreeNode
to generate valid slash command paths -
reply methods have been extracted to a
ReplyAction
andReplyCallback
interface with their respective implementations for text and interactions commands. -
added
toCommandData
andtoSubCommandData
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'
}