Skip to content

Releases: freya022/BotCommands

v3.0.0-alpha.11 | Modal improvements, default timeouts and interfaced declarations

02 Mar 13:54
a15644f
Compare
Choose a tag to compare

JDA version

Overview

Simplified code-declared commands, autocomplete and rate limit declarations; Separated annotated command properties and QoL additions.

Mandatory JDAService (#154)

Creating a service extending JDAService is now required.
This has many advantages:

  • Checking gateway intents, cache flags, and member cache requirements for event listeners and event waiters
  • Conditionally enabling services based on gateway intents (see @RequiredIntents),
    cache flags, and member cache
  • Starting JDA when every other service is ready

However, this means that you can only initialize JDA in one place,
as a reminder, you can get a JDA instance by either:

  • Listening to InjectedJDAEvent
  • Retrieving it using lazy services
  • Getting it manually, after it has been injected (not recommended)

Code-declared commands using interfaced services (#153)

To reduce confusion, simplify documentation, improve feature discoverability and performance,
@TextDeclaration and @AppDeclaration were replaced with interfaces: TextCommandProvider and GlobalApplicationCommandProvider/GuildApplicationCommandProvider.
Declaring command is now as simple as implementing one of these interfaces.

The only downside is that you can no longer use dependency injection, but you can still move those dependencies to the declaring class.

Before
@Command
class MyCommand {
    @AppDeclaration
    fun declare(manager: GlobalApplicationCommandManager) {
        // declare commands
    }
}
After
@Command
class MyCommand : GlobalApplicationCommandProvider {
    override fun declareGlobalApplicationCommands(manager: GlobalApplicationCommandManager) {
       // declare commands
    }
}

Code-declared autocomplete using interfaced services (#153)

In-command autocomplete declarations had a few issues, the main issue being that they could be declared multiple times (due to loops, being callable per-guild, or having to be updated),
which could override previous handlers, and caused these previous handlers to not be invalidated.

Autocomplete handlers can now be declared similarly to commands, by implementing AutocompleteHandlerProvider,
and be referenced by name, using autocompleteByName, or by callable reference, such as autocompleteByFunction(SlashPlay::onTitleAutocomplete).

Before
@Command
class SlashBasicAutocomplete : GlobalApplicationCommandProvider {
    suspend fun onSlashBasicAutocomplete(event: GuildSlashEvent, fruit: String) {
        // Reply
    }

    fun onFruitAutocomplete(event: CommandAutoCompleteInteractionEvent, fruit: String): Collection<String> {
        return emptyList() // Return choices
    }

    override fun declareGlobalApplicationCommands(manager: GlobalApplicationCommandManager) {
        manager.slashCommand("basic_autocomplete", function = ::onSlashBasicAutocomplete) {
            option("fruit") {
                // This seems easier but you would run into issues if that line was executed more than once,
                // which includes when your commands are getting updated a second time
                autocomplete("SlashBasicAutocomplete: fruit", ::onFruitAutocomplete)
            }
        }
    }
}
After
@Command
class SlashBasicAutocomplete : GlobalApplicationCommandProvider, AutocompleteHandlerProvider {
    suspend fun onSlashBasicAutocomplete(event: GuildSlashEvent, fruit: String) {
        // Reply
    }

    fun onFruitAutocomplete(event: CommandAutoCompleteInteractionEvent, fruit: String): Collection<String> {
        return emptyList() // Return choices
    }

    override fun declareGlobalApplicationCommands(manager: GlobalApplicationCommandManager) {
        manager.slashCommand("basic_autocomplete", function = ::onSlashBasicAutocomplete) {
            option("fruit") {
                // Reference an existing autocomplete value supplier for this option
                autocompleteByFunction(::onFruitAutocomplete)
            }
        }
    }

    override fun declareAutocomplete(manager: AutocompleteManager) {
        // Register this function as an autocomplete values supplier
        // You can customize, but there's nothing to do here
        manager.autocomplete(::onFruitAutocomplete)
    }
}

Code-declared rate limits using interfaced services (#156)

Similar to autocomplete handlers, rate limits could be declared multiple times, which led to exceptions.
This change makes it so annotated and in-command rate limits are declared anonymously, as they don't have a name and cannot be referenced.

Also, to keep a similar API with commands and autocomplete handlers, rate limits are now declared by implementing RateLimitProvider.

Note: In-command rate limits can still be used.

Before
@Command
class MyCommand {
    @RateLimitDeclaration
    fun declare(rateLimitContainer: RateLimitContainer) {
       // declare commands
    }
}
After
@Command
class MyCommand : RateLimitProvider {
    override fun declareRateLimit(manager: RateLimitManager) {
        // declare rate limits
    }
}

Prefixed component and modal IDs (#150)

To help verify ownership of components and modals, a prefix has been added to their IDs,
as such, any previously created component / modal will no longer be recognized.

In the future, this should allow to disable errors related to unknown components and modals,
if you have an use case for such thing, make sure to make a feature request for it.

Note: Custom modal IDs can no longer be set, they were used to cache values of a cancelled modal,
but are tricky to use, and rather need proper support from Discord.

Distinct annotations for path-specific command properties (#146)

Annotated commands suffer from several issues due to all the data being written in one annotation:

  • For multiple commands with the same top-level name, you must specify the same data everytime (like the scope, defaultLocked or nsfw), which causes hard to diagnose issues if the values are not the same everywhere, without even mentioning the maintainability problem
  • The description of subcommand groups had a chance to not be applied on the right group
    • This is due to the annotation applying the description to the top-level command, the subcommand group, as well as the subcommand, as all of them share the same description
    • This is also what causes unnecessary application command updates, as the description of subcommand groups would sometimes alternate (partially due an unstable order of reflectively-obtained methods), this did not cause an issue as subcommand groups are not visible on Discord (yet)
  • Text commands had a generalDescription property, but this only applies to the text command itself, i.e., not on the text command variation
    • It was unclear where that description was applied on

Solution

Properties which are attribuable to only a part of a command (such as the scope which only can be set on the top-level command) will be in a different annotation:

  • Slash commands will have 3 annotations:
    • [Required on subcommands] Top-level (scope, defaultLocked, nsfw, description)
    • [Optional] Subcommand group (description)
    • [Required] Slash command (name, group, subcommand, description)
  • Text commands will have 2 annotations:
    • [Optional] Text command (path, aliases, description) (path is the path this annotation applies to, if empty, apply on the variation's path)
    • [Required] Variation (path, order, description, usage, example)

Annotations which applies to text commands may appear on a single variation, but they affect the command as a whole, and are not allowed more than once per path.

The description for a top-level text command can be only be set on either annotations.

Slash commands - Before
@Command
class MyMentionsString {
    @JDASlashCommand(name = "mentions_string", subcommand = "member")
    suspend fun onSlashMentionsStringMember(
        event: GuildSlashEvent,
        @SlashOption @MentionsString mentions: List<Member>
    ) {
        // Reply
    }

    @JDASlashCommand(name = "mentions_string", subcommand = "input_user")
    suspend fun onSlashMentionsStringInputUser(
        event: GuildSlashEvent,
        @SlashOption @MentionsString mentions: List<InputUser>
    ) {
        // Reply
    }
}
Slash commands - After
@Command
class MyMentionsString {
    @TopLevelSlashCommandData // This is required once, when you have subcommands
    @JDASlashCommand(name = "mentions_string", subcommand = "member")
    suspend fun onSlashMentionsStringMember(
        event: GuildSlashEvent,
        @SlashOption @MentionsString mentions: List<Member>
    ) {
        event.reply("Mentions:\n${mentions.joinAsList(linePrefix = "-")}").await()
    }

    @JDASlashCommand(name = "mentions_string", subcommand = "input_user")
    suspend fun onSlashMentionsStringInputUser(
        event: GuildSlashEvent,
        @SlashOption @MentionsString mentions: List<InputUser>
    ) {
        event.reply("Mentions:\n${mentions.joinAsList(linePrefix = "-")}").await()
    }
}
Text commands - Before
@Command
class TextTest {
    // Quite a bit messy to put the command description and the variation's description i...
Read more

v3.0.0-alpha.10 | Text command suggestions, exception context and primary service providers

04 Jan 09:06
5fc3b15
Compare
Choose a tag to compare

Overview

Added text command suggestions, extra exception context and primary service providers.

Don't hesitate to check out the changelogs and the wiki as they contain more details.

Fixes

  • Added back support for regional indicator emojis (Commit)
  • Prepared statements returns a nullable ResultSet
  • Skip adding the "Usages" header in help content if there are no variations
  • Services missing an injected dependency (such as JDA) can always be retrieved

Changes

  • Updated JDA-KTX to the maven-central version: club.minnced:jda-ktx:0.11.0-beta.19
    • You no longer need the Jitpack repository
  • Deprecated BBuilder entry point, replaced by BotCommands
  • Make entry point return BContext
  • Application command cache is now stored in:
    • %appdata%/BotCommands on Windows
    • /var/tmp/BotCommands on Unix
  • BContext#getPrefix is nullable
    • null if no prefix has been added and ping-as-prefix is not configured, in which case it is logged

Additions

  • Added null variants in EmojiUtils
  • Added "primary" service providers
    • A primary service provider is prioritized over a normal service provider
    • If multiple service providers exist, only one must be usable, or, only one must be marked primary (using @Primary).
  • Exposed #setParameters on prepared statements
    • This allows setting parameters when using batch statements
  • Reimplemented text command suggestions (#143)
    • Enabled by default
    • Hidden text commands behave the same as if the command didn't exist at all
    • Added TextSuggestionSupplier and a default implementation, allows command filtering and sorting
  • Add extra context to uncaught exceptions in commands/component handlers (#144)
    • Improved message format
    • Improved exception cleaning
    • Any context info can be added in BContext#dispatchException
  • Added DBResult#stream (Mainly for Java users)

Full Changelog: v3.0.0-alpha.9...v3.0.0-alpha.10

v3.0.0-alpha.9 | H2 DB, blocking database, improved query logging and service injection

03 Dec 15:19
ce8f639
Compare
Choose a tag to compare

Overview

Added H2 database support, blocking database and buildable components for Java users, reworked query logging and improved service injection with lazy and list of interfaced services.

Note: The wiki has now moved to https://freya022.github.io/BotCommands/3.X

Don't hesitate to check out the changelogs as they contain more details.

Fixes

  • Fixed inexistant application commands map when BApplicationConfig#slashGuildIds was used (Commit)
  • Fixed Event#getRawData not returning anything
  • Fixed component timeouts not being retrievable when no handler was added
  • Fixed component timeout handlers not having user data passed through (#137)
  • Fixed Java type matching for parameter resolver factories (Commit)
  • Reply with "Application commands not available" message if a command is not found, and global applications are not registered. (Commit)
    • This happens if a global command tries to be executed, when global commands failed to update on startup
  • Fixed name of requested services not being taken into account (Commit)
  • Fix unknown component filters by preventing usage of anonymous component filters (Commit)

Changes

  • Moved Logging to core package
  • Replaced emoji-java with JEmojis (#132)
    • This removes the org.json dependency and updates jackson-databind to 2.16.0
    • Fixes issues with emoji indexes and incorrect fitzpatrick formats
  • Require @DevConfig opt-in on BApplicationConfig#forceGuildCommands
  • Allow calling DBResult's Iterator#hasNext more than once
  • Reworked query logging (#133)
    • Allows adding RDBMS-specific parametrized queries, as to provide the most accurate executable queries
    • Connections made with (Blocking)Database transparently return traced connections and prepared statements
    • Prepared statements are logged by using the class which created it, this means that your logger level for the class itself must be on TRACE
    • Prepared statements can have their loggers changed manually, this is only useful if the logger's name cannot be retrieved using the execution stack, see Database for more details on tracing
  • BConfig#logQueries is now disabled by default
    • This is done as to avoid accidental logging, now that the logger is the caller class
  • Java users can now use use a builder pattern when creating components, similar to V2
  • Allow null in persistent handlers / timeouts user data (#137)
  • Separated database configs in a database block (Commit)

Additions

  • Added a message when applications commands are not registered yet
  • Added BlockingDatabase for Java users (#133)
  • Added the ability to read generated keys (Commit)
  • Added support for primitive arrays when setting statement parameters (Commit)
  • Added missing lazy overloads on ServiceContainer (Commit)
  • Added support for Lazy and List when injecting services
    • Lazily injected services can have their element type nullable (#141)
  • Added support for H2 database (#139)
    • Requires PostgreSQL compabitility mode, see ConnectionSupplier for more details
    • This allows you to run an in-memory database, or have it saved to a file, see H2 Database connection modes for details
    • Flyway users: Due to required migration script changes, the bc schema needs to be deleted, other solutions include changing the checksum or using Flyway#repair, with their own caveats
  • Allow unresolvable services on optional parameters (Commit)
  • Added ServiceContainer#canCreateService overload for named services

Removals

  • Removed deprecated interaction filtering methods

Full Changelog: v3.0.0-alpha.8...v3.0.0-alpha.9

v3.0.0-alpha.8 | Mentions string, command filters and dynamic channel resolvers

08 Nov 15:00
8bae2ea
Compare
Choose a tag to compare

Overview

Added getting mentions from slash command strings, command-specific filters and improvements in documentation.

Don't hesitate to check out the changelogs as they contain more details.

Fixes

  • Fixed slash command groups not using default descriptions
  • Fixed reading arrays with DBResult
  • Fix parameter resolver cache

Changes

  • Renamed commands.prefixed package to commands.text
  • Renamed RegexParameterResolver to TextParameterResolver
  • Moved resolver interfaces from parameters to parameters.resolvers
  • Updated to Kotlin 1.9.20
  • Replaced Class with KClass in DSLs
  • Filters no longer handles replying, a "rejection handler" must be created for it, check the changelogs for more details
  • Abort component interactions if an option is unresolvable and has been acknowledged
    • Previously, this would have thrown

Additions

  • Allow logger live template in Kotlin object declarations
  • Added command specific filters (PR)
  • Added cache flags to JDAService
  • Use service priority when loading non-interfaced services
  • Added @MentionsString to get a list of mentionables in a STRING option
  • Added a dynamic channel resolver
    • All GuildChannel types are supported (including future channel types), except trait interfaces (such as IPositionableChannel)
    • ThreadChannel is only supported for slash commands

Full Changelog: v3.0.0-alpha.7...v3.0.0-alpha.8

v3.0.0-alpha.7 | Package change, enhanced resolver factories

21 Oct 10:26
f060b10
Compare
Choose a tag to compare

Overview

Changed the base package, added predicate-based resolver factories, more extensions and fixes.

Don't hesitate to check out the changelogs as they contain more details.

Fixes

  • Fixed some potential unknown events (commit)
  • Fixed timeout caused by Database#fetchConnection not suspending before a connection is available (commit)
  • Fixed custom conditions on service factories
  • Fixed default descriptions not being retrieved for DSL-declared commands (commit)
  • RequiredIntents properly throws if JDAService is not present

Changes

  • Updated kotlin-logging to 5.X
  • Changed base package from com.freya02 to io.github.freya022
    • A simple Find & Replace is enough to fix this
  • Bot templates now exist as GitHub repository templates, both in Java and Kotlin
  • Changed packages of GlobalExceptionHandlerAdapter, InstanceSupplier, DefaultMessages, RateLimitScope and BContext
  • (Java users) Renamed some primary annotations values to value, avoiding named parameters
  • Revamped the built-in command-specific help embed
  • Replaced name/group/subcommand in @JDATextCommand with a path array
    • Still limited to 3 path components

Additions

  • Added CommandBuilder#cooldown extension
  • Added BConfig#queryLogThreshold, logs a query on WARN if it takes longer than the configured duration
  • Added per-variant usage and examples on text commands
  • Added predicate-based parameter resolver factories
    • Allows you to return parameter resolvers based on custom conditions, see the changelog and docs for more details
  • Added RestAction#timeout using Kotlin's Duration
  • Added deleteDelayed extensions for webhook replies/edits
  • Added IThreadContainer#retrieveThreadChannelByIdOrNull (commit)
  • Added BContext to framework events

Removals

  • Removed BContext from resolvers, GlobalExceptionHandler(Adapter), DynamicSupplier
    • Retrieve the context using dependency injection instead

Full Changelog: v3.0.0-alpha.6...v3.0.0-alpha.7

v3.0.0-alpha.6 | Rate limiting, localization extensions and DB debug

29 Sep 10:39
61aa03a
Compare
Choose a tag to compare

Overview

Added token bucket-based rate limiting, a convenient way to get both a user and a member, more extensions, transaction debugging and a Java bot template.

Don't hesitate to check out the changelogs as they contain more details.

Fixes

  • Fixed text subcommand aliases
  • Fixed commands parsing when only the bot mention was present
  • Fixed ClassGraphProcessor#postProcess running more than once

Changes

  • Having a root localization bundle for a given bundle name is now eagerly enforced
  • BApplicationConfigBuilder#onlineAppCommandCheckEnabled is now opt-in
  • Tweaked setter names in config builders for Java users
  • Persistent handler name is passed to ComponentInteractionFilter if available

Additions

Removals

  • Removed deprecated DBResult functions

Full Changelog: v3.0.0-alpha.5...v3.0.0-alpha.6

v2.10.3 | Command suggestions switch, a few fixes

20 Sep 15:37
7e5d553
Compare
Choose a tag to compare

Overview

Adds the ability to disable text command suggestions and fixes a few issues

Fixes

  • Fixed paginators not able to delete themselves

Changes

  • Data passed to Modals#create now accepts null values

Additions

  • Added TextCommandsBuilder#disableSuggestions, disables suggestions when a user tries to use an unknown command

Full Changelog: v2.10.2...v2.10.3

v3.0.0-alpha.5 | Custom conditions, resolver service factories, and JDAService

12 Sep 16:56
f5f5265
Compare
Choose a tag to compare

Overview

Added custom conditions, parameter resolvers can be created from service factories, and added a JDA service abstraction.

Fixes

  • Paginator can delete itself in a channel it does not have access to
  • Interfaced services with the same "simple name" no longer exclude each others

Changes

  • Service annotations can be used on property getters
  • Deprecated DBResult#readOnce with read/readOrNull
  • Null values are now allowed in modal data

Additions

  • Added more JDA extensions
  • Added BTextConfig#showSuggestions to enable command suggestions on unknown command
  • Added custom condition annotations
  • Added support for parameter resolver using service factories
  • Added bindTo extensions for persistent components
    • This allows you to avoid using a constant to declare the handler, and while having the handler reference, as well as the arguments, checked at compile time
  • Added JDAService, see here
    • This allows you to not worry about initialization order, as the function creating JDA is called at the right time
    • This also allows the framework to know in advance what intents JDA is using
  • Added @RequiredIntents, allowing you to enable/disable a service based off JDAService#intents
  • Added intent checks on event listeners
    • BEventListener#ignoreIntents can be used to ignore those checks
    • BConfig#ignoredIntents can be used to not warn about the supplied intents
    • BConfig#ignoredEventIntents can be used to not warn about the intents of a specified event, in the EventWaiter

Removals

  • Non-suspending functions of KPreparedStatement, inherited from PreparedStatement, are now hidden

Full Changelog: v3.0.0-alpha.4...v3.0.0-alpha.5

v3.0.0-alpha.4 | Localization extensions, service priorities

13 Aug 20:32
a44f0bb
Compare
Choose a tag to compare

Overview

Improved the extensibility of the Localization API, service types of interfaced services are added automatically, and added service priority.

Fixes

Changes

  • Renamed FirstReadyEvent to FirstGuildReadyEvent
  • Improved extension of the Localization API, more details here
  • Service types of interfaced services are now added automatically
    • If you still have a @ServiceType used for it, you will be warned
  • Application commands will not be updated if there is an error on the initial update (i.e., on startup)
  • Improved exception when an option annotation was possibly forgotten
  • Bundles with a -default postfix (between the base name and the locale tag) are read by default
    • The "default" bundle is overridden by existing bundles
  • Reworked interaction filters
    • Uses interfaced services and coroutines
    • All filters are now ran before their targets gets executed

Additions

  • Added extensions to MessageCreateData and MessageEditData
  • Added suppressContentWarning to temporarily suppress message content intent warnings
    • This is useful if you read the content of message context commands, but without having the MESSAGE_CONTENT intent
  • Added namedDefaultScope to easily create a CoroutineScope with incrementally named threads
  • Added readResource, withResource and readResourceAsString to read resources relative to the caller class
  • Added getValue operator on ServiceContainer (enables you to use the by operator to get a service)
  • Added service priority
    • Either on @BService or with @ServicePriority
  • Added Class overloads for functions which accepted KClass
  • Added logs of annotated commands being excluded by @Test / @CommandId
  • Check autocomplete parameters missing from slash commands
  • Added an error when invalid component IDs are used

Removals

  • Removed Gson

Full Changelog: v3.0.0-alpha.3...v3.0.0-alpha.4

v3.0.0-alpha.3 | Docs, dynamic help examples and EventWaiter

18 Jul 17:52
0c1e81c
Compare
Choose a tag to compare

Overview

Added back EventWaiter, fixed inconsistent handling of default locked/test commands

Fixes

  • Fixed inconsistent handling of default locked/test commands

Changes

  • Separated AppOption into SlashOption and ContextOption

Additions

  • Added back EventWaiter, with coroutines support
  • Added dynamic help examples, which lets you generate an help example based on the execution context (by using the event)
  • Exposed CooldownService to the API
  • Added InjectedJDAEvent, which gets fired when a JDA instance is received and injected as a service
  • Reworked most docs related to commands/components/modals

Full Changelog: v3.0.0-alpha.2...v3.0.0-alpha.3