Skip to content

Releases: discord-jda/JDA

v6.0.0-rc.2 | New Pin Pagination API

27 Jul 19:35
3f04b55
Compare
Choose a tag to compare
Pre-release

Overview

This release includes a minor breaking change to the retrievePinnedMessages method.

Originally, this method could only fetch up to 50 pinned messages. However, the underlying endpoint has been deprecated and replaced with a new paginated endpoint, as detailed in the Discord Changelog.

We have updated our API to utilize a PaginationAction. The callback response is now a list of PinnedMessage objects instead of a list of messages. Each PinnedMessage instance contains the timestamp when the message was pinned and the pinned message object. With this pagination action, the retrieval of pinned messages is no longer limited to 50 messages and can now fetch more, for instance by using takeAsync(200).

To replicate the previous behavior (retrieving only up to 50 pinned messages), you can use queue() as before, but you will need to map the list to a List<Message> as follows:

channel.retrievePinnedMessages()
  .map(list -> list.stream().map(PinnedMessage::getMessage).toList())
  .queue(list -> ...);

Changes

Full Changelog: v6.0.0-rc.1...v6.0.0-rc.2

Installation

Gradle

repositories {
    mavenCentral()
}
dependencies {
    implementation("net.dv8tion:JDA:6.0.0-rc.2")
}

Maven

<dependency>
    <groupId>net.dv8tion</groupId>
    <artifactId>JDA</artifactId>
    <version>6.0.0-rc.2</version> 
</dependency>

v6.0.0-rc.1 | New Components

20 Jul 14:51
8bc17a4
Compare
Choose a tag to compare
Pre-release

Overview

Warning

This is the first release candidate for JDA 6.0.0. The major version bump reflects several breaking changes to the message and modal component APIs. Additional breaking changes may still be introduced before the final stable release of 6.0.0.

This version introduces support for Components Version 2, a significant update to Discord's component system. To accommodate this new API, we’ve made a number of key changes to our component implementation:

  • All components are now immutable
    Previously, ActionRow allowed modification of its contained components. To simplify and modernize the API, this mutability has been removed.

  • New top-level component interfaces
    The LayoutComponent interface (previously only implemented by ActionRow) has been replaced by two new interfaces:
    - MessageTopLevelComponent
    - ModalTopLevelComponent
    This change reflects the increased flexibility introduced in Components V2, where top-level components are no longer restricted to layout containers like ActionRow. Components such as TextDisplay and FileDisplay can now appear directly at the top level.

  • Renamed getIdgetCustomId
    The original getId method has been renamed to getCustomId to avoid confusion with Discord's new getUniqueId, which is a numeric, auto-generated identifier.

  • Temporary removal of toData for components
    Some components now require attachments to function properly, complicating serialization. We’ve removed the toData method for now and are working on a new, more capable serialization API that will be introduced in a later update.

Big thanks to @freya022 and @DV8FromTheWorld for contributing on this giant feature!

Using Components V2

To use the new components introduced in this release, you must enable the Components V2 feature flag on your message request. This can be done using the useComponentsV2 method on MessageRequest.

Tip

Enabling this flag comes with certain limitations, so we strongly recommend reviewing the documentation for important details before integrating it into your project.

To get started, check out the new ComponentsV2Example to explore the possibilities of this updated API. You can also see it in action in a demo project by @DV8FromTheWorld: discord-pokedex.

pokemon-card

New Components

JDA 6 introduces several new component types as part of the Components V2 system:

  • Container
    Displays components inside a visually distinct box — similar to how embeds are styled.

  • Thumbnail
    Shows a small image next to text. Commonly used as an accessory within a Section component.

  • FileDisplay
    Displays a file attachment as a downloadable item. For visual file content (e.g., images), consider using MediaGallery instead.

  • MediaGallery
    Shows multiple images in a gallery layout — similar to a list of image attachments in Discord.

  • Section
    Displays a block of text content with optional accessories like thumbnails or buttons.

  • Separator
    Adds vertical spacing between components, helping visually organize content.

  • TextDisplay
    A simple text component used to display content without relying on the content field of a message.

Note

Components that use files, such as FileDisplay or MediaGallery, will automatically attach files as message attachments in your requests.

New Utilities For Components

Several new utilities have been added to simplify working with complex component structures — including traversal, replacement, and deserialization:

Migrating To 6.0.0

To help ease the upgrade to JDA 6.0.0, we've provided an OpenRewrite recipe that can automatically refactor parts of your codebase. This will update imports and replace a few method calls with their new equivalents in JDA 6.0.0.

However, not all breaking changes can be handled automatically — for example, code that relied on the mutability of ActionRow will require manual adjustments.

The OpenRewrite Recipe

Before applying the recipe, make sure you’re using version control (e.g., Git) or back up your project manually. You’ll also need to be using Gradle or Maven to apply the migration.

Gradle

We are using the OpenRewrite Gradle Plugin. Before changing your JDA version in gradle, you can add the rewrite plugin and use the recipe to migrate your code:

plugins {
    id("org.openrewrite.rewrite") version "7.11.0"
}

repositories {
    mavenCentral()
}

dependencies {
    // Your current JDA version before upgrading to 6.0.0
    implementation("net.dv8tion:JDA:5.+")

    // The current 6.0.0 release version
    rewrite("net.dv8tion:JDA:6.0.0-rc.1")
    rewrite("org.openrewrite.recipe:rewrite-java-dependencies:1.37.0")
}

rewrite {
    activeRecipe("net.dv8tion.MigrateComponentsV2")
}

Once you configured this plugin, you can use the rewriteDryRun task to generate a git patch in build/reports/rewrite/rewrite.patch to see what the plugin will do with your source code. To apply the changes, either use this patch or use rewriteRun.

After migrating your code, you can then update your JDA version (if the rewrite hasn't done it already) and remove the plugin again.

Maven

We are using the OpenRewrite Maven Plugin. Before changing your JDA version in your pom, you can add the rewrite plugin and use the recipe to migrate your code:

<plugin>
  <groupId>org.openrewrite.maven</groupId>
  <artifactId>rewrite-maven-plugin</artifactId>
  <version>6.13.0</version>
  <configuration>
    <activeRecipes>
      <recipe>net.dv8tion.MigrateComponentsV2</recipe>
    </activeRecipes>
  </configuration>
  <dependencies>
    <dependency>
      <groupId>org.openrewrite.recipe</groupId>
      <artifactId>rewrite-java-dependencies</artifactId>
      <version>1.37.0</version>
    </dependency>
    <dependency>
      <groupId>net.dv8tion</groupId>
      <artifactId>JDA</artifactId>
      <version>6.0.0-rc.1</version>
    </dependency>
  </dependencies>
</plugin>

Once you configured this plugin, you can use the rewrite:dryRun task to generate a git patch in target/site/rewrite/rewrite.patch to see what the plugin will do with your source code. To apply the changes, either use this patch or use rewrite:run.

After migrating your code, you can then update your JDA version (if the rewrite hasn't done it already) and remove the plugin again.

The ComponentReplacer

If you previously used LayoutComponent.updateComponents or changed an action row with the mutable getComponents(), you will have to migrate your code to the new ComponentReplacer instead.

Before:

List<LayoutComponent> components = message.getComponents();

LayoutComponent.updateComponent(
    components,
    "my-component-id",
    Button.primary("button-id", "Click me").asDisabled()
);

After:

MessageComponentTree components = message.getComponentTree();
...
Read more

v5.6.1

08 Jun 18:44
f8e78d6
Compare
Choose a tag to compare

Bug Fixes

Full Changelog: v5.6.0...v5.6.1

Installation

Gradle

repositories {
    mavenCentral()
}
dependencies {
    implementation("net.dv8tion:JDA:5.6.1")
}

Maven

<dependency>
    <groupId>net.dv8tion</groupId>
    <artifactId>JDA</artifactId>
    <version>5.6.1</version> 
</dependency>

v5.6.0 | ApplicationManager and minor improvements

07 Jun 21:09
8e687c8
Compare
Choose a tag to compare

Overview

This release introduces the ApplicationManager, which can be used to update the application's description and other settings through JDA.

New Features

Changes

  • Add with_components=true query param to WebhookClient requests by @Xirado in #2850
  • Set thread ID when manipulating message objects made by webhooks by @freya022 in #2849

Bug Fixes

Full Changelog: v5.5.1...v5.6.0

Installation

Gradle

repositories {
    mavenCentral()
}
dependencies {
    implementation("net.dv8tion:JDA:5.6.0")
}

Maven

<dependency>
    <groupId>net.dv8tion</groupId>
    <artifactId>JDA</artifactId>
    <version>5.6.0</version> 
</dependency>

v5.5.1 | Bug fixes and performance improvements

03 May 11:31
99d1f98
Compare
Choose a tag to compare

Overview

This is a small release, including a bug fix for editCommand and editCommandById, as well as some performance improvements for looking up members by roles.

Additionally, you can now create threads with a custom slowmode.

New Features

Bug Fixes

Full Changelog: v5.5.0...v5.5.1

Installation

Gradle

repositories {
    mavenCentral()
}
dependencies {
    implementation("net.dv8tion:JDA:5.5.1")
}

Maven

<dependency>
    <groupId>net.dv8tion</groupId>
    <artifactId>JDA</artifactId>
    <version>5.5.1</version> 
</dependency>

v5.5.0 | Improved voice state cache and file proxies

27 Apr 14:01
b919401
Compare
Choose a tag to compare

Changes to voice state cache (#2835)

Voice states are now cached independently of guild members. JDA can now detect when a member connects or disconnects from an audio channel, even when the member is not currently cached.

With this change, you can technically use MemberCachePolicy.NONE and will still receive voice join / leave events, as long as CacheFlag.VOICE_STATE is enabled.

To reduce the memory footprint, we now only cache voice states if the member is connected to an audio channel. While disconnected, we will not keep the voice state cached, meaning we lose track of muted/deafend state and return an "empty" voice state for Member#getVoiceState.

Improvements to FileProxy (#2782 and #2727)

The FileProxy, ImageProxy, and AttachmentProxy now all support downloadAsFileUpload to easily stream a Discord proxies URL to a message.

@Override
public void onMessageReceived(MessageReceivedEvent event) {
    List<Message.Attachment> attachments = event.getMessage().getAttachments();

    List<FileUpload> uploads = attachments.stream()
        .map(attachment ->
            attachment
                .getProxy()
                .downloadAsFileUpload(attachment.getWidth(), attachment.getHeight()))
        .collect(Collectors.toList());
    
    event.getChannel().sendFiles(uploads).queue();
}

New Features

Changes

Bug Fixes

Full Changelog: v5.4.0...v5.5.0

Installation

Gradle

repositories {
    mavenCentral()
}
dependencies {
    implementation("net.dv8tion:JDA:5.5.0")
}

Maven

<dependency>
    <groupId>net.dv8tion</groupId>
    <artifactId>JDA</artifactId>
    <version>5.5.0</version> 
</dependency>

v5.4.0 | Interaction callback response and security incidents

20 Apr 14:42
2b972ab
Compare
Choose a tag to compare

Access the created or updated message from interaction replies (#2798)

You can now use InteractionHook#getCallbackResponse to access the messages created by interaction replies.

@Override
public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
  event.reply("React with your favorite emoji")
    .map(hook -> hook.getCallbackResponse().getMessage())
    .flatMap(message -> message.addReaction(emoji))
    .queue();
}

Previously, this could be done using an additional retrieveOriginal request. To reduce requests and improve responsiveness, we recommend preferring this new getter instead.

Guild security incidents (#2577)

With guild security incidents, you can now be aware when Discord detects raids or spam in direct messages in a guild. These detections are available with Guild#getSecurityIncidentDetections and are updated with GuildUpdateSecurityIncidentDetectionsEvent.

Additionally, you can modify the security incident actions to temporarily pause invites or disable direct messages in your guild. See Guild#modifySecurityIncidents for details.

guild.modifySecurityIncidents(SecurityIncidentActions.enabled(
        // Pause invites for 2 hours
        OffsetDateTime.now().plusHours(2),
        // Disable direct messages for 1 hour
        OffsetDateTime.now().plusHours(1)
)).queue();

// Or disable security incident actions prematurely
guild.modifySecurityIncidents(SecurityIncidentActions.disabled()).queue();

New Features

Changes

  • Add missing exceptions when attempting to move entities before selecting by @freya022 in #2797

Bug Fixes

  • Prevent firing voice state update events if member is not cached by @freya022 in #2773
  • Fix FileProxy#withClient return types by @freya022 in #2698

Full Changelog: v5.3.2...v5.4.0

Installation

Gradle

repositories {
    mavenCentral()
}
dependencies {
    implementation("net.dv8tion:JDA:5.4.0")
}

Maven

<dependency>
    <groupId>net.dv8tion</groupId>
    <artifactId>JDA</artifactId>
    <version>5.4.0</version> 
</dependency>

v5.3.2 | Bug fix for PrivateChannel#getName

05 Apr 10:00
1932a7f
Compare
Choose a tag to compare

Overview

Small bug fix release.

Bug Fixes

Full Changelog: v5.3.1...v5.3.2

Installation

Gradle

repositories {
    mavenCentral()
}
dependencies {
    implementation("net.dv8tion:JDA:5.3.2")
}

Maven

<dependency>
    <groupId>net.dv8tion</groupId>
    <artifactId>JDA</artifactId>
    <version>5.3.2</version> 
</dependency>

v5.3.1 | Bug fixes

27 Mar 17:41
5805666
Compare
Choose a tag to compare

Overview

Small bug fix release due to API changes regarding user-installed applications.

Bug Fixes

Full Changelog: v5.3.0...v5.3.1

Installation

Gradle

repositories {
    mavenCentral()
}
dependencies {
    implementation("net.dv8tion:JDA:5.3.1")
}

Maven

<dependency>
    <groupId>net.dv8tion</groupId>
    <artifactId>JDA</artifactId>
    <version>5.3.1</version> 
</dependency>

v5.3.0 | User-Installable Apps

02 Feb 15:02
4d372fd
Compare
Choose a tag to compare

Overview

After many months of waiting, this release finally adds support for user-installable apps. This will allow you to make use of interactions (and especially commands) anywhere on Discord, by installing the application on a user directly instead of a guild.

Creating User-Installable Apps

To create a user-installable app, you first have to enable the feature in your application dashboard in the installation settings:

firefox_X9eJoKZ88K

Once enabled, you can create user-installable commands, by changing the integration types:

Commands.slash("say", "Makes the bot say what you tell it to")
// Allow the command to be used anywhere (Bot DMs, Guild, Friend DMs, Group DMs)
  .setContexts(InteractionContextType.ALL) 
// Allow the command to be installed on users instead of guilds
  .setIntegrationTypes(IntegrationType.USER_INSTALL) 
  .addOption(STRING, "content", "What the bot should say", true)

Installing to a User

To actually install your app to a user, you can use the generator provided by discord. In the OAuth2 URL Generator, change the integration type to User Install:

firefox_VGe9NK4Xld

The generated link, can now be used to install your application to the authorizing user.

image

Detached Guilds / Roles / Channels / Members

This comes with a few changes to expectations around JDA functionality. Since interactions can now come from anywhere on Discord, some features aren't available in certain contexts.

Some entities can now appear as Detachable Entity, which essentially means that they come from a guild or private channel, that your bot is not directly involved in.

For instance, if a command is installed on a user and that command is used in a guild, your bot is not necessarily a member of that guild. Since the bot is not a member, it only has access to the guild context, that the interaction event provides. Many features such as channels, roles, or members are not accessible without being an actual member of the guild. If you try to use or access anything that isn't accessible, JDA will throw a new DetachedEntityException.

New Features

Full Changelog: v5.2.3...v5.3.0

Installation

Gradle

repositories {
    mavenCentral()
}
dependencies {
    implementation("net.dv8tion:JDA:5.3.0")
}

Maven

<dependency>
    <groupId>net.dv8tion</groupId>
    <artifactId>JDA</artifactId>
    <version>5.3.0</version> 
</dependency>