JDA
Java wrapper for the popular chat & VOIP service: Discord https://discord.com
Install / Use
/learn @discord-jda/JDAREADME
JDA (Java Discord API)
This open source library is intended for implementing bots on Discord using the real-time gateway and REST API. It provides event based functionality to implement bots of any kind, allowing for effective and scalable applications.
📖 Overview
The core concepts of JDA have been developed to make building scalable apps easy:
- Event System
Providing simplified events from the gateway API, to respond to any platform events in real-time without much hassle. - Rest Actions
Easy to use and scalable implementation of REST API functionality, letting you choose between callbacks with combinators, futures, and blocking. The library also handles rate-limits imposed by Discord automatically, while still offering ways to replace the default implementation. - Customizable Cache
Trading memory usage for better performance where necessary, with sane default presets to choose from and customize.
You can learn more by visiting our wiki or referencing our Javadocs.
🔬 Installation
This library is available on maven central. The latest version is always shown in the GitHub Release.
The minimum java version supported by JDA is Java SE 8. JDA also uses JSR 305 to support solid interoperability with Kotlin out of the box.
[!NOTE] To use JDA for audio connections, you must also add a dependency that implements the DAVE Protocol. See Making a Music Bot for details.
Gradle
repositories {
mavenCentral()
}
dependencies {
implementation("net.dv8tion:JDA:$version") { // replace $version with the latest version
// Optionally disable audio natives to reduce jar size by excluding `opus-java` and `tink`
// Gradle DSL:
// exclude module: 'opus-java' // required for encoding audio into opus, not needed if audio is already provided in opus encoding
// exclude module: 'tink' // required for encrypting and decrypting audio
// Kotlin DSL:
// exclude(module="opus-java") // required for encoding audio into opus, not needed if audio is already provided in opus encoding
// exclude(module="tink") // required for encrypting and decrypting audio
}
}
Maven
<dependency>
<groupId>net.dv8tion</groupId>
<artifactId>JDA</artifactId>
<version>$version</version> <!-- replace $version with the latest version -->
<!-- Optionally disable audio natives to reduce jar size by excluding `opus-java` and `tink` -->
<exclusions>
<!-- required for encoding audio into opus, not needed if audio is already provided in opus encoding
<exclusion>
<groupId>club.minnced</groupId>
<artifactId>opus-java</artifactId>
</exclusion> -->
<!-- required for encrypting and decrypting audio
<exclusion>
<groupId>com.google.crypto.tink</groupId>
<artifactId>tink</artifactId>
</exclusion> -->
</exclusions>
</dependency>
🤖 Creating a Bot
To use this library, you have to create an Application in the Discord Application Dashboard and grab your bot token. You can find a step-by-step guide for this in our wiki page Creating a Discord Bot.
🏃♂️ Getting Started
We provide a number of examples to introduce you to JDA. You can also take a look at our official Wiki, Documentation, and FAQ.
Every bot implemented by JDA starts out using the JDABuilder or DefaultShardManagerBuilder. Both builders provide a set of default presets for cache usage and events it wants to receive:
createDefault- Enables cache for users who are active in voice channels and all cache flagscreateLight- Disables all user cache and cache flagscreate- Enables member chunking, caches all users, and enables all cache flags
We recommend reading the guide on caching and intents to get a feel for configuring your bot properly. Here are some possible use-cases:
Example: Message Logging
[!NOTE] The following example makes use of the privileged intent
GatewayIntent.MESSAGE_CONTENT, which must be explicitly enabled in your application dashboard. You can find out more about intents in our wiki guide.
Simply logging messages to the console. Making use of JDABuilder, the intended entry point for smaller bots that don't intend to grow to thousands of guilds.
Starting your bot and attaching an event listener, using the right intents:
public static void main(String[] args) {
JDABuilder.createLight(token, EnumSet.of(GatewayIntent.GUILD_MESSAGES, GatewayIntent.MESSAGE_CONTENT))
.addEventListeners(new MessageReceiveListener())
.build();
}
Your event listener could look like this:
public class MessageReceiveListener extends ListenerAdapter {
@Override
public void onMessageReceived(MessageReceivedEvent event) {
System.out.printf("[%s] %#s: %s\n",
event.getChannel(),
event.getAuthor(),
event.getMessage().getContentDisplay());
}
}
You can find a more thorough example with the MessageLoggerExample class.
Example: Slash Command Bot
This is a bot that makes use of interactions to respond to user commands. Unlike the message logging bot, this bot can work without any enabled intents, since interactions are always available.
public static void main(String[] args) {
JDA jda = JDABuilder.createLight(token, Collections.emptyList())
.addEventListeners(new SlashCommandListener())
.build();
// Register your commands to make them visible globally on Discord:
CommandListUpdateAction commands = jda.updateCommands();
// Add all your commands on this action instance
commands.addCommands(
Commands.slash("say", "Makes the bot say what you tell it to")
.addOption(STRING, "content", "What the bot should say", true), // Accepting a user input
Commands.slash("leave", "Makes the bot leave the server")
.setContexts(InteractionContextType.GUILD) // this doesn't make sense in DMs
.setDefaultPermissions(DefaultMemberPermissions.DISABLED) // only admins should be able to use this command.
);
// Then finally send your commands to discord using the API
commands.queue();
}
An event listener that responds to commands could look like this:
public class SlashCommandListener extends ListenerAdapter {
@Override
public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
switch (event.getName()) {
case "say" -> {
String content = event.getOption("content", OptionMapping::getAsString);
event.reply(content).queue();
}
case "leave" -> {
event.reply("I'm leaving the server now!")
.setEphemeral(true) // this message is only visible to the command user
.flatMap(m -> event.getGuild().leave()) // append a follow-up action using flatMap
.queue(); // enqueue both actions to run in sequence (send message -> leave guild)
}
}
}
}
You can find a more thorough example with the SlashBotExample class.
🚀 RestAction
In this library, the RestAction interface is used as a request builder for all API endpoints. This interface represents a lazy request builder, as shown in this simple example:
channel.sendMessage("Hello Friend!")
.addFiles(FileUpload.fromData(greetImage)) // Chain builder methods to configure the request
.queue() // Send the request asynchronously
[!IMPORTANT] The final call t

