Releases: freya022/BotCommands
v3.1.0 | Checkboxes, radio groups and checkbox groups
Updated to JDA 6.4.0 and added support for checkboxes, radio groups and checkbox groups.
Checkboxes, checkbox groups and radio groups (#253)
This adds support for reading values in modal handlers, and Kotlin extensions + DSL builders for the new modals components.
Values of those new components can now be read as:
Checkbox->BooleanCheckboxGroup->List<String>,Stringfor single values (can benull)RadioGroup->String(can benull)
Example command
private const val MODAL_NAME = "SlashModal: modal"
private const val CHECKBOX_ID = "checkbox-id"
private const val RADIO_GROUP_ID = "radio_group-id"
private const val CHECKBOX_GROUP_ID = "checkbox_group-id"
@Command
class SlashModal(private val modals: Modals) {
@JDASlashCommand(name = "modal", description = "Test new modal features!")
fun onSlashModal(event: GuildSlashEvent) {
val modal = modals.create("Modal") {
label("I like checking boxes") {
child = Checkbox(CHECKBOX_ID, isDefault = true)
}
label("Which Discord client do you use?") {
child = RadioGroup(RADIO_GROUP_ID) {
option("Discord (Stable)", "stable", "The vanilla option", default = true)
option("Discord PTB", "ptb", "A peek into the future")
option("Discord Canary", "canary", "Living on the edge")
}
}
label("Which modal components do you use?") {
child = CheckboxGroup(CHECKBOX_GROUP_ID) {
option("Text Inputs", "textinputs")
option("Select Menus", "selectmenus")
option("File Uploads", "fileuploads")
option("Checkbox groups", "checkboxgroups", default = true)
}
}
bindTo(MODAL_NAME)
}
event.replyModal(modal).queue()
}
@ModalHandler(MODAL_NAME)
fun onModal(
event: ModalEvent,
@ModalInput(CHECKBOX_ID) doTheyLikeCheckingBoxes: Boolean,
@ModalInput(RADIO_GROUP_ID) client: String,
@ModalInput(CHECKBOX_GROUP_ID) features: List<String>,
) {
event.reply("""
Do you like checking boxes? $doTheyLikeCheckingBoxes
On what client? $client
Using what features? $features
""".trimIndent())
.setEphemeral(true)
.queue()
}
}JDA PR: discord-jda/JDA#3010
New feature
jda-ktx
- Added
RestActionReasonContextandwithRestActionReasonContext- Coroutine support for JDA's
ThreadLocalReason
- Coroutine support for JDA's
Don't hesitate to check out the examples and the wiki.
Full Changelog: v3.0.0...v3.1.0
Installation
As a reminder, the minimum Java version supported is Java 17.
Kotlin Gradle
repositories {
mavenCentral()
}
dependencies {
implementation("io.github.freya022:BotCommands:3.1.0")
}Maven
<dependency>
<groupId>io.github.freya022</groupId>
<artifactId>BotCommands</artifactId>
<version>3.1.0</version>
</dependency>v3.0.0
It's finally here, after almost 4 years and nearly 2500 commits.
This is quite different from BC v2, so there is no clear migration guide, but I would recommend looking at the setup wiki along with dependency injection.
For those running on v3 pre-release builds, you can upgrade to 3.0.0-beta.10, then do a full build to catch all the deprecations before upgrading.
Don't hesitate to check out the examples and the wiki.
Full Changelog: v3.0.0-beta.10...v3.0.0
Installation
As a reminder, the minimum Java version supported is Java 17.
Kotlin Gradle
repositories {
mavenCentral()
}
dependencies {
implementation("io.github.freya022:BotCommands:3.0.0")
}Maven
<dependency>
<groupId>io.github.freya022</groupId>
<artifactId>BotCommands</artifactId>
<version>3.0.0</version>
</dependency>v3.0.0-beta.10 | Hot restarting module
Overview
This release adds hot restarting and a few fixes. The wiki has also been greatly updated, feedback is welcome.
Added hot restarting (#232)
This new development-only module restarts your app automatically upon build, while keeping the same JVM, leading to much faster restarts, as it doesn't need to recompile most of the code.
Look at the README for more details.
Deprecations
Localization
getDiscordLocaleof all locale providers (UserLocaleProvider,GuildLocaleProvider,TextCommandLocaleProvider) were deprecated- You must implement
getLocaleinstead
- You must implement
Event waiter
BConfig#ignoredEventIntentswas deprecated- This has been replaced by
EventWaiterBuilder#ignoreMissingIntents
- This has been replaced by
Changes
- Updated to JDA 6.3.2
- Updated to Jackson 2.21.1
Fixes
Database
- Fixed schema not being reset-ed correctly when returning to the connection pool in some cases
Don't hesitate to check out the examples and the wiki.
Full Changelog: v3.0.0-beta.9...v3.0.0-beta.10
Installation
As a reminder, the minimum Java version supported is Java 17.
Kotlin Gradle
repositories {
mavenCentral()
}
dependencies {
implementation("io.github.freya022:BotCommands:3.0.0-beta.10")
}Maven
<dependency>
<groupId>io.github.freya022</groupId>
<artifactId>BotCommands</artifactId>
<version>3.0.0-beta.10</version>
</dependency>v3.0.0-beta.9
Important
JDA is no longer included as a transitive dependency, you will need to include it in your project.
Preparation for configuration of modules (#254)
In newer 3.X modules, and for most, if not all features in 4.X, each feature/module added by the user will contain their own configuration.
Each configuration is registered on the main configuration, Kotlin users are able to use an extension.
Registering the module's configuration means enabling the feature.
Changes
- Added methods to get/add configurations:
getConfigOrNull(on the built root configuration)registerModule(on the root configuration builder)
Added shutdown functions (#255)
Changes
- Added
isDaemontonamedDefaultScope - Added new statuses
- Added shutdown functions
- Added functions to await shutdown
- Added shutdown hooks, enabled by default
Migration from DiscordLocale to Locale in localization (#260)
As mapping Locale between DiscordLocale is not perfect, and the underlying localization is using Locale, getting messages should be using Locale. Implicit convertions should be avoided, so methods using DiscordLocale are deprecated.
If you wish to continue using DiscordLocale, you will have to use toLocale().
Commands are still localized using DiscordLocale, any feature that is limited to the locales Discord supports, should use DiscordLocale.
Warning
Breaking changes
AppLocalizationContext.userLocalenow returnsLocaleTextLocalizationContext.guildLocalenow returnsLocaleLocalizationContext.effectiveLocalenow returnsLocale
Deprecations
getDiscordLocalewas deprecated in all locale providers (UserLocaleProvider,GuildLocaleProvider,TextCommandLocaleProvider)- Deprecated all reply/edit methods accepting
DiscordLocale
Additions
- Added new overloads accepting
Locale
Warning
Breaking changes
Components
- Exceptions changed when awaiting on a component:
ComponentTimeoutExceptionis thrown when the timeout is reached while awaitingRemovedComponentExceptionis thrown when a component is removed while awaiting
Modals
- Exceptions changed when awaiting on a modal:
ModalTimeoutExceptionis thrown when the timeout is reached while awaiting
Misc
- Removed dependency on
kotlinx.datetime- All
kotlinx.datetimeimports were replaced bykotlin.time
- All
New features
Typesafe messages
- Added more
createoverloads inIMessageSourceFactory- To create message sources from message events (text commands) and arbitrary locales
Kotlin extensions
- Added
TimeFormat.atInstantwithkotlin.time.Instant
Deprecations
Application commands
- Deprecated configuration property
slashGuildIds, renamed asguildsToUpdate
Localization
LocalizationContext factories are deprecated and were replaced by a builder (LocalizationContext.builder)
Changes
Dependencies
- Updated to Kotlin 2.3.10
Modals
- You can now have
@ModalInputrefer to an input absent from the submitted modal, if the parameter is nullable or optional Stringparameters (from string selects) andMessage.Attachmentparameters (from file uploads) are now supported in modal handlersModal#await()now throwsModalTimeoutExceptioninstead ofTimeoutCancellationException
Components
await()now throwsComponentTimeoutExceptioninstead ofTimeoutCancellationExceptionawait()throwsRemovedComponentExceptionwhen the component is removed while it is awaited
Method accessors
BotCommands#preferClassFileAccessorswas moved toMethodAccessorsConfig
Localization
- Locales are evaluated lazily
Fixes
Components
- Fixed checking PostgreSQL driver version
Application commands
- Fixed global commands sometimes unnecessarily updating when using database-backed cache
Don't hesitate to check out the examples and the wiki.
Full Changelog: v3.0.0-beta.8...v3.0.0-beta.9
Installation
As a reminder, the minimum Java version supported is Java 17.
Kotlin Gradle
repositories {
mavenCentral()
}
dependencies {
implementation("io.github.freya022:BotCommands:3.0.0-beta.9")
}Maven
<dependency>
<groupId>io.github.freya022</groupId>
<artifactId>BotCommands</artifactId>
<version>3.0.0-beta.9</version>
</dependency>v3.0.0-beta.8 | Safe localization module, command improvements and fixes
Overview
Added a safer localization module, removed superclass requirements of annotated commands and fixed stuff.
New module with much safer localization (#237)
A new incubating module has been added to enable you more pre-emptive checks for your localization needs!
It allows you to define interfaces to retrieve your messages, meaning cleaner commands, less chance to misspell something, and much, much earlier error messages if something isn't configured correctly.
See the README for more details.
Split and deprecate ApplicationCommand and TextCommand (#252)
This removes the requirement of extending ApplicationCommand/TextCommand by splitting them in optional interfaces for each feature.
Deprecations
- Deprecated
ApplicationCommandandTextCommand
Changes
- Split
ApplicationCommandinto optional interfacesSlashOptionChoiceProviderApplicationGeneratedValueSupplierProvider
- Split
TextCommandinto optional interfacesTextCommandHelpConsumerTextGeneratedValueSupplierProvider
New features
Introspection
- Added
method,declaringKClassanddeclaringClasstoExecutable
Event listeners
- Added support for lists and lazy services in event listener parameters
Misc
- Added support for Kotlin 2.3.0
- Haven't updated to it yet because of some (rare) reflection bugs
Deprecations
Text commands
- Deprecated and split
HelpBuilderConsumer#acceptinto two methodsacceptGlobalacceptCommand
Changes
Dependencies
- Updated to JDA 6.3.0
- Updated to Caffeine 3.2.3
- Updated to ClassGraph 4.8.184
- Updated to JEmoji 1.7.5
- Updated to Spring Boot 3.5.8 and Spring Framework 6.2.14
- It will likely not get updated to Spring Boot 4, however, this library is compatible with it, you can upgrade it on your project with no issue
Built-in DI
@Dependencies,@ConditionalServiceand custom@Conditionannotations are now searched on supplied services- Supplied services are those added at runtime, will not affect anyone
Annotated commands
- Removed exception thrown when both
@TopLevelSlashCommandDataand@SlashCommandDatahad a description (on a top-level command)@TopLevelSlashCommandDatawill get prioritized instead
Interactions
- Events of external components and modals are now logged on the
DEBUGlevel
Interaction filters
- Filters that do not acknowledge the interaction are now logged on the
WARNlevel
Fixes
Annotated application commands
- Fixed
@DeclarationFilterbeing applied incorrectly
Built-in DI
- Fixed initialization exceptions not interrupting program startup when using ClassFile-based method accessors
Misc
- Fixed building message with pre-CV2 content when the Components V2 flag is enabled by default
Don't hesitate to check out the examples and the wiki.
Full Changelog: v3.0.0-beta.7...v3.0.0-beta.8
Installation
As a reminder, the minimum Java version supported is Java 17.
Kotlin Gradle
repositories {
mavenCentral()
}
dependencies {
implementation("io.github.freya022:BotCommands:3.0.0-beta.8")
}Maven
<dependency>
<groupId>io.github.freya022</groupId>
<artifactId>BotCommands</artifactId>
<version>3.0.0-beta.8</version>
</dependency>v3.0.0-beta.7 | Modal file uploads
Overview
This release primarily adds support for file uploads in modals.
Creating a Modal accepting file uploads
Kotlin
modals.create("modal-id") {
label("Banner image") {
child = AttachmentUpload("banner-file")
}
}Java
modals.create("modal-id")
.addComponents(Label.of("Banner Image", AttachmentUpload.of("banner-file")))
.build()Using the uploaded file
If you use @ModalHandler, you can add a @ModalInput parameter with a List<Message.Attachment> type.
@ModalHandler(name = "modal-id")
fun onModal(event: ModalEvent, @ModalInput("banner-file") bannerAttachments: List<Message.Attachment>) { ... }If you use coroutines, you can use modalEvent[attachmentUpload] instead.
val bannerFileComponent = AttachmentUpload("banner-file")
val modal = modals.create("modal-id") {
label("Banner image") {
child = bannerFileComponent
}
}
// Reply with the modal
val event = modal.await()
val bannerFile = event[bannerFileComponent].asAttachmentList.single()Changes
Dependencies
- Updated to JDA 6.1.0
- Updated to Kotlin 2.2.20
jda-ktx
- Added
customIdto[Type]SelectMenuandTextInputDSLs
Fixes
jda-ktx
- Fixed
LabelDSL not checking if a label was set
Don't hesitate to check out the examples and the wiki.
Full Changelog: v3.0.0-beta.6...v3.0.0-beta.7
Installation
As a reminder, the minimum Java version supported is Java 17.
Kotlin Gradle
repositories {
mavenCentral()
}
dependencies {
implementation("io.github.freya022:BotCommands:3.0.0-beta.7")
}Maven
<dependency>
<groupId>io.github.freya022</groupId>
<artifactId>BotCommands</artifactId>
<version>3.0.0-beta.7</version>
</dependency>v3.0.0-beta.6 | Components V2 and new modal components
Overview
This release updates to JDA 6 and adds support for Components V2 as well as new modal components such as text displays, labels and select menus.
Components V2 (#233)
Please refer to the JDA 6.0.0-rc.1 release for details on this feature.
Deprecations
UsedComponentSet#setComponents(Iterable)was deprecated- Replaced by
setComponents(ComponentTree)
- Replaced by
New features
- Added
deleteTreein services which can create components (Buttons/SelectMenus)
Kotlin extensions
Several factory functions were added:
ActionRowContainerFileDisplayMediaGalleryMediaGalleryItemSectionSeparatorTextDisplayThumbnail
Additionally, functions were added in inline builders to directly insert components where they can:
actionRowlinkButton
containerfileDisplaymediaGalleryitem
sectionseparatortext
For example,
val message = MessageCreate {
components += Container { /* */ }
}can also be written as
val message = MessageCreate {
container { /* */ }
}Note: These functions are available only in components which accept multiple child components (ActionRow, Container, Section content), for fields such as the accessory of Section, you will need to set the component manually.
Labels and string select menus in modals (#242)
Alongside with the new JDA additions, instead of having "input names" to match with your handler's @ModalInput, you can now use the native custom ID, note that it must be unique per modal.
Adding a text input, a label or a string select menu, now only uses the native JDA components.
See the JDA 6.0.0-rc.4 release for more details.
Example changes:
@Command
public class SlashFormat extends ApplicationCommand {
private static final String MODAL_NAME = "SlashFormat: formatModal";
- private static final String CODE_INPUT_NAME = "SlashFormat: formatModal codeInput";
+ private static final String CODE_INPUT_ID = "SlashFormat: formatModal codeInput";
private final Modals modals;
public SlashFormat(Modals modals) {
this.modals = modals;
}
@JDASlashCommand(name = "format")
public void onSlashFormat(GuildSlashEvent event) {
Modal modal = modals.create("Format your code")
.bindTo(MODAL_NAME)
.addComponents(
- modals.createTextInput(CODE_INPUT_NAME, "Code", TextInputStyle.SHORT)
+ Label.of(
+ "Code",
+ TextInput.create(CODE_INPUT_ID, TextInputStyle.SHORT).build()
+ )
)
.build();
event.replyModal(modal).queue();
}
@ModalHandler(MODAL_NAME)
- public void onFormatModal(ModalEvent event, @ModalInput(CODE_INPUT_NAME) String code) {
+ public void onFormatModal(ModalEvent event, @ModalInput(CODE_INPUT_ID) String code) {
// ...
}
}You can see a more complete example in the "Entity select menus and text displays in modals" section.
Breaking changes
- (Kotlin only)
nameof@ModalInputhas been updated tocustomId - Removed custom
TextInputBuilder- Use
TextInput.create(Java) orTextInput(...) { ... }(Kotlin) instead - The given custom ID will be used to match against
@ModalInputparameters
- Use
New features
@ModalInput(...) List<String>parameters can now be resolved- Added Kotlin DSLs:
- Modals (
Modals#create(...) { ... }) - Labels (
Label(...) { ... }) - Text inputs (
TextInput(...) { ... }) - String select menus (
StringSelectMenu(...) { ... })
- Modals (
Entity select menus and text displays in modals
Similarly to string select menus, entity select menus can now be added to modals using the native JDA component, the same can be said for text displays.
Please see the JDA 6.0.0-rc.5 release for more details.
Here is an example modal using text inputs, text displays, labels, string select menus and entity select menus:
Kotlin example
private const val MODAL_NAME = "request role"
private const val INPUT_REASON = "reason"
private const val INPUT_ROLE = "role"
private const val INPUT_DETAILS = "details"
@Command
class SlashRequestRole(private val modals: Modals) {
@JDASlashCommand(name = "request_role", description = "Request a role")
fun onSlashRequestRole(event: GuildSlashEvent) {
val modal = modals.create("Role Request Form") {
text(
"""
### Welcome!
Please read the following before continuing:
1. Select the role you wish to get
2. Select the reason why you want this role
3. (Optional) Add any detail about your request
-# Abuse of this system may result in penalties
""".trimIndent()
)
label("Role") {
child = EntitySelectMenu(INPUT_ROLE, SelectTarget.ROLE)
}
label("Reason") {
child = StringSelectMenu(INPUT_REASON) {
option("It looks cool!", "cool")
option("I like the color", "color")
option("I am interested in the relevant discussions", "discussions")
}
}
label("Details") {
child = TextInput(INPUT_DETAILS, TextInputStyle.PARAGRAPH, isRequired = false)
}
bindTo(MODAL_NAME)
}
event.replyModal(modal).queue()
}
@ModalHandler(MODAL_NAME)
fun onRequestRoleModal(
event: ModalEvent,
@ModalInput(INPUT_REASON) reason: List<String>,
@ModalInput(INPUT_ROLE) roles: List<Role>,
@ModalInput(INPUT_DETAILS) details: String,
) {
event.reply("Your request has been submitted!")
.setEphemeral(true)
.queue()
}
}Java example
@Command
public class SlashRequestRole extends ApplicationCommand {
private static final String MODAL_NAME = "request role";
private static final String INPUT_ROLE = "role";
private static final String INPUT_REASON = "reason";
private static final String INPUT_DETAILS = "details";
private final Modals modals;
public SlashRequestRole(Modals modals) {
this.modals = modals;
}
@JDASlashCommand(name = "request_role", description = "Request a role")
public void onSlashRequestRole(GuildSlashEvent event) {
var modal = modals.create("Role Request Form")
.addComponents(
TextDisplay.of("""
### Welcome!
Please read the following before continuing:
1. Select the role you wish to get
2. Select the reason why you want this role
3. (Optional) Add any detail about your request
-# Abuse of this system may result in penalties
"""),
Label.of(
"Role",
EntitySelectMenu.create(INPUT_ROLE, SelectTarget.ROLE).build()
),
Label.of(
"Reason",
StringSelectMenu.create(INPUT_REASON)
.addOption("It looks cool!", "cool")
.addOption("I like the color", "color")
.addOption("I am interested in the relevant discussions", "discussions")
.build()
),
Label.of(
"Details",
TextInput.create(INPUT_DETAILS, TextInputStyle.PARAGRAPH)
.setRequired(false)
.build()
)
)
.bindTo(MODAL_NAME)
.build();
event.replyModal(modal).queue();
}
@ModalHandler(MODAL_NAME)
public void onRequestRoleModal(
ModalEvent event,
@ModalInput(INPUT_ROLE) List<Role> roles,
@ModalInput(INPUT_REASON) List<String> reason,
@ModalInput(INPUT_DETAILS) String details
) {
event.reply("Your request has been submitted!")
.setEphemeral(true)
.queue();
}
}New features
@ModalInputparameters can now resolveMentionsandT/List<T>whereTis one of:IMentionable,Role,User,InputUser,Member,GuildChannel- Added Kotlin DSLs:
text(...)inInlineModalEntitySelectMenu(...) { ... }factory
Breaking changes
- Updated to JDA 6.0.0-rc.5
New features
- Added
Mentions.inputUsers- Ret...
v3.0.0-beta.5
Bug fix release, please refer to previous release for the changelog.
Changes
- Removed
BotCommands-method-accessor-classfile- Can now be optionally included
Bug fixes
- Fixed assignment of parameters
- Fixed handling of value class return types
Don't hesitate to check out the examples and the wiki.
Full Changelog: v3.0.0-beta.4...v3.0.0-beta.5
Installation
As a reminder, the minimum Java version supported is Java 17.
Kotlin Gradle
repositories {
mavenCentral()
}
dependencies {
implementation("io.github.freya022:BotCommands:3.0.0-beta.5")
}Maven
<dependency>
<groupId>io.github.freya022</groupId>
<artifactId>BotCommands</artifactId>
<version>3.0.0-beta.5</version>
</dependency>v3.0.0-beta.4
Replaced jda-ktx with a new module (#239)
Removes jda-ktx and introduces a new BotCommands-jda-ktx module, this is done for a few reasons:
- A significant part of it is unused, because the framework already provides the functionality in a similar way, such as creating commands, components and modals
- It depends on JDA, meaning we can't upgrade to a new major JDA version without also updating jda-ktx, and in some cases it forces us to use Jitpack for it, we don't want that
- Along with the previous point, adding utilities is faster if we maintain it ourselves
This will no longer include jda-ktx transitively, you are recommended to migrate, but if you choose to add it back, be aware that functions relying on CoroutineEventManager, such as JDA#await/listen will no longer work.
Please look at the README for more details.
Differences with jda-ktx
Changes to the CoroutineEventManager
The core module includes its own event manager, you can configure its default timeout at BEventManagerConfig#defaultTimeout, and the CoroutineScope in BCoroutineScopesConfig#eventManagerScope.
As a result, extensions from jda-ktx relying on its CoroutineEventManager no longer work, but you can fix this by importing the extension from this module.
You can still register CoroutineEventListeners (the one from BotCommands-core, not jda-ktx!) if required.
Changed functionalities
If you decide to switch, some functions have replacements:
awaitMessagemust now be used on anEventWaiterinstanceawaitButtonis nowButton#await(the framework'sButtonclass)jda-ktx'sPaginatoris replaced by the corePaginators
Incompatible functionalities
If you keep using jda-ktx, some functions will not work or behave unexpectedly:
scopeonJDA/ShardManager- Any function related to build JDA or shard managers, it is recommended you use the helper functions in
JDAService.
Missing functionalities
Additionally, jda-ktx has additional extensions that were not ported:
String#toEmoji()String#toCustomEmoji()- It is recommended to use application emojis
String#toUnicodeEmoji()- It is recommended to use jda-emojis's
UnicodeEmojisclass (included by default)
- It is recommended to use jda-emojis's
getDefaultScope- Replaced with
namedDefaultScope
- Replaced with
- All extensions already handled by the framework, such as creating/listening to commands, components and modals
- The
WebhookAppender named,String#invokeand someintoextensions from messages/utils.kt- OkHttp's
CallextensionsawaitWithandawait- I would recommend using ktor with the OkHttp client engine
- SLF4J logger delegation (
private val logger by SLF4J)- I recommend using kotlin-logging instead (
private val logger = KotlinLogging.logger { }) - The
Loggingclass may also be of interest
- I recommend using kotlin-logging instead (
refextensions on entities- I don't recommend using them because while they keep entities up to date between reconnects, they don't prevent you from sending requests to deleted entities
Please open an issue if you feel like one of these extensions are worth porting, an alternative is to port them locally.
Migrating
You can apply an OpenRewrite recipe to change all relevant imports, note that this could still require you to do some changes after it.
Before migrating, your codebase must compile, so you must not update any versions yet.
Make sure you have committed your current changes, or make a back-up of your project.
Registering the recipe
Note
This will log warnings for Kotlin sources, but the recipes still work fine.
(Kotlin) Gradle
plugins {
// ...
id("org.openrewrite.rewrite") version "7.11.0"
}
repositories {
// ...
maven("https://jitpack.io")
}
dependencies {
// Existing dependencies, DO NOT UPDATE THEM YET
// ...
rewrite("io.github.freya022:BotCommands-jda-ktx:{{NEW_VERSION}}")
rewrite("org.openrewrite.recipe:rewrite-java-dependencies:1.37.0")
}
rewrite {
// Use 'dev.freya02.MigrateToBcJdaKtx' if you want to migrate from jda-ktx (recommended)
// Use 'dev.freya02.MigrateFromBcCoreToBcJdaKtx' if you want to keep using jda-ktx
activeRecipe("dev.freya02.MigrateToBcJdaKtx")
}Checking changes (dry run)
Run the rewriteDryRun task, this can be done by pressing CTRL twice on IntelliJ then running gradle rewriteDryRun.
This will generate a diff file at build/reports/rewrite/rewrite.patch, you can check the possible changes there.
Applying changes
Run the rewriteRun task.
Maven
- Add the following repository:
<repository>
<id>jitpack</id>
<url>https://jitpack.io</url>
</repository>- Add the following plugin:
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>6.13.0</version>
<configuration>
<activeRecipes>
<!-- Use 'dev.freya02.MigrateToBcJdaKtx' if you want to migrate from jda-ktx (recommended) -->
<!-- Use 'dev.freya02.MigrateFromBcCoreToBcJdaKtx' if you want to keep using jda-ktx -->
<recipe>dev.freya02.MigrateToBcJdaKtx</recipe>
</activeRecipes>
</configuration>
<dependencies>
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-java-dependencies</artifactId>
<version>1.37.0</version>
</dependency>
<dependency>
<groupId>io.github.freya022</groupId>
<artifactId>BotCommands-jda-ktx</artifactId>
<version>{{NEW_VERSION}}</version>
</dependency>
</dependencies>
</plugin>Checking changes (dry run)
Run the rewrite:dryRun goal, this can be done by pressing CTRL twice on IntelliJ then running mvn rewrite:dryRun.
This will generate a diff file at target/site/rewrite/rewrite.patch, you can check the possible changes there.
Applying changes
Run the rewrite:run goal.
You can then update BotCommands-core and add BotCommands-jda-ktx, if you do use it.
It is recommended to optimize imports (Code | Optimize imports in IntelliJ) after migrating.
Notes
Breaking changes
- Removed
ICoroutineEventManagerSupplier- If you want to configure the default timeout, set
BEventManagerConfig#defaultTimeout - If you want to configure the coroutine scope, set
BCoroutineScopesConfig#eventManagerScope
- If you want to configure the default timeout, set
- Removed the
jda-ktxapi dependency- You can add it back if you want, but I'd recommend migrating to
BotCommands-jda-ktx
- You can add it back if you want, but I'd recommend migrating to
New Features
- Added
CoroutineEventListener - Ported part of jda-ktx to
BotCommands-jda-ktx - Added more extensions, see the readme
Changes
- Moved JDA extensions from the core modules to
BotCommands-jda-ktx- Deprecated accessors were made to help migrate
- Extensions for
RestAction,RestResultand related, which have vararg parameters, now require at least 1 argument
Added generate method accessors (#241)
For Java 24+ users, this feature allows using improved method calls (event listeners, commands and service initialization),
reducing the size of stack traces in exceptions and in your debugger, as well as slightly improved performance.
More technical details are in the README.
New features
- Added
BotCommand.preferClassFileAccessors()
Breaking changes
- Replaced jda-ktx with a new module (#239)
New features
- Added generate method accessors (#241)
Changes
- Added missing static methods for function and properties in
objects - Added missing overloads using Java reflection (instead of Kotlin reflect)
- Added missing overloads using Java durations (instead of Kotlin durations)
- Removed
datamodifier fromTimeoutInfo
Bug fixes
BCServiceContainercan now be injected- Unknown event types no longer log twice per function
Don't hesitate to check out the examples and the wiki.
Full Changelog: https://github.com/freya022/BotComm...
v3.0.0-beta.3
Added BotCommandsMessages and PermissionLocalization (#236)
DefaultMessages and DefaultMessagesFactory are deprecated in favor of:
BotCommandsMessagesfor the messages used by the frameworkPermissionLocalizationforDefaultMessage#getPermission
Deprecation process
If a non-default configuration of DefaultMessages is detected, the auto-configured BotCommandsMessagesFactory instance will delegate to it instead, and you will see a warning about the deprecation.
Differences
BotCommandsMessages is similar to DefaultMessages, however:
- The template keys have been changed as to allow nesting in some cases
- Each method returns a
MessageCreateDatainstead of aString, allowing you to fully customize the responses (such as by using Components V2 👀) - The method names were shortened
The default strings were unchanged.
Migrating
If you made DefaultMessages[language].json files, you will need to replace DefaultMessages by BotCommandsMessages, then migrate the keys to the new ones found in BotCommandsMessages-default.json.
Breaking changes
Modules
- Spring support was moved to a separate
BotCommands-springartifact
Dependencies
-
Some
compiledependencies are no longer included transitively:You do not need to depend on them unless your code compiles against them in your project
-
Optional dependencies are no longer in the published POM, this does not affect your project at all
Rate limiting
- Generics were removed from
RateLimitHandlermethods
Deprecations
Default DI
- Deprecated
DefaultServiceContainer, renamed toBCServiceContainer
Changes
Modules
- The
BotCommandsartifact will be split in more submodules, those new modules will still be included transitively
Slash commands
- Allows vararg parameters to be received with 0 required options (#234)
Text commands
- Enforce at least 1 required option when using varargs (#234)
Core configuration
JDAService#getDefaultRestConfig()now appends a link to itself in the HTTP User-Agent
Extensions
-
Some extensions had a wrong contract with the
blockspecified as being calledEXACTLY_ONCE, this has been corrected toAT_MOST_ONCErunCatchingResponserunIgnoringResponserunIgnoringResponseOrNullrunCatchingRest
See
c4deec1152for more details
Dependencies
- Updated Kotlin to 2.2.0
- Updated JDA to 5.6.1
- Updated Jackson to 2.19.1
New features
Components
- Added
ButtonFactory#toLabelButton()(e.g.buttons.primary("Page 1/5").toLabelButton())- Allows creating disabled buttons for display purposes
Default DI
- Added
@ConditionalOnMissingService
Reflection
- Added
ClassGraphProcessorProvider- This is an SPI returning
ClassGraphProcessorinstances at startup, mainly used by other modules - Is opt-in via
@ExperimentalReflectionApi
- This is an SPI returning
Bug fixes
Default DI
- Fix
BServiceConfig#serviceSuppliernot being used - Fix supplied services being unable to be retrieved by their primary type
Database
- Fix
DBResult's iterator not fetching values whenhasNext()was not called
Rate limiting
- Don't attempt to delete rate limit message if the channel was deleted
Don't hesitate to check out the examples and the wiki.
Full Changelog: v3.0.0-beta.2...v3.0.0-beta.3
Installation
As a reminder, the minimum Java version supported is Java 17.
Kotlin Gradle
repositories {
mavenCentral()
}
dependencies {
implementation("io.github.freya022:BotCommands:3.0.0-beta.3")
}Maven
<dependency>
<groupId>io.github.freya022</groupId>
<artifactId>BotCommands</artifactId>
<version>3.0.0-beta.3</version>
</dependency>