Releases: freya022/BotCommands
v3.0.0-alpha.20 | Default persistent timeout, improved introspection/resolver, fixes
Overview
Added a default persistent component timeout, improved introspection API/resolvers, and a bunch of fixes.
Breaking changes
Autocomplete
- Autocomplete handlers can now only get parameters that are present on the slash command
Deprecations
Components
- Deprecated
Components.defaultTimeout
- Renamed to
Components.defaultEphemeralTimeout
- Now nullable
- Renamed to
Resolvers
- All
resolve
andresolveSuspend
functions were deprecated- New overloads were added, which accepts different kinds of options instead of the commands
- You can still get the command back from the
executable
property
Introspection API
- Deprecated getting parameters and option by name
- You can still use the collection methods to achieve the same result
Changes
Text commands
- Go to next text command variation if a value is
null
and required- Aligns with documented behavior on
TextParameterResolver#resolve
- Aligns with documented behavior on
New features
Components
- Added a default persistent component timeout (
Components.defaultPersistentTimeout
)- Set to
null
by default
- Set to
Commands
- Add support for inline classes in annotated commands
Bug fixes
Default DI
- Fixed
DefaultServiceContainer#getServiceNamesForAnnotation
returning services which were unavailable
Misc
- Fixed inability to scan nested JARs
- Such as Spring Boot JARs
Components
- Fixed inability to create select menus
Don't hesitate to check out the examples and the wiki.
Full Changelog: v3.0.0-alpha.19...v3.0.0-alpha.20
v3.0.0-alpha.19 | Configurable command cache and QoL improvements
Overview
Added a configurable command cache, components which reset their timeout on use, and a bunch of QoL changes.
Common interfaces for command builders (#194)
Option aggregate builders now share the same methods as command builder to declare options.
Breaking changes
- (In aggregate)
nestedOptionVararg
->optionVararg
- (In aggregate)
nestedAggregate
->aggregate
inlineClassOption
andinlineClassOptionVararg
were moved to extensions- Moved some classes related to option builders
- This shouldn't affect most users as the types should not be used explicitly outside of extensions, you can re-import at worst
Changes
- Command, option and aggregate builders are now interfaces
Additions
- Added support for value classes in annotated options of user/message context commands
- Added
inlineClassAggregate
, lets you add any option inside an inline class aggregator- Basically, no longer limited to an option/vararg
Priority parameter on ParameterResolverFactory
(#197)
This enables overriding existing parameters resolvers.
To override a built-in resolver with your own, set your factory's (or the @Resolver
annotation) priority to higher than 0.
Note: Spring users may see a warning related to annotation property aliasing, you can ignore it.
This is due to @BService
and @ResolverFactory
both having a priority
property.
Additions
- Added
ParameterResolverFactory#priority
- Added a
priority
property for@Resolver
Changes
- Resolvers are now chosen based off their compatibility and priority
- Errors if both have same priority
New way of getting custom text command prefixes (#198)
You can now get custom text command prefixes based on a given GuildMessageChannel
,
methods to get the supported/preferred prefixes now accurately return the prefixes used in other places.
Possible breaking changes - If you had prefixes set with `SettingsProvider`
Retrieving allowed prefixes of a command in a specific channel has slightly changed:
Previous behavior
- If ping-as-prefix is enabled, and the command starts with the bot's mention, then the command is accepted
- Else, the prefixes are gathered, and if it starts with any, the command is accepted:
- If a
SettingsProvider
is available, fromSettingProvider#getPrefixes(Guild)
- Else, from
BTextConfig#prefixes
- If a
New behavior
The command is accepted if any prefix given by TextCommandsContext#getPrefixes(GuildMessageChannel)
matches:
- If a
TextPrefixSupplier
is available, fromTextPrefixSupplier#getPrefixes(GuildMessageChannel)
- If a
SettingsProvider
is available, fromSettingProvider#getPrefixes(Guild)
(now deprecated) - Else, from
BTextConfig#prefixes
+ the bot's mention ifBTextConfig#usePingAsPrefix
is enabled
Deprecations
SettingsProvider
SettingsProvider#getPrefixes(Guild)
TextCommandsContext#prefixes
TextCommandsContext#isPingAsPrefix
TextCommandsContext#getPreferredPrefix(JDA)
Changes
- The prefix used in the content of the built-in help command is now determined by
TextCommandsContext#getPreferredPrefix(GuildMessageChannel)
Additions
- Added
TextPrefixSupplier
- Returns the allowed prefixes for a given
GuildMessageChannel
- Returns the preferred prefix for a given
GuildMessageChannel
- Returns the allowed prefixes for a given
Configurable application commands cache (#201)
This allows you to configure the path in which files are written, or to switch to a database storage,
but also disable caching.
Deprecations
- Deprecated
BApplicationConfig#onlineAppCommandCheckEnabled
- Moved to
ApplicationCommandsCacheConfig#checkOnline
- Moved to
- Deprecated
BApplicationConfig#logApplicationData
- Moved to
ApplicationCommandsCacheConfig#logDataIf
- Moved to
- Deprecated
BApplicationConfig#diffEngine
- Moved to
ApplicationCommandsCacheConfig#diffEngine
- Moved to
Changes
- If the application commands cache folder is not writable, an in-memory cache is used.
Additions
- Added
BApplicationConfig#fileCache
,databaseCache
anddisableCache
- All of these have the properties that were deprecated
fileCache
lets you configure where the cache is, may be useful for Docker containers- (Recommended)
databaseCache
reuses the existingConnectionSupplier
, more resilient to write errors, no extra files in containers disableCache
always updates commands on startup, not recommended
Added more component delete methods and resetTimeoutOnUse
(#202)
Breaking changes
deleteComponentsById
now takes integers instead of strings- These are the integers returned by the
internalId
property - Useful if you need cheap storage of used component IDs, used in paginators for example
- If you need to delete components by their
String
ID, usedeleteComponents
withIdentifiableComponent.fromId
- These are the integers returned by the
Additions
- Added
resetTimeoutOnUse
- Resets the timeout everytime the component is used
- Can be set on a component group, using any component inside that group resets the timeout
- Added a
BContext
property in component factories - Added static methods to make fake
IdentifiableComponent
s - Added
deleteComponents
takingIdentifiableComponent
s - Added
deleteRows
takingCollection<LayoutComponent>
- Useful when deleting components from a JDA
Message
- Useful when deleting components from a JDA
Misc
Prioritized rate limiter (#205)
Added a RestRateLimiter
implementation which enforces the 50 requests/s,
preventing cloudflare bans (as best as it can, depends on your host).
This rate limiter is used by default when using the new factories in JDAService
,
which I highly recommend using.
Changes
- If the default
RestRateLimiter
is used, application commands are pushed at a rate of 20 requests/s
Additions
- Added
PriorityGlobalRestRateLimiter
- Enforces 50 requests/s
- There may be a lot of command updates, so their requests have lower priority
- Prevents CF bans on large bots as all requests are fired at once due to each request being on its own bucket
Single-shard and sharded factories in JDAService
(#206)
Static factories similar to JDA's were added,
they configure the event manager and rest config,
but also the intents and cache flags.
Example
Before
public class Bot extends JDAService {
@Override
public void createJDA(BReadyEvent event, IEventManager eventManager) {
JDABuilder.createLight(token, getIntents())
.setEventManager(eventManager)
.enableCache(getCacheFlags())
.setRestConfig(getDefaultRestConfig()) // new
// Other configuration, such as activity, member cache policy...
.build();
}
}
After
public class Bot extends JDAService {
@Override
public void createJDA(BReadyEvent event, IEventManager eventManager) {
light(token)
// Other configuration, such as activity, member cache policy...
.build();
}
}
Ability to read meta-annotations recursively (#207)
This allows combining one or more annotations on a single annotation.
Breaking changes
@Filter
can no longer be used on classes
Changes
- Custom condition annotations and their checkers no longer need to be in the search path
- Most, if not all, annotations can be used as meta-annotations
- The following annotations can be read multiple times, when they are used indirectly (as meta-annotations):
@DeclarationFilter
@Filter
@ChannelTypes
@MentionsString
Be aware that such annotations are overridden if the same annotation is used directly
Refactor rate limiters to allow easier use of proxied buckets (#208)
These changes improve the customization of rate limiters and how the bucket keys and configurations are retrieved.
Breaking changes
- Renamed
Cooldown#rateLimitScope
=>scope
- Removed
BucketFactory
- Utility methods were moved to
Buckets
- Replaced with
BucketConfigurationSupplier
- Utility methods were moved to
- Removed
RateLimiterFactory
- Registering a rate limiter only requires the "group" (name) and a
RateLimiter
- Registering a rate limiter only requires the "group" (name) and a
- Renamed
DefaultBucketAccessor
->InMemoryBucketAccessor
- Moved
DefaultRateLimiter
to internal package- Use
RateLimiter#createDefault
instead
- Use
- The
rateLimitReference
method while building a component, now accepts aComponentRateLimitReference
- You can create one with the
createRateLimitReference
method of your component factory
- You can create one with the
Additions
- Added
RateLimiter#createDefaultProxied
- Allows you to give a Bucket4J
ProxyManager
to use store buckets remotely, such as in a database
- Allows you to give a Bucket4J
- Added
BucketConfigurationSupplier
- Lets you return different buckets based on the execution context
- You can use
Buckets
+BucketConfigurationSupplier#constant
(BucketConfiguration#toSupplier
in Kotlin) to always use the same "bucket configuration"
- Added
ProxyBucketAccessor
- Uses a
BucketKeySupplier
for the... bucket key, yea
- Uses a
- Added
AnnotatedRateLimiterFactory
- Lets you configure which
RateLimiter
to use on annotated rate limits / cooldown
- Lets you configure which
Examples
Command rate limiting, with code-declaration:
v3.0.0-alpha.18 | Hotfix for Spring startup
Overview
Hotfix for an issue preventing Spring apps from starting up
Deprecations
- Deprecated
BServiceConfig#serviceAnnotations
Fixes
- Fixed an issue preventing Spring apps from starting up
Don't hesitate to check out the wiki.
Full Changelog: v3.0.0-alpha.17...v3.0.0-alpha.18
v3.0.0-alpha.17 | Improved Spring support, text/app command switch and command update logs
Overview
Improved Spring support, added text/application command switches and improved application command update logs.
Add Spring auto configuration (#190)
You no longer need to use the annotation, nor be forced to make a meta-annotation to prevent annotation overriding.
Simply adding the library to your project will load it,
you can avoid running it with the exclude
value of your @SpringBootApplication
.
Add Spring configuration metadata (#188)
You can now benefit from autocomplete and hints in your application.properties
/application.yaml
.
If you're interested in how that's done: Annotation processor
Breaking changes
- Renamed
botcommands.database.queryLogThresholdMillis
tobotcommands.database.queryLogThreshold
- Uses Java's
Duration
, Spring supports the ISO-8601 format, a simplified format or milliseconds
- Uses Java's
- Changed how maps are read from properties
- Use the standard format,
[property key].[map key]=[map value]
- Affects
botcommands.application.localizations
- Use the standard format,
Additions
- Added metadata for Spring configuration properties (More info)
- Note: Description is a copy of the docs due to https://youtrack.jetbrains.com/issue/IDEA-356678
Fixes
- Fix configuring
botcommands.text.dmClosedEmoji
Deprecations
- Deprecated
@EnableBotCommands
- Remove it and it works.
Add switches to disable application / text commands (#186)
At least you have the choice to not use them, right?
Additions
- Added an
enable
properties toBApplicationConfig
andBTextConfig
, as well as their Spring properties. - Added
@RequireApplicationCommands
and@RequireTextCommands
, you can use these to disable services that depend on them.
Improve command diff and their logs (#191)
The new application command diff engine will give you more accurate details over what changed on your application commands.
The new engine is used by default, and will log the differences if TRACE
logs are enabled for io.github.freya022.botcommands.internal.commands.application.diff.DiffLogger
or any package it is in.
Deprecations
BDebugConfig#enableApplicationDiffsLogs
- Only used for the old diff engine
Changes
- New application command diff engine by default
- Only logs what changed, with more accuracy, logs on
TRACE
- Only logs what changed, with more accuracy, logs on
Additions
BApplicationConfig#diffEngine
- Lets you switch back in case there's a bug
BApplicationConfig#logApplicationCommandData
- Logs the raw JSON when commands needs to be updated
Deprecations
Configuration
- Deprecated
BDebugConfig#enabledMissingLocalizationLogs
- Replaced by
BApplicationConfig#logMissingLocalizationKeys
- Replaced by
- Deprecated
BDebugConfig
- Deprecated
BComponentsConfig#useComponents
- Renamed to
BComponentsConfig#enable
- Renamed to
Fixes
Spring configuration
- Fixed default configs being returned with manual getters (such as from
BContext
orBConfig
)
Text commands
- Fixed help command being disabled if another Spring bean was declared but disabled
Application commands
- Fix global commands always updating
Don't hesitate to check out the changelogs and the wiki.
Full Changelog: v3.0.0-alpha.16...v3.0.0-alpha.17
v3.0.0-alpha.16 | Improved localization, command introspection and RestResult
Overview
Improved localization support, added an API to inspect commands and improved RestAction
exception handling in Kotlin, among other features and changes.
Add localized reply functions to events (#177)
All interaction events, InteractionHook
and BaseCommandEvent
(incl CommandEvent
) now have several functions
to reply using the user locale, guild locale, or any locale.
By default, the localization bundles used are those registered in BLocalizationConfig#responseBundles
,
you can set a specific bundle, and set a localization prefix,
by setting localizationBundle
and localizationPrefix
on your event.
In interactions, the user and guild locales can be customized by implementing UserLocaleProvider
and GuildLocaleProvider
respectively.
In text commands, the locale can be customized by implementing TextCommandLocaleProvider
.
Use locale providers for AppLocalizationContext
/TextLocalizationContext
Using the same providers from the above feature, injected localization contexts will use their returned locales.
Previously it would always use Interaction#userLocale/guildLocale
or Guild#locale
,
it will now use UserLocaleProvider
/GuildLocaleProvider
and TextCommandLocaleProvider
.
This allows you to customize the locale without reimplementing your own localization.
Note: I recommend using the localized reply methods on the event itself.
Added API to introspect commands, parameters and options (#178)
You can now retrieve details, parameters and options of text and application commands.
Breaking changes
ComponentDescriptor
is no longer passed inComponentParameterResolver
ModalHandlerInfo
is no longer passed inModalParameterResolver
TextCommandVariation
andSlashCommandInfo
has moved to the API package- Parameters of
TextParameterResolver#getHelpContent
changed- Old:
(parameter: KParameter, event: BaseCommandEvent, isID: Boolean)
- New:
(option: TextCommandOption, event: BaseCommandEvent)
- Old:
Added annotated application command declaration filters (#185)
Old ways to restrict commands to a guild have been deprecated,
and replaced with an annotation set on each application command.
This enables having such filters be more visible, instead of being tucked away in two interfaces.
Deprecations
- Deprecated
CommandList
,SettingsProvider#getGuildCommands
andApplicationCommand#getGuildsForCommandId
Addition
- Added
@DeclarationFilter
andCommandDeclarationFilter
- Run on annotated application commands when pushed to a guild
Reworked getting framework messages (#181)
Breaking changes
- Renamed
DefaultMessagesSupplier
toDefaultMessagesFactory
- Has a default instance, can be overridden
- Added methods to get instances from
Interaction
andMessageReceivedEvent
- Uses
UserLocaleProvider
andTextCommandLocaleProvider
by default
- Uses
Deprecations
- Deprecated
DefaultMessages
getters in BContext
Additions
- Added getters in
LocalizableAction
(i.e., for text commands and interactions)
Added usability getters for text/application commands (#182)
You can now use getUsability
on TextCommandInfo
/ApplicationCommandInfo
,
this allows checking if a given command is visible and/or usable.
Also added support for any NSFW channels in text commands, previously it only supported text and news channels.
Improved text command patterns (commit)
Patterns of text command options can now specify pattern flags in Pattern.compile
;
Using embedded flag expressions is no longer necessary, but can still be used.
Unicode character classes (incl. unicode casing) are also now used on all patterns.
Improved text option resolvers (#184)
Deprecations
- Deprecated
TextParameterResolver#requiredGroups
Changes
- The pattern of resolvers is wrapped in a non-capturing group to prevent conflicts
- Improved detection of mentions
- Correctly reads either the full mention or the ID
Added a BotOwners
service (#183)
This service should now be used to check bot owners, it will take owner IDs from BConfig#predefinedOwnerIds
,
if not set, will retrieve owners from Discord.
Deprecations
- Deprecated
BConfig#ownerIds
- Renamed to
predefinedOwnerIds
, as these IDs do not always represent the real owners.
- Renamed to
- Deprecated
BConfig#addOwners
, renamed to BConfig#addPredefinedOwners - Deprecated
BConfig#isOwner
,BContext#isOwner
,BContext#ownerIds
Now using command IDs to differentiate top-level commands (#179)
This allows two commands with the same top-level name, in both the global and the guild scope.
Breaking changes
- Removed
ApplicationCommandMap
- Good riddance
ApplicationCommandsContext#findLive[Type]Command
->find[Type]Command
ApplicationCommandsContext#getLiveApplicationCommandsMap
->getApplicationCommands
ApplicationCommandsContext#getEffectiveApplicationCommandsMap
->getEffectiveApplicationCommands
Additions
- Added
ApplicationCommandsContext#getApplicationCommandById
- Finds by id, group, subcommand, and type
Replaced functional RestAction
handling from Result
to RestResult
(#180)
Now allows properly ignoring error responses from rest actions,
under the condition that the value never tries to get returned (i.e., you can still use onSuccess
).
See example here
Breaking changes
RestAction#awaitCatching
now returnsRestResult
Result
extensions moved toRestResult
- To have a
RestResult
, userunCatchingRest
- To have a
Changes
ignore
properly ignores error responsesgetOrThrow
still throws, usegetOrNull
oronSuccess
orThrow
throws if the exception has not been ignored
Additions
- Added
runCatchingRest
- Added
RestResult#recover
, creates a newRestResult
if the exception matches, with a new value or exception.
Breaking changes
Components
- Components that can be grouped implement
IGroupHolder
- Allows to not group groups
- Technically breaking, but you shouldn't see anything
Text commands
- Removed
Consumer
parameter fromBaseCommandEvent#sendWithEmbedFooterIcon
- It was unused anyway, as the
RestAction
is returned
- It was unused anyway, as the
Deprecations
Application commands
- Deprecated
BConfig#disableAutocompleteCache
- Moved to application configs
- Deprecated
BContext#invalidateAutocompleteCache
- Moved to
ApplicationCommandContext
- Moved to
Text commands
- Deprecated text command related properties in
BContext
, moved toTextCommandsContext
Misc
- Deprecated
BContext#getEffectiveLocale
andSettingsProvider#getLocale
- Prefer using locale getters such as
UserLocaleProvider
/GuildLocaleProvider
/TextCommandLocaleProvider
- Prefer using locale getters such as
Components
- Deprecated
EphemeralHandlerBuilder
/PersistentHandlerBuilder
andbindTo
overloads which configured those- This should not affect anyone as they are extra steps for no reason
- Deprecated type-safe
bindTo
andtimeout
extensions- Replaced with
bindWith
andtimeoutWith
- Should help with importing the functions
- Replaced with
- Deprecated
oneUse
- Renamed to
singleUse
- Renamed to
Changes
Dependencies
- JDA:
5.0.0-beta.24
->5.0.0
- jda-ktx:
0.11.0-beta.20
->0.12.0
- kotlinx.coroutines:
1.8.0
->1.8.1
- jackson-databind:
2.17.1
->2.17.2
- (JDA alignment) trove4j (changed artifact id from
trove4j
tocore
):3.0.3
->3.1.0
- kotlin-logging-jvm:
6.0.9
->7.0.0
Text commands
- Load and log on initialization
Misc
- Use timeout of
CoroutineEventManager
by default for each listener - Exceptions are sent to all bot owners
Additions
Built-in resolvers
- Added a
UserSnowflake
resolver for text/application commands, and components.
Text commands
- Added back text command support for enum resolver
- Added default provider for
DefaultEmbedSupplier
/DefaultEmbedFooterIconSupplier
- Added emoji for "Closed DMs"
- Used when an internal reply method cannot send a DM to a user
- Injecting a
TextSuggestionSupplier
will return the default text suggestion supplier if nothing else is available
Application commands
- Added
ApplicationCommandResolverData
- Allows you to inspect the command builder when getting a resolver
Components
- Added
bindWith
andtimeoutWith
extensions to allow unbound callable references- Allows
bindWith(MyClass::myFunction, arg1, arg2...)
, useful when you don't have the instance
- Allows
- Added metadata to top-level application commands
id
,version
and convenience methods, such as getting a command as a mention
Misc
- Added
KLogger#[Level]Null
- Logs and returns
null
- Logs and returns
- Added ban/bulk-ban extensions with Kotlin
Duration
- Added
BContext#getExceptionContext
- Allows getting the same message content as if it was sent automatically
Fixes
Application commands
- Always update global commands (in addition ...
v3.0.0-alpha.15 | Added anonymous handlers, hotfixes
Overview
Added anonymous handlers, hotfixes
Allow anonymous handlers if type-safe binding exists (#176)
This allows you to not set a name on annotated methods which are reference-able using a callable reference.
bindTo
JDAButtonListener
(defaults toFullyQualifiedClassName.methodName
)JDASelectMenuListener
(defaults toFullyQualifiedClassName.methodName
)
timeout
ComponentTimeoutHandler
(defaults toFullyQualifiedClassName.methodName
)GroupTimeoutHandler
(defaults toFullyQualifiedClassName.methodName
)
autocompleteByFunction
AutocompleteHandler
(defaults tonull
)
Changes
Dependencies
- Kotlin: 2.0.0-RC2 -> 2.0.0
Built-in resolvers
- [Breaking] Removed support for text command options on
Resolvers.enumResolver
, as they were inconsistent with other option types and are,
in general, awkward to use for an user, much rather let you define what gets mapped to which entry - [Small breaking] Improved usages of
enumResolver
, uses builder
Misc
- Warn when a timeout is set on
CoroutineEventManager
(as it is ignored)
Removals
ResolverContainer
is now internal, as it wasn't really usable in the first place, use service factories to register your resolver(s) (factories)
Fixes
Components
- Fixed missing dependency exception when components were not used
Don't hesitate to check out the changelogs and the wiki.
Full Changelog: v3.0.0-alpha.14...v3.0.0-alpha.15
v3.0.0-alpha.14 | Improved channel options, retrieve thread by ID and reentrant transactions
Overview
Improved channel resolver support, added retrieving threads by IDs and enabled support for reentrant transactions
Add support for archived threads in text commands and components, improved resolution of slash command channel options (#164)
Added a few extensions to retrieve a thread by id, even if it is archived, as well as some improvements in built-in channel resolvers.
New features
- Added
Guild#retrieveThreadChannelOrNull
- Added
Guild#retrieveThreadChannelById
- Throws
InvalidChannelTypeException
if the channel ID does not represent a thread
- Throws
- Channel options now support (archived) threads in text commands and component data
- They will be retrieved if they are archived
- Added localization key
resolver.channel.missing_access.message
in case the thread channel exists but isn't accessible
- Channel options now support attribute channel types
- The channel types will be set to all channels which have the said attribute, unless overridden with
@ChannelTypes
. (For example, if you ask for aIPostContainer
, the option will acceptsForumChannel
s andMediaChannel
s)
- The channel types will be set to all channels which have the said attribute, unless overridden with
Removals
- [Small breaking] Removed
IThreadContainer#retrieveThreadChannelByIdOrNull
- Replaced with
Guild#retrieveThreadChannelOrNull
- Replaced with
- [Small breaking] Replaced
SlashCommandOption(Builder)#channelTypes
by@ChannelTypes
Add contextual data to parameter resolvers (#169)
Data is passed in some situations, allowing for some checks to be done.
New features
- Prevent usage of required guild-only entities in commands which can be used in DMs
Changes
- [Small breaking] Replaced
ParameterWrapper
in resolvers withResolverRequest
, holds theParameterWrapper
andRequestData
- Resolvers factories are now only checked if their output matches the requested resolver
- This does not break existing factories
- For example, a factory returning a
SlashParameterResolver
is only queried if it was requested for a slash command
Separate custom options and services, add annotations on component and timeout data (#171)
Annotations to differentiate what purpose a parameter is for, enables better exception messages and improve readability of your functions.
New features
- Added
serviceOption
to code-declared commands- Deprecated usages of
customOption
if the parameter is a service
- Deprecated usages of
- Added
@ComponentData
and@TimeoutData
- Add it on data passed in
bindTo
/timeout
- Logs a warning if annotation is not found
- Add it on data passed in
Changes
- Refresh method-injected
List
andLazyService
until they are stable (will not change later)- Still recommended to retrieve them from a constructor-injected
ServiceContainer
- Still recommended to retrieve them from a constructor-injected
New features
Components
- Added type-safe
timeout
function on persistent components, works the same as thebindTo
type-safe extensions
Database
- Added
DBResult#getKotlinInstant
- Added
DBResult#getKotlinInstantOrNull
- Added contracts to inline database functions
- Added support for reentrant transactions (commit)
- If you start a new transaction inside one, it will no longer deadlock, as it reuses the existing transaction
- NOTE: Reentrant connections requires a compatible read-only status
- You can always create a Read-only transaction only, but you cannot create a read-write transaction in a read-only one
- I highly recommend to return results early if possible, to avoid nesting and indentations
- If you want to do transactions in multiple steps, you can use "savepoints" manually
- [Small breaking] transaction block no longer support non-local returns
- Added suspending methods for
execute(Large)Batch
Built-in resolvers
- Added timeout parameter support for
Boolean
,Double
,Emoji
,Int
, andLong
, seeParameterResolver
- Added timeout parameter support in
enumResolver
Misc
- Added
User
/Member#asInputUser
- Added extensions to get an
InputUser
fromInteraction
,Message
andMessageReceivedEvent
: - Added several
RestAction
extensions: - Overriden "effective" getters in
InputUser
, so they always get the best value from theMember
, if available
Changes
Spring IoC
BContext
will start loading onceApplicationReadyEvent
is fired- This enables JDA to start when your application is ready
- Added
@Bean
to secondary service annotations (@Command
,@Resolver
...)
Dependency injection
- Using an explicit name on a
List
is an error - Deprecated
Lazy
, replaced withLazyService
- Does not allow for nullable types, use
ServiceContainer
to get them on-demand
- Does not allow for nullable types, use
Components
- [Small breaking] replaced
ModalInteractionEvent
withModalEvent
- Moved expiration timestamps to the base component entity
- If you don't use a database migration tool, you will need to run this script
Dependencies
- Kotlin: 1.9.23 -> 2.0.0-RC2
- JDA: 5.0.0-beta.22 -> 5.0.0-beta.24
- Bucket4J: 8.4.0 -> 8.12.0
- Artifact:
bucket4j-core
->bucket4j_jdk17-core
- Artifact:
- Jackson Databind: 2.16.1 -> 2.17.1
Fixes
Components
- Made
awaitOrNull
on components return the correct event type (#166) - Await on a component inside a group now throws an exception (#166)
- Groups of ephemeral components deleted on startup are now also deleted
- Select menu event type is now checked
Built-in resolvers
- Fixed
Resolvers#toHumanName
not replacing underscores
Spring IoC
- Added workaround to get bean types if unavailable (#165)
Dependency injection
- Fixed lazy services only being retrieved by their parameter name
- It now uses the parameter name, or fallbacks on matching the type
Don't hesitate to check out the changelogs and the wiki.
Full Changelog: v3.0.0-alpha.13...v3.0.0-alpha.14
v2.10.4 | Bug fixes
Fixes
- Fixed an issue trying to get command suggestions when the input contains illegal characters
- Fixed cooldown being checked even when disabled
Full Changelog: v2.10.3...v2.10.4
v3.0.0-alpha.13 | New pagination, component factories and Spring support
Overview
Reworked pagination, added factories for buttons and select menus, added Spring support and other utilities.
Reworked pagination (#159)
Pagination was overhauled to take advantage of dependency injection, to have better extensibility, to support coroutines and Kotlin's Duration
.
Name changes
ChoiceMenu
->ButtonMenu
InteractiveMenu
->NestedPagination
Usage changes
- A
Paginators
service that serves as a pagination factory has to be used, improving discoverability - Mandatory parameters are no longer behind setters, they are requested by the factory, reducing errors
New features
ButtonMenu
can have different a button style on each entryButtonMenu
can have its buttons reused, in which case the callback can be called more than once- Added support for Kotlin coroutines and
Duration
- Some callbacks (like
PageEditor
) cannot use coroutines as they are called by methods overridable by Java users
- Some callbacks (like
NestedPagination
saves the page number before switching
Changes
- Most options use default values, such as paginator buttons and timeouts
- Requesting a new page invalidates the replaced page's components, can be disabled
- Paginators expire by default using the same timeout as in
Components
- Timeout consumers are optional, timeout can be entirely disabled
- Page editors no longer require returning an embed, you can freely edit the message and/or the existing embed
Extension changes
- Builders are passed instead of their individual values
- Creating a message from the pagination's state is fully handled by the base class, and decomposed into steps that can be overridden
Added factories for buttons and select menus, intermediary step to choose component lifetime (#160)
Components are now created in their own factories, Buttons
for buttons, and SelectMenus
for... select menus.
This solves conflicts with the components
property in JDA-KTX builders, and allows for shorter and more maintainable code, as ephemeral/persistent overloads are no longer needed.
Creating component groups and deleting components can still be done in Components
, or any of those two classes.
- Added an intermediary component factory, which lets you choose whether a component is ephemeral or persistent
- Added
primary
/secondary
/success
/danger
/link
overloads to create buttons with predefined styles - Removed overloads that let you construct empty (invalid) buttons
- Added docs
- Added
ButtonContent#withEmoji
- Deprecated old
Components
methods - Deprecated
Components#deleteComponentsById
, replaced withdeleteComponentsByIds
Button example
Creating a button - Before
fun onSlashCommand(event: GuildSlashEvent, components: Components) {
val button = components.ephemeralButton(ButtonStyle.DANGER, emoji = EmojiUtils.resolveJDAEmoji("wastebasket")) {
// ...
}
}
Creating a button - After
fun onSlashCommand(event: GuildSlashEvent, buttons: Buttons) {
val button = buttons.danger(EmojiUtils.resolveJDAEmoji("wastebasket")).ephemeral {
// ...
}
}
Select menu example
Creating a select menu - Before
fun onSlashCommand(event: GuildSlashEvent, components: Components) {
val selectMenu = components.ephemeralStringSelectMenu {
// ...
}
}
Creating a select menu - After
fun onSlashCommand(event: GuildSlashEvent, selectMenus: SelectMenus) {
val selectMenu = selectMenus.stringSelectMenu().ephemeral {
// ...
}
}
Component group example
Creating a component group - Before
fun onSlashCommand(event: GuildSlashEvent, components: Components) {
val button: Button = TODO()
val selectMenu: StringSelectMenu = TODO()
val group = components.ephemeralGroup(button, selectMenu) {
// ...
}
}
Creating a component group - After
fun onSlashCommand(event: GuildSlashEvent, components: Components/Buttons/SelectMenus) {
val button: Button = TODO()
val selectMenu: StringSelectMenu = TODO()
val group = components.group(button, selectMenu).ephemeral {
// ...
}
}
Added declaration sites to command, autocomplete and rate limit declarations
When an error occurs when declaring a command, the error contains a reference to the method linked to the error.
This works great for annotated declarations, but for code declarations, this meant that there was no way of knowing where the declaration was done.
To fix that, everytime a command (etc...) is declared, the call site (i.e. the line where the command was created) is saved in a DeclarationSite
,
which will then be used in the error, pointing to the actual declaration.
In case you are using an utility class to declare your commands/autocomplete/rate limits, you can always use @IgnoreStackFrame
,
so the declaration site is the one which calls your utility class, instead of the utility class itself.
Added Spring support (#162)
The built-in dependency can now be replaced with Spring IoC.
Additions
- Added
@EnableBotCommands
as a Spring entry point - Added application properties for most configurations
- Added
JDAConfiguration
, containing intents and cache flags, you can use it for yourJDAService
- Added configurers, letting you configure the framework using code, in case the application properties aren't enough
- Added
@RequiresDatabase
and@RequiresComponents
- It is recommended to replace
@Dependencies
on(Blocking)Database
/Components
/Buttons
/SelectMenus
with them
- It is recommended to replace
Changes
CoroutineEventManager
is no longer passed to theBotCommands
entry point and has been deprecated- Must now implement
ICoroutineEventManagerSupplier
in a service - A default provider with 4 threads is used as fallback
- Must now implement
- [Small breaking] The
ServiceContainer
API was slightly altered, but no behavior changed, this should not affect anyone - [Small breaking] You can no longer put services using
BContext
, useServiceContainer
instead - [Small breaking]
BContext
parameter is no longer passed inClassGraphProcessor
(s), this should not affect anyone - [Small breaking]
BContext
parameter was replaced withServiceContainer
inConditionalServiceChecker
andCustomConditionChecker
New features
Built-in dependency injection
- Added
@IgnoreServiceTypes
- Used to ignore types added by implementing an interface annotated with
@InterfacedService
- Used to ignore types added by implementing an interface annotated with
Parameter resolvers
- Added top-level
resolverFactory
to create resolver factory
Misc
- Added
MessageCreate/EditData
extensions - Added
RestAction<InteractionHook>.deleteDelayed
Changes
Configuration
- Command localization locales store
DiscordLocale
instead ofLocale
Built-in dependency injection
- Improved error messages
- Allow
@Dependencies
on functions and getters
Application commands
- [Small breaking] Moved
ApplicationGeneratedValueSupplier
tocommands.application
package - Added a check to prevent mixing top-level commands and subcommands
- Allow declaring application commands with the same name if they are of different type
Components
- Added
asDisabled
/asEnabled
on buttons and select menus - [Small breaking] Added
ButtonStyle
inButtonContent
- [Small breaking] Refactored InteractionConstraints
Parameter resolvers
- Exposed
TypedParameterResolverFactory#type
Misc
- [Small breaking] Renamed
KotlinLogging.logger
tologgerOf
, to help with conflicts - Keep RestAction type in
deleteDelayed
extension - Show app owner and ID in logs if exception dispatch fails
Removals
Components
- [Non-trivial breaking] Removed default timeout on persistent components, meaning they will no longer expire automatically
Fixes
Components
- Fixed deleting components by IDs
- Fixed missing annotation detection on resolver factories
Don't hesitate to check out the changelogs and the wiki.
Full Changelog: v3.0.0-alpha.12...v3.0.0-alpha.13
v3.0.0-alpha.12 | Components hotfix and dependency injection improvements
Overview
Components hotfix and dependency injection improvements
Allow multiple service providers using the same name (#157)
Services that uses the same name will no longer throw an exception at startup, however, in this case, getting the service by its name won't work, as it selects more than one.
New features
Dependency injection
- Prevent usages of conditions on
object
classes- Singletons always get instantiated, using conditions does not make sense
- Report service factories as being unusable if their declaring class is unusable
- This means that a failing condition of a class will also disable service factories inside it
- Property-based service factories are now registered using the property name
- Added
@BConfiguration
- No-op annotation for classes that purely provide service factories
Application commands
- Exposed a
BContext
in application command managers
Changes
Dependency injection
- [Small breaking] Added the requested service name to
DynamicSupplier
- Multiple service providers with the same name are now allowed
- Indirect annotations are no longer read
- This prevents reading meta-annotations, as they are not supported everywhere
- Improved service error formatting
Fixes
Dependency injection
- Fixed issues when multiple factories supplied the same type
Components
- Fixed an issue related to autogenerated keys, preventing from storing components using PostgreSQL
Don't hesitate to check out the changelogs and the wiki.
Full Changelog: v3.0.0-alpha.11...v3.0.0-alpha.12