-
-
Notifications
You must be signed in to change notification settings - Fork 89
Add a new command
This tutorial shows how to add custom commands to the bot.
-
Setup project locally
- you can run the bot locally from your IDE and connect it to a server
- the basic architecture of the code
- how the command system works
- how to add your own custom command
- basics of JDA, used to communicate with Discord
- basics of jOOQ, used to interact with databases
- basics of SLF4J, used for logging
Before we get started, we have to familiarize with the general code structure.
The entry point of the bot is Application
, which will first create instances of:
-
Config
, which provides several properties read from a configuration file -
Database
, a general purpose database used by the bot and its commands -
JDA
, the main instance of the framework used to communicate with Discord
The Config
is available to everyone from everywhere, it is a global singleton. You can just write Config.getInstance()
and then use its properties. The Database
is available to all commands, also for your custom command. You can read and write any data to it. From within a command, the JDA
instance will also be available at any time. Almost all JDA objects, such as the events, provide a getJDA()
method.
Next, the application will setup the command system.
The command system is based around the class CommandSystem
, which is registered as command handler to JDA
. It receives all command events from JDA and forwards them to the corresponding registered commands.
Custom commands are added to the Commands
class, where CommandSystem
will fetch them by using its createSlashCommands
method, also providing the database instance. This method could for example look like:
public static Collection<SlashCommand> createSlashCommands(Database database) {
return List.of(new PingCommand(), new DatabaseCommand(database));
}
As an example, when someone uses the /ping
command, the event will be send to CommandSystem
by JDA, which will then forward it to the PingCommand
class.
Commands have to implement the SlashCommand
interface. Besides metadata (e.g. a name) and the command setup provided by getData()
, it mostly demands implementation of the event action handlers:
onSlashCommand
onButtonClick
onSelectionMenu
It is also possible to extend SlashCommandAdapter
which already implemented all methods besides onSlashCommand
.
Therefore, a minimal example command, could look like:
public final class PingCommand extends SlashCommandAdapter {
public PingCommand() {
super("ping", "Bot responds with 'Pong!'", SlashCommandVisibility.GUILD);
}
@Override
public void onSlashCommand(@NotNull SlashCommandEvent event) {
event.reply("Pong!").queue();
}
}
In the following, we will add two custom commands to the application:
-
/days <from> <to>
- computes the difference in days between the given dates
- e.g.
/days 26.09.2021 03.10.2021
will respond with7 days
-
/question ask <id> <question>
,/question get <id>
- asks a question and users can click a
Yes
orNo
button - the choice will be saved in the database from which it can be retrieved using the
get
subcommand - e.g.
/question ask "noodles" "Do you like noodles?"
and/question get "noodles"
- asks a question and users can click a
Please refer to
- Add days command,
- Add question command and
- Adding context commands respectively.