Creating a Discord trivia bot in Java using Javacord
Write your own bot that helps you play trivia on your Discord server
Have you ever interacted with a bot on one of your messaging platforms and wondered how they work/are built? Well, wonder no more because in no time you will be making one in Java with the help of this awesome library called Javacord.
You can look at my github repo here
Why Javacord?
According to Javacord itself, it is “an easy to use multithreaded library for creating Discord bots in Java”. It describes the library perfectly, it is very simple to use and set up, even for people who have very limited experience with Java. Javacord reduces its functionality to standard Java classes which means that a developer does not need to deal with complex abstraction or learn a new framework syntax. Finally, like every other good library out there, it has great documentation and walks you through every kind of functionality you might need.
How do I set it up?
Before we get coding, we need a Discord application. Navigate to this link and follow the instructions here to set up your application https://discord.com/developers/applications
- Click the new application button on the top right of the page
2. Click the Bot section on the right tab and then the “Add Bot” button on the page
3. Fill out the information you would like to on this page
4. Finally click the reveal token and copy this; this is what we will use to interact with the Discord API
How do I get this project even started?
Okay in order to get started on this, we need to create a Gradle project. Gradle is basically a build automation tool which can be configured to run certain tasks like compilation, packaging, testing and deployment. It will help us set up our Javacord library as well as the Gson library (required while parsing through http json responses)
I’ll be using IntelliJ for this project and I’d suggest you do too so that it is easier to follow along. To set up a gradle Java project in IntelliJ,
- Go to: File -> New -> Project
- Select Gradle on the left bar
- Click Next and run through the screens to create a project
- Locate your
build.gradle
file and open it - Paste the following within your dependencies
implementation 'org.javacord:javacord:3.3.0'
implementation 'com.google.code.gson:gson:2.8.5'
Your file should look something like this:
(If you get an error that says the symbol could not be found, then go to file -> invalidate caches and restart)
Alright so we have our dependencies ready and now we can start writing our code. Let’s write a short script which replies when it sees a certain message in a channel, it can be done with the following code:
What is going on here?
I’ll break it down line by line, starting from the top, we have our imports for the classes that we will be using, particularly the DiscordApi
and the DiscordApiBuilder
classes.
Inside the main function, there is a line for storing our token from the Discord bot page that we got as a string. Then we create a new instance of the DiscordApi
class. This helps us communicate with Discord’s API for our bot.
Then we need add an event listener which listens for when a message is created with the string Hi and the bot needs to reply with a Hello. The addMessageCreateListener
class does just that, it allows us to get an event object and implement a lambda function with the ->
syntax. Lambda expressions take in a parameter and give an output, they are similar to other methods but don’t need a name.
Then using the event
object that was passed in as the parameter, we use getMessageContent()
to get the contents of the message, and use equalsIgnoreCase()
to ignore if the string is upper/lower case. This is one of the greatest plusses of Javacord, the methods and classes are well named and do exactly what you would expect them to.
Finally, in the final line, using the api
object that was created earlier, we can generate an invite link for the bot to our server using api.createBotInvite()
.
Okay time to run this and see it in action, when you run it you should see something like this on your console:
Copy the link that was printed to the console and go to the browser, add the bot to your server and try typing in Hi
Et voilà, you have created your very first Java bot, it was that simple.
There are a ton of other event listeners, which you can leverage to create a bunch of applications with your bot. Here’s a few that might be helpful for create other similar applications:
.addMessageDeleteListener
can be used to send a message when a message is deleted in a channel. Similar to a message create event, it also has It can be implemented with a lambda expression:
//adds a listener when a message is deleted on your serverapi.addMessageDeleteListener(event -> { event.getChannel().sendMessage(“What are you hiding there bud?”);});
Example:
Similar to the above one, the library also has a reaction listener which, based on a reaction, performs an action. Lastly, we can also create an embed message using the Javacord library. Let’s combine all of this to create some sort of a chatbot which uses deletion, creation, reaction and embeds:
Okay so we have dialed it up a notch and there is a lot going on here, so let’s break it down. Again, we use a token to create a DiscordApi instance, then have a message create listener, and a message delete listener. Then we create an embed, using the EmbedBuilder
class in which we can set a bunch of fields and other info. (We’ll be using embeds for our trivia bot).
Followed by the embed we have an add message listener which listens for “show me an embed” message and replies with an embed. Finally, we have a reaction listener which listens to someone’s reaction on a message, and when someone reacts with a thumbs down, it deletes that message.
Now that we have a basic understanding of event listeners and how to work with Javacord, we can finally get started on working on creating a trivia bot.
First and foremost, remembering good design, our Main.java
file was starting to get long, so we can beware while coding this longer bot and break the one long file that we might have into individual function and classes that follow the Single Responsibility Principle (SRP).
Let’s start by creating a Main.java
file, where we instantiate our Trivia
object which we will use for creating an http request to get our trivia questions. Inside the Trivia.java
we start by declaring a URL
object, then create a HttpURLConnection
and parse through the response to store values as class attributes. It can all be implemented like this:
Here, we define a URL object to our API which using the HttpConnection
object make our request out to the API. Then using a BufferedReader
, read in the API response line by line. A BufferedReader
is used to read text from a character input stream, buffering characters to provide efficient reading of characters.
Finally, we use the Gson
library by google to convert the returned string from API calls to a json object. And then parse through the nested array in the json object to store the question, category and correct answer
as class attributes.
There’s also a bunch of getters defined at the end of the file to help retrieve this information returned API from our initialized Trivia
objects.
Okay then now that we have the Trivia class done, we can focus on the Main.java
class to listen for a message and then give us a trivia question:
In the Main.java
file we first initialize our Trivia
object and the DiscordApi
object. Then using message create listeners we listen for someone to play trivia and reply with an embed created by another class. There is also a listener for someone’s reply, which uses the Trivia
object’s attributes for answer validation. So the final piece of this bot is to create an embed class:
public class EmbedHelper {
private final String question;
private final String category;
public EmbedHelper(String question, String category) {
this.question = question;
this.category = category;
}
public EmbedBuilder createEmbed() {
//create an embed
EmbedBuilder embed = new EmbedBuilder()
.setTitle("Question")
.setDescription(question)
.addField("How to reply", "Type \"Trivia Answer: \" followed by true or false")
.addField("Category", category)
.setColor(Color.BLUE);
return embed;
}
}
Pretty standard stuff here again, create a new class which needs a question and a category in the constructor and then using that data replies with an EmbedBuilder
object which the Main class uses to send an embed.
Okay, so how does it look?
Here is a working demo:
Conclusion
Javacord is an awesome library for creating discord bots for any purposes. It has a lot more to be explored, you can create servers, channels and even webhooks with it. It is also really easy to implement because the naming is solid. I highly suggest looking over their documentation here: https://docs.javacord.org/api/v/3.3.0/overview-summary.html
Finally, have fun creating bots for your servers!
References:
Link to my repository: