BotCommands
BotCommands copied to clipboard
A JDA command framework (& much more) which helps to develop your bots faster
BotCommands
A Kotlin-first (and Java) framework that makes creating Discord bots a piece of cake, using the JDA library.
Features
The framework being built around events and dependency injection, your project can take advantage of that and avoid passing objects around, while also easily being able to use services provided by the framework.
Commands
- Automatic registration of commands, resolvers, services, etc... with full dependency injection
- Text commands (annotated or manually declared), either with:
- Automatic token parsing into your parameters
- Suppose the prefix is
!
and the command isban
@JDATextCommandVariation(name = "ban") fun onTextBan(event: BaseCommandEvent, @TextOption user: User, @TextOption timeframe: Long, @TextOption unit: TimeUnit, // A resolver is used here @TextOption reason: String) { //Ban the user }
- Which can be used as:
!ban @freya02 7 days Get banned
- Suppose the prefix is
- Manual token consumption
- Automatic token parsing into your parameters
- Application commands (annotated or DSL-declared)
- Slash commands with automatic & customizable argument parsing
- Supports choices, min/max values/length, channel types and autocomplete
- Options can be grouped into objects
- Context menu commands (User / Message)
- Automatic, smart application commands registration
- Slash commands with automatic & customizable argument parsing
Components and modals
- Unlimited data storage for components, with persistent and ephemeral storage
- Both modals and persistent components have a way to pass data
Event handlers
- Custom (annotated) event handlers, with priorities and async
Localization
- Entirely localizable, from the command declaration to the bot responses
Dependency injection
- Loads everything and passes objects automatically
- Can create custom conditions to disable services/commands at startup
- Can be replaced with Spring IoC
Utilities
- A PostgreSQL (and H2) database abstraction, with logged queries
- An event waiter with (multiple) preconditions, timeouts and consumers for every completion state
- Message parsers (tokenizers, see
RichTextParser
) and emoji resolvers (turning:joy:
into 😂) - Paginators and menus of different types (using components!)
And way more features!
Getting Started
You are strongly recommended to have some experience with Kotlin (or Java), OOP, JDA and Dependency Injection basics before you start using this library.
Prerequisites
- An OpenJDK 17+ installation
- A competent IDE (I recommend IntelliJ IDEA, you can't go wrong with it in Java & Kotlin, + Live Templates)
- (Recommended, only Java) Enable method parameters names, please refer to the wiki page
- (Recommended) Use HotswapAgent in development, to avoid restarting too often
- (Recommended) Use stacktrace-decoroutinator, to get clearer stack traces in suspending code
Head over to the wiki to get started.
Getting the library
Maven
<dependencies>
<dependency>
<groupId>io.github.freya022</groupId>
<artifactId>BotCommands</artifactId>
<version>VERSION</version>
</dependency>
</dependencies>
Gradle
repositories {
mavenCentral()
}
dependencies {
implementation 'io.github.freya022:BotCommands:VERSION'
}
Alternatively, you can use Jitpack to use snapshot versions, you can refer to the JDA wiki for more information.
Sample usage
Here is how you would create a slash command that sends a message in a specified channel.
Kotlin
@Command
@RequiresComponents // Disables the command if components are not enabled
class SlashSay(private val buttons: Buttons) : ApplicationCommand() {
@JDASlashCommand(name = "say", description = "Sends a message in a channel")
suspend fun onSlashSay(
event: GuildSlashEvent,
@SlashOption(description = "Channel to send the message in") channel: TextChannel,
@SlashOption(description = "What to say") content: String
) {
event.reply_("Done!", ephemeral = true)
.deleteDelayed(event.hook, 5.seconds)
.queue()
channel.sendMessage(content)
.addActionRow(buttons.danger(EmojiUtils.resolveJDAEmoji("wastebasket")).ephemeral {
bindTo { buttonEvent ->
buttonEvent.deferEdit().queue()
buttonEvent.hook.deleteOriginal().await()
}
})
.await()
}
}
Kotlin (DSL)
@Command
@RequiresComponents // Disables the command if components are not enabled
class SlashSay(private val buttons: Buttons) : GlobalApplicationCommandProvider {
suspend fun onSlashSay(event: GuildSlashEvent, channel: TextChannel, content: String) {
event.reply_("Done!", ephemeral = true)
.deleteDelayed(event.hook, 5.seconds)
.queue()
channel.sendMessage(content)
.addActionRow(buttons.danger(EmojiUtils.resolveJDAEmoji("wastebasket")).ephemeral {
bindTo { buttonEvent ->
buttonEvent.deferEdit().queue()
buttonEvent.hook.deleteOriginal().await()
}
})
.await()
}
override fun declareGlobalApplicationCommands(manager: GlobalApplicationCommandManager) {
manager.slashCommand("say", function = ::onSlashSay) {
description = "Sends a message in a channel"
option("channel") {
description = "Channel to send the message in"
}
option("content") {
description = "What to say"
}
}
}
}
Java
@Command
@RequiresComponents // Disables the command if components are not enabled
public class SlashSay extends ApplicationCommand {
private final Buttons buttons;
public SlashSay(Buttons buttons) {
this.buttons = buttons;
}
@JDASlashCommand(name = "say", description = "Sends a message in a channel")
public void onSlashSay(
GuildSlashEvent event,
@SlashOption(description = "Channel to send the message in") TextChannel channel,
@SlashOption(description = "What to say") String content
) {
event.reply("Done!")
.setEphemeral(true)
.delay(Duration.ofSeconds(5))
.flatMap(InteractionHook::deleteOriginal)
.queue();
final Button deleteButton = buttons.danger(EmojiUtils.resolveJDAEmoji("wastebasket")).ephemeral()
.bindTo(buttonEvent -> {
buttonEvent.deferEdit().queue();
buttonEvent.getHook().deleteOriginal().queue();
})
.build();
channel.sendMessage(content)
.addActionRow(deleteButton)
.queue();
}
}
Examples
You can find a number of feature demonstrations in the examples.
Debugging tips
- Enable the debug/trace logs in your logback.xml file, for a logging tutorial you can look at the wiki's logging page
- Look at the switches in
BDebugConfig
Live templates
IntelliJ IDEA users can use live templates provided in this zip file, helping you make commands and other handlers with predefined templates, for both Kotlin and Java, keeping a consistent naming scheme and acting as a cheatsheet.
For example, if you type slashCommand
in your class, this will generate a slash command
and guide you through the declaration.
A list of live template can be found in Settings > Editor > Live Templates
,
in the BotCommands 3.X - [Language]
group.
For an installation guide, you can follow this guide from JetBrains.
Support
Don't hesitate to join the support server if you have any question!
Contributing
If you want to contribute, make sure to base your branch on 3.X
, and create your PR from it.
It would be appreciated to focus on improving the documentation,
such as the wiki, the library documentation, or by creating examples.
Maintainers will focus on bug reports and feature requests, which you can create issues for.
Read the contributing guide for more details.