MCPcopy Index your code
hub / github.com/Discord4J/Discord4J

github.com/Discord4J/Discord4J @3.3.2

Chat with this repo
repository ↗ · DeepWiki ↗ · release 3.3.2 ↗ · + Follow
8,065 symbols 25,518 edges 949 files 3,740 documented · 46% updated 4d ago3.3.2 · 2026-04-02★ 1,91824 open issues
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Discord4J

Support Server Invite Maven Central Javadocs GitHub Workflow Status (branch)

Discord4J is a fast, powerful, unopinionated, reactive library to enable quick and easy development of Discord bots for Java, Kotlin, and other JVM languages using the official Discord Bot API.

🏃 Quick Example

In this example for v3.3, whenever a user sends a !ping message the bot will immediately respond with Pong!.

Make sure your bot has the Message Content intent enabled in your developer portal.

public class ExampleBot {

    public static void main(String[] args) {
        String token = args[0];
        DiscordClient client = DiscordClient.create(token);
        GatewayDiscordClient gateway = client.login().block();

        gateway.on(MessageCreateEvent.class).subscribe(event -> {
            Message message = event.getMessage();
            if ("!ping".equals(message.getContent())) {
                MessageChannel channel = message.getChannel().block();
                channel.createMessage("Pong!").block();
            }
        });

        gateway.onDisconnect().block();
    }
}

For a full project example, check out our example projects repository here.

🔗 Quick Links

💎 Benefits

  • 🚀 Reactive - Discord4J follows the reactive-streams protocol to ensure Discord bots run smoothly and efficiently regardless of size.

  • 📜 Official - Automatic rate limiting, automatic reconnection strategies, and consistent naming conventions are among the many features Discord4J offers to ensure your Discord bots run up to Discord's specifications and to provide the least amount of surprises when interacting with our library.

  • 🛠️ Modular - Discord4J breaks itself into modules to allow advanced users to interact with our API at lower levels to build minimal and fast runtimes or even add their own abstractions.

  • ⚔️ Powerful - Discord4J can be used to develop any bot, big or small. We offer many tools for developing large-scale bots from custom distribution frameworks, off-heap caching, and its interaction with Reactor allows complete integration with frameworks such as Spring and Micronaut.

  • 🏫 Community - We pride ourselves on our inclusive community and are willing to help whenever challenges arise; or if you just want to chat! We offer help ranging from Discord4J specific problems, to general programming and web development help, and even Reactor-specific questions. Be sure to visit us on our Discord server!

📦 Installation

Gradle

repositories {
    mavenCentral()
}

dependencies {
    implementation 'com.discord4j:discord4j-core:3.3.0'
}

Gradle Kotlin DSL

repositories {
    mavenCentral()
}

dependencies {
    implementation("com.discord4j:discord4j-core:3.3.0")
}

Maven


<dependencies>
    <dependency>
        <groupId>com.discord4j</groupId>
        <artifactId>discord4j-core</artifactId>
        <version>3.3.0</version>
    </dependency>
</dependencies>

SBT

libraryDependencies ++= Seq(
  "com.discord4j" % "discord4j-core" % "3.3.0"
)

🔀 Discord4J Versions

Discord4J 3.3.x includes simpler and more powerful APIs to build requests, a new entity cache and performance improvements from dependency upgrades. Check our Migration Guide for more details.

Discord4J Support Gateway/API Intents Interactions
v3.3.x Current v10 Mandatory, non-privileged default Fully supported
v3.2.x Maintenance only v8 Mandatory, non-privileged default Fully supported
v3.1.x Unsupported v6 Optional, no intent default Maintenance only

See our docs for more details about compatibility.

🎉 Sponsors

We would like to give special thanks to all of our sponsors for providing us the funding to continue developing and hosting repository resources as well as driving forward initiatives for community programs. In particular, we would like to give a special shoutout to these wonderful individuals:

⛰️ Large Bots

Here are some real-world examples of large bots using Discord4J:

  • Groovy - Was the second-largest bot on Discord, serving music to over 4 million servers before its shutdown in August 2021.
  • ZeroTwo - An anime multi-purpose bot used in over 1 million servers.
  • DisCal - Implements Google Calendar into Discord as seamlessly and comprehensively as possible; serving over 21k servers.
  • Shadbot - A configurable multipurpose bot with music, gambling mini-games, video game stats, and more; serving nearly 12K servers before its shutdown in August 2021.
  • See-Bot - A Fortnite focused bot with stat tracking, player lookup, mission alerts, and much more; in over 10k servers.

Do you own a large bot using Discord4J? Ask an admin in our Discord or submit a pull request to add your bot to the list!

⚛️ Reactive

Discord4J uses Project Reactor as the foundation for our asynchronous framework. Reactor provides a simple yet extremely powerful API that enables users to reduce resources and increase performance.

public class ExampleBot {

    public static void main(String[] args) {
        String token = args[0];
        DiscordClient client = DiscordClient.create(token);

        client.login().flatMapMany(gateway -> gateway.on(MessageCreateEvent.class))
            .map(MessageCreateEvent::getMessage)
            .filter(message -> "!ping".equals(message.getContent()))
            .flatMap(Message::getChannel)
            .flatMap(channel -> channel.createMessage("Pong!"))
            .blockLast();
    }
}

Discord4J also provides several methods to aid in better reactive chain compositions, such as GatewayDiscordClient#withGateway and EventDispatcher#on with an error handling overload.

public class ExampleBot {

    public static void main(String[] args) {
        String token = args[0];
        DiscordClient client = DiscordClient.create(token);

        client.withGateway(gateway -> {
            Publisher<?> pingPong = gateway.on(MessageCreateEvent.class, event ->
                Mono.just(event.getMessage())
                    .filter(message -> "!ping".equals(message.getContent()))
                    .flatMap(Message::getChannel)
                    .flatMap(channel -> channel.createMessage("Pong!")));

            Publisher<?> onDisconnect = gateway.onDisconnect()
                .doOnTerminate(() -> System.out.println("Disconnected!"));

            return Mono.when(pingPong, onDisconnect);
        }).block();
    }
}

🧵 Kotlin

By utilizing Reactor, Discord4J has native integration with Kotlin coroutines when paired with the kotlinx-coroutines-reactor library.

val token = args[0]
val client = DiscordClient.create(token)

client.withGateway {
    mono {
        it.on(MessageCreateEvent::class.java)
            .asFlow()
            .collect {
                val message = it.message
                if (message.content == "!ping") {
                    val channel = message.channel.awaitSingle()
                    channel.createMessage("Pong!").awaitSingle()
                }
            }
    }
}
    .block()

🐛 Common mistakes

Calling Message#getContent without enabling the Message Content intent

Starting from September 1, 2022, Discord requires bots to enable the "MESSAGE_CONTENT" intent to access the content of messages. To enable the intent, go to the Discord Developer Portal and select your bot. Then, go to the "Bot" tab and enable the "Message Content" intent. Then, add the intent to your bot when creating the DiscordClient:

GatewayDiscordClient client = DiscordClient.create(token)
    .gateway()
    .setEnabledIntents(IntentSet.nonPrivileged().or(IntentSet.of(Intent.MESSAGE_CONTENT)))
    .login()
    .block();

📚 Examples

📑 Message Embeds

message-embed

// IMAGE_URL = https://cdn.betterttv.net/emote/55028cd2135896936880fdd7/3x
// ANY_URL = https://www.youtube.com/watch?v=5zwY50-necw
MessageChannel channel = ...
EmbedCreateSpec.Builder builder = EmbedCreateSpec.builder();
builder.author("setAuthor", ANY_URL, IMAGE_URL);
builder.image(IMAGE_URL);
builder.title("setTitle/setUrl");
builder.url(ANY_URL);
builder.description("setDescription\n" +
      "big D: is setImage\n" +
      "small D: is setThumbnail\n" +
      "<-- setColor");
builder.addField("addField", "inline = true", true);
builder.addField("addFIeld", "inline = true", true);
builder.addField("addFile", "inline = false", false);
builder.thumbnail(IMAGE_URL);
builder.footer("setFooter --> setTimestamp", IMAGE_URL);
builder.timestamp(Instant.now());
channel.createMessage(builder.build()).block();

🏷️ Find Members by Role Name

Users typically prefer working with names instead of IDs. This example will demonstrate how to search for all members that have a role with a specific name.

Guild guild = ...
Set<Member> roleMembers = new HashSet<>();

for (Member member : guild.getMembers().toIterable()) {
  for (Role role : member.getRoles().toIterable()) {
    if ("Developers".equalsIgnoreCase(role.getName())) {
      roleMembers.add(member);
      break;
    }
  }
}

return roleMembers;

Alternatively, using Reactor:

Guild guild = ...
return guild.getMembers()
  .filterWhen(member -> member.getRoles()
    .map(Role::getName)
    .any("Developers"::equalsIgnoreCase));

🎵 Voice and Music

Discord4J provides full support for voice connections and the ability to send audio to other users connected to the same channel. Discord4J can accept any Opus audio source with LavaPlayer being the preferred solution for downloading and encoding audio from YouTube, SoundCloud, and other providers.

[!WARNING]
The original LavaPlayer is no longer maintained. A new maintained version can be found here. If you need Java 8 support, you can use Walkyst's LavaPlayer fork, but it is also no longer maintained!

To get started, you will first need to instantiate and configure an, conventionally global, AudioPlayerManager.

public static final AudioPlayerManager PLAYER_MANAGER;

static {
  PLAYER_MANAGER = new DefaultAudioPlayerManager();
  // This is an optimization strategy that Discord4J can utilize to minimize allocations
  PLAYER_MANAGER.getConfiguration().setFrameBufferFactory(NonAllocatingAudioFrameBuffer::new);
  AudioSourceManagers.registerRemoteSources(PLAYER_MANAGER);
  AudioSourceManagers.registerLocalSource(PLAYER_MANAGER);
}

Next, we need to allow Discord4J to read from an AudioPlayer to an AudioProvider.

```ja

Extension points exported contracts — how you extend this code

EntityRetriever (Interface)
Abstraction for entity retrieval. [8 implementers]
core/src/main/java/discord4j/core/retriever/EntityRetriever.java
VoiceSendTaskFactory (Interface)
A factory to create a task that reads audio packets from an AudioProvider, encodes them and then sends them thro [44 implementers]
voice/src/main/java/discord4j/voice/VoiceSendTaskFactory.java
GatewayDataUpdater (Interface)
Defines methods to handle update operations in response to events received from the Discord gateway. [6 implementers]
common/src/main/java/discord4j/common/store/api/layout/GatewayDataUpdater.java
RateLimitStrategy (Interface)
A mapper between a HttpClientResponse and a Duration representing a delay due to rate limiting. [8 implementers]
rest/src/main/java/discord4j/rest/request/RateLimitStrategy.java
PayloadWriter (Interface)
Strategy for encoding a GatewayPayload and writing its contents to a Publisher of ByteBuf. [6 implementers]
gateway/src/main/java/discord4j/gateway/payload/PayloadWriter.java
DiscordOAuth2ResponseHandler (Interface)
An I/O handler to customize the response given by a DiscordOAuth2Server after a login process is completed. [4 implementers]
oauth2/src/main/java/discord4j/oauth2/DiscordOAuth2ResponseHandler.java
Spec (Interface)
A contract specifying how an object should be built. @param the type of the resulting object. [35 implementers]
core/src/main/java/discord4j/core/spec/Spec.java
VoiceConnectionFactory (Interface)
A factory to create VoiceConnection instances using a set of VoiceGatewayOptions. [44 implementers]
voice/src/main/java/discord4j/voice/VoiceConnectionFactory.java

Core symbols most depended-on inside this repo

map
called by 1160
common/src/main/java/discord4j/common/store/api/ActionMapper.java
build
called by 403
core/src/main/java/discord4j/core/event/EventDispatcher.java
asLong
called by 367
core/src/main/java/discord4j/core/object/command/ApplicationCommandOptionChoice.java
asLong
called by 356
common/src/main/java/discord4j/common/util/Snowflake.java
of
called by 352
core/src/main/java/discord4j/core/spec/EmbedCreateFields.java
empty
called by 322
common/src/main/java/discord4j/common/store/api/ActionMapper.java
builder
called by 287
core/src/main/java/discord4j/core/event/EventDispatcher.java
id
called by 256
common/src/main/java/discord4j/common/store/impl/EmptyUser.java

Shape

Method 6,946
Class 865
Interface 164
Enum 90

Languages

Java100%

Modules by API surface

core/src/main/java/discord4j/core/object/entity/Guild.java158 symbols
common/src/main/java/discord4j/common/store/impl/LocalStoreLayout.java136 symbols
common/src/main/java/discord4j/common/store/legacy/LegacyStoreLayout.java113 symbols
core/src/main/java/discord4j/core/event/ReactiveEventAdapter.java106 symbols
common/src/test/java/discord4j/common/TestStoreLayout.java101 symbols
core/src/main/java/discord4j/core/object/Embed.java74 symbols
core/src/main/java/discord4j/core/object/entity/Message.java70 symbols
core/src/main/java/discord4j/core/GatewayDiscordClient.java63 symbols
rest/src/main/java/discord4j/rest/entity/RestGuild.java60 symbols
common/src/main/java/discord4j/common/store/api/layout/DataAccessor.java57 symbols
common/src/main/java/discord4j/common/store/action/read/ReadActions.java57 symbols
rest/src/main/java/discord4j/rest/service/GuildService.java55 symbols

For agents

$ claude mcp add Discord4J \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page