π A fast, powerful and easy-to-use Javacord framework written in Kotlin.
Cordex is an innovative command framework designed to optimize the capabilities of Javacord, combining rich features and an intuitive syntax that simplifies the process of building Discord bots. It presents a developer-friendly solution for defining command arguments in a manner reminiscent of command-line interfaces (CLI).
Warning
Keep in mind that this library is in beta, and may not be ready for production purposes just yet.
In order to use Cordex, you'll need the following prerequisites:
- Java:
8 or later
- Kotlin:
1.9.0
- Coroutines:
1.7.3
- Javacord:
3.9.0
repositories {
...
maven("https://jitpack.io")
}
dependencies {
implementation("com.github.vyfor:Cordex:0.3.2")
}
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependency>
<groupId>com.github.vyfor</groupId>
<artifactId>Cordex</artifactId>
<version>0.3.2</version>
</dependency>
Initialize Cordex by setting your bot token. You can configure the created DiscordApiBuilder inside the api
block.
fun main() {
cordex("TOKEN") {
prefix { "~" }
api {
setAllIntents()
}
}
}
There are two ways of creating commands:
- Through inheritance:
- Define a custom command by extending the
Command
class and implementing its execute function.
class ExampleCommand : Command("example") { override suspend fun Arguments.execute(ctx: Context) { // Command logic goes here ctx.message.reply("This is an example command!") } }
- Define a custom command by extending the
- Through the DSL function:
- Define a custom command by using the
command()
function and providing necessary fields.
command("example") { execute { ctx -> ctx.message.reply("This is an example command!") } }
- Define a custom command by using the
Add your newly created command to the command registry using the following methods:
- A plus sign followed by an instance of your command class.
- The
load("package")
method to load classes extending theCommand
class.
cordex("TOKEN") {
//...
commands {
+ExampleCommand()
load("me.blast.commands")
}
}
Warning
Specifying a package name isn't mandatory, but highly recommended. Not doing so may negatively impact the startup overhead of the bot.
Cordex offers robust error handling capabilities to ensure your bot can gracefully manage unexpected situations.
Use onError
to define how your bot responds when an exception occurs during command execution.
cordex("TOKEN") {
onError { event, command, ex ->
// Error handling logic goes here
event.message.reply("Error!")
}
}
Cordex defaults to sending a usage message on argument parsing errors. However, you can customize this behavior with your own function using onParseError
:
cordex("TOKEN") {
onParseError { event, command, ex ->
// Error handling logic goes here
event.message.reply(
when (ex) {
is ArgumentException.Invalid -> "Invalid value provided for argument ${ex.argument.argumentName}"
is ArgumentException.Empty -> "No value provided for argument ${ex.argument.argumentName}"
is ArgumentException.Insufficient -> "Insufficient amount of values provided for argument ${ex.argument.argumentName}"
is ArgumentException.Missing -> "Missing required arguments: ${ex.arguments.joinToString(", ") { it.argumentName }}"
}
)
}
}
Cordex follows the approach of handling arguments in a way similar to how command-line interfaces (CLI) do.
There exist 3 types of arguments:
- Options
- Options are arguments capable of accepting values.
- Flags
- Flags are arguments that are optional, and providing them assigns their value as true.
- Positional arguments
- Positional arguments are arguments provided without explicit naming.
You can define each of these argument types using their respective functions:
class ExampleCommand : Command("example") {
val option by option("Description") // --option, -o <value>
val flag by flag("Description") // --flag, -f
val positional by positional("Description") // [--positional] <value>
}
Names are optional; Cordex obtains them from variable names, using the first letter as the short name.
Argument values can be accessed in different ways:
option.value
option()
option { it -> ... }
Arguments may be optional, hold default values, accept multiple values, and have validators:
val name by option().multiple(1..2) // List<String> (min: 1, max: 2)
val age by option().optional(18) { toInt() } // Int? (default: 18)
Validators also offer the capability to include custom error messages, achieved by throwing an exception with a message included.
Cordex provides a range of predefined validators you can utilize:
int()
uInt()
long()
uLong()
float()
double()
user()
role()
category()
message()
customEmoji()
snowflake()
textChannel()
voiceChannel()
threadChannel()
stageChannel()
forumChannel()
channel(types...)
url()
duration()
date()
dateTime()
color()
unicodeEmoji()
enum()
map()
Note
These methods combine multiple input values (from multi-value arguments) into a single string and try to convert the combined result to the appropriate type.
If you want each input value to be converted separately, use the same function with a plural name. e.g. users()
roles()
Cordex offers a feature known as command suggestions, allowing the bot to proactively suggest commands that closely match any incorrectly provided by the user.
To enable this functionality, simply include the following line of code:
cordex("TOKEN") {
enableCommandSuggestion(DistanceAccuracy)
}
Here, the parameter DistanceAccuracy
represents the level of precision in matching input string with defined commands.
You can create a paginator that goes through a given list using the List<T>.paginate
or List<T>.paginateDefault
function.
The paginateDefault
function provides the same pagination features but with default handlers attached.
The syntax is as follows:
List<T>.paginate(
channel = ctx.channel,
messageEvent = ctx.event,
itemsPerPage = 1,
onStart = { messageEvent, paginator, currentItems ->
MessageBuilder().setContent(currentItems.joinToString("\n"))
},
onPagination = { message, paginator, currentItems ->
MessageUpdater(message).setContent(currentItems.joinToString("\n"))
},
onEmpty = {
MessageBuilder().setContent("No items found")
},
removeAfter = 2.minutes,
canClose = true // Adds a button to close the paginator
)
Take a look at PaginationUtils.kt to see a complete example.
As the name suggests, command interceptors intercept a command's execution and run the given block of code. The block must return a boolean value, indicating whether to continue the execution or not.
cordex("TOKEN") {
intercept("refresh") { event, command ->
event.server.get().id == 0123456789L
}
}
Cordex relies on these amazing libraries:
-
https://github.com/Javacord/Javacord
An easy to use multithreaded library for creating Discord bots in Java.
-
https://github.com/felldo/JEmoji
Java Emoji (JEmoji) is a lightweight fast emoji library for Java with the purpose to improve and ease working with emojis
[ ] Slash command support
[ ] Attachment
argument type
[ ] Command categorization
[ ] Subcommands