How is it started?
A few months ago, I started to create a discord bot for task management which is built for big communities.
It is painful for developers to set up an event handler system for component interaction events, specially for developers who care about their code quality.
Therefore, I wrote a discord bot framework in Kotlin, a new solution for creating a cool discord bot.
It is still in an experimental stage, things might be broken when updating to a newer version.
Why BJDA?
BJDA is based on JDA (Java Discord API).
It provides those things:
- A better way for creating and listening to Slash Commands
- A UI module for creating powerful high-quality UI
- Dynamically updating for messages, and state management similar to React.js
With those cool features, you can create a cool bot easier!
Actually, for Kotlin, we have Kord which is also in an experimental stage. BJDA will also be moved to Kord soon
Getting Started
Install
<dependency>
<groupId>io.github.sonmoosans</groupId>
<artifactId>bjda</artifactId>
<version>4.3.1</version>
</dependency>
Now, we can create a Todo discord bot.
First of all, you need to get a JDA instance
fun main() {
val jda = JDABuilder.createDefault("token here")
.build()
.awaitReady()
}
Then install modules with BJDA by doing BJDA.create(jda)
fun main() {
val jda = JDABuilder.createDefault("token here")
.build()
.awaitReady()
BJDA.create(jda)
.install(
SuperCommandModule( //slash commands
TodoCommands,
),
UIEventModule() //ui event handlers
)
}
Notes: SuperCommand means Slash Command.
UIEventModule should always be installed if your bot uses UI listeners provided by BJDA.
After that, we are going to create the TodoCommands
variable
val TodoCommands = SuperCommandGroup.create("todo", "Todo Commands",
CreateTodo()
)
and create the /todo create
command
val users = UIStore<User>()
private class CreateTodo: SuperCommand(name = "create", description = "Create a Todo List") {
override val run: CommandHandler = {
val ui = users.getUI(event.user) {
UI(
TodoApp {}
)
}
ui.reply(event) {
ui.listen(it)
}
}
}
UIStore
is util for storing UI instances, similar to HashMap<*, UI>
.
The run
function is fired when the Slash command is executed.
users.getUI(event.user)
will return a UI instance or default value.
Notice that ui.listen(it)
means that it supports real-time updating. When the ui is updated, all messages will be edited.
After declaring the command, we can start designing our UI!
Imports:
import bjda.plugins.ui.hook.ButtonClick.Companion.onClick
import bjda.plugins.ui.hook.MenuSelect.Companion.onSelect
import bjda.plugins.ui.modal.Form.Companion.form
import bjda.ui.component.RowLayout
import bjda.ui.component.Text
import bjda.ui.component.TextType
import bjda.ui.component.action.Button
import bjda.ui.component.action.Menu
import bjda.ui.component.action.TextField
import bjda.ui.core.*
import bjda.ui.core.FComponent.Companion.component
import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle
import net.dv8tion.jda.api.interactions.components.selections.SelectOption
import net.dv8tion.jda.api.interactions.components.text.TextInputStyle
State
Same as React, you can define a prop
and state
.
In this example, we are not going to define a prop for it.
data class State(
val todos: ArrayList<String> = ArrayList()
)
Next, we can create our component:
val TodoApp = component {
val state = useState(State())
val addForm by form {
title = "Add Todo"
onSubmit = { event ->
state.update(event) {
todos += event.value("todo")
}
}
render = {
+ row (
TextField("todo") {
label = "TODO"
style = TextInputStyle.PARAGRAPH
}
)
}
}
val onAddItem by onClick { event ->
event.replyModal(addForm).queue()
};
{
val (todos) = state.get()
+ Text()..{
content = "**TODO List**"
type = TextType.LINE
}
+ on (todos.isEmpty()) {
Text()..{
content = "No Todos"
type = TextType.CODE_BLOCK
}
}
//Elements Collections will be converted to Fragment
+ todos.mapIndexed { i, todo ->
TodoItem(i, todo)
}
+ RowLayout() -{
+ Button(onAddItem) {
label = "Add"
}
}
}
}
In the above code, we did:
- Modal to Add a todo
- a Button to Open the Modal
- Code blocks to list all the todos
You can try to understand those codes by running the application and modifying the example.
Test your bot
Now run the main function and start testing!
Try to run the /todo create
command, you should see a panel.
Click the "Add" button and add some todos.
Keep improving
You can add a button to close the panel. Therefore, you can destroy the UI and remove it from UIStore users
, to avoid memory leaks.
Now, you just created a cool todo bot with BJDA!
You can take a look at the Github repo: https://github.com/SonMooSans/bjda
Top comments (0)