Remora.Discord.Commands
28.1.0
Prefix Reserved
dotnet add package Remora.Discord.Commands --version 28.1.0
NuGet\Install-Package Remora.Discord.Commands -Version 28.1.0
<PackageReference Include="Remora.Discord.Commands" Version="28.1.0" />
paket add Remora.Discord.Commands --version 28.1.0
#r "nuget: Remora.Discord.Commands, 28.1.0"
// Install Remora.Discord.Commands as a Cake Addin #addin nuget:?package=Remora.Discord.Commands&version=28.1.0 // Install Remora.Discord.Commands as a Cake Tool #tool nuget:?package=Remora.Discord.Commands&version=28.1.0
Remora.Discord.Commands
This package provides glue code for using Remora.Commands
with
Remora.Discord
, adding appropriate conditions, autocompletion, type parsers,
and uniform UX for Remora-based applications.
Structure
Most of the library's functionality is offloaded to Remora.Commands
, for which
documentation is available at its repository. Beyond this, the structure of
the library revolves around concepts that should be relatively familiar to users
of other Discord libraries.
Take a look in Parsers for an overview of the various types supported
as first-class parameters, beyond what Remora.Commands
provides out of the
box.
For each command interaction that is received by your application, a matching
appropriate command is identified in your registered command trees, and is
executed with an implementation of ICommandContext
, which provides contextual
information about the command environment (such as guilds, users, additional
data payloads, etc).
Furthermore, any autocompletion requests are routed to implementations of
IAutocompleteProvider
, enabling you to provide bot-driven autocompletion of
command parameters.
Usage
To enable commands, call the following method on your dependency injection container.
services.AddDiscordCommands(enableSlash: true);
Note that slash commands are not enabled by default, and you must opt into them
by passing true
as above.
Registering slash commands
Once you've added the command services and instantiated your service container, you must register your command tree(s) with Discord.
Inject or retrieve the SlashService
from your container in an appropriate way,
and then call
await slashService.UpdateSlashCommandsAsync();
This will register the default command tree globally; optionally, you may register a different named tree, or register the tree at a guild level.
await slashService.UpdateSlashCommandsAsync(guildID: myServerID, treeName: myTreeName);
Not every feature supported by Remora.Commands
is supported by Discord - if
you end up using incompatible features, an exception will be thrown at this
point.
Special Attributes
Remora.Discord.Commands exposes a number of attributes you can use to influence or configure the way your commands are translated to Discord's slash command UX.
For the most part, these attributes map directly to fields or properties on Discord's application command object, but some have more specialized uses.
ChannelTypes
Sets the channel types that should be show in Discord's autocompletion when a user is typing.
Can be applied to Snowflake
or IPartialChannel
(and implementors)-typed
command parameters.
DiscordDefaultDMPermission
Sets the default DM accessibility for a group or command.
Can be applied to top-level groups or commands. The attribute is not compatible with nested groups or commands, and will produce an exception if applied to those.
DiscordDefaultMemberPermissions
Sets the default member permissions required for a user to use a group or command.
Can be applied to top-level groups or commands. The attribute is not compatible with nested groups or commands, and will produce an exception if applied to those.
DiscordNsfw
Sets whether the group or command is age-restricted and hidden or otherwise made unavailable in open channels.
Can be applied to top-level groups or commands. The attribute is not compatible with nested groups or commands, and will produce an exception if applied to those.
DiscordTypeHint
Hints Discord's autocompletion about the type of the parameter it is applied to, allowing only certain types of autocompleted input data.
Can be applied to any parameter, but is typically most useful for
Snowflake
-typed parameters.
ExcludeFromChoices
Removes the marked enumeration member from Discord's autocomplete list.
Can be applied to enumeration members.
ExcludeFromSlashCommands
Excludes the marked group or command from the slash command UI. This is primarily useful when you have certain commands which use incompatible Remora.Commands features, since it also removes all restrictions that would otherwise come from being a slash command.
Can be applied to groups and commands.
MinValue
Marks a numeric parameter as having a minimum allowed value. This restricts Discord's autocompletion and client-side validation to the specified range.
The range is inclusive.
Can be applied to any parameter which has a numeric C# type.
MaxValue
Marks a numeric parameter as having a maximum allowed value. This restricts Discord's autocompletion and client-side validation to the specified range.
The range is inclusive.
Can be applied to any parameter which has a numeric C# type.
SuppressInteractionResponse
This attribute prevents Remora from automatically sending an interaction response on your behalf when receiving a slash command (or similar interaction, such as a context menu click or button press). If you suppress the response, you must send one yourself within a few seconds of entering user code or Discord will consider the interaction failed.
Can be applied to groups and commands.
Context Menu Commands
Discord also supports context menu items on users and messages, which are treated as special slash commands by their system.
These commands have some additional restrictions.
- they must have a particular C# signature
- they must be declared as top-level commands
- they must not have descriptions
To mark a command as either a User
or a Message
command, apply the
CommandType
attribute.
A User
command must take a single parameter named user
.
A Message
command must take a single parameter named message
.
In both cases, the data passed to the command will be a string
containing the
user or message's ID; typically, this means you'd want to declare the parameter
with a type that can parse this ID into the entity you want. IUser
or
IMessage
is probably a good bet, but you can use any type you want as long as
its parser understands a Snowflake
in string
form.
Context menus also have relaxed rules when it comes to command names, and you can use both varied capitalization as well as whitespace.
[Command("My User Command")]
[CommandType(ApplicationCommandType.User)]
public async Task<IResult> MyUserCommand(IUser user)
{
// ...
}
User Feedback
If you want to create messages with a uniform UX, you may use the
FeedbackService
for various message types, such as notices, successes,
failures, etc. The styling of these messages is controlled by an
IFeedbackTheme
, of which there are two provided by default. These themes map
to Discord's own dark and light themes, respectively.
You may also implement your own theme and register it with the dependency injection container.
Autocomplete
To provide autocomplete options while users of your application type, create a
class that implements either IAutocompleteProvider<T>
(for autocompletion of
specific parameter types) or IAutocompleteProvider
(for generic
autocompletion).
public class MyAutocompleteProvider : IAutocompleteProvider
{
public string Identity => "autocomplete::my-provider";
public ValueTask<IReadOnlyList<IApplicationCommandOptionChoice>> GetSuggestionsAsync
(
IReadOnlyList<IApplicationCommandInteractionDataOption> options,
string userInput,
CancellationToken ct = default
)
{
// ...
}
}
You may suggest up to 25 choices when your provider is invoked.
In order to select which autocomplete provider to use, apply the
AutocompleteAttribute
to the appropriate parameters in your command groups. If
you're using the type-specific autocomplete provider, this is not required.
Preparation error events
If a command can't be successfully prepared from whatever the user sends (due to malformed input, parsing failures, failed conditions etc.), the command's "preparation" is considered failed.
In many cases, it's useful to hook into this event in order to provide the end user with helpful information about what they did wrong or why the command didn't work.
This can be accomplished by registering a preparation error event, which is a
class that implements IPreparationErrorEvent
.
public class MyPreparationErrorEvent : IPreparationErrorEvent
{
public Task<Result> PreparationFailed(IOperationContext context, IResult preparationResult, CancellationToken ct = default)
{
// ...
}
}
...
services.AddPreparationErrorEvent<MyPreparationErrorEvent>();
The preparation result contains information about the error - try checking for
things like CommandNotFoundError
or ParameterParsingError
when you get a
preparation error.
If you return an error in a preparation error event, the command invocation is cancelled, and never progresses to the real execution stage.
By default, user- or environment-caused preparation errors don't produce any log messages or user-facing output. It's up to you to decide if and how you want to handle these.
Note that if you register multiple preparation events, they will run sequentially within the same service scope. Order is not guaranteed, but typically ends up being the same as registration order. Every event will get a chance to run even if one of them fails, but failure of any of the events is considered a collective failure, and will cause the command invocation to be cancelled.
Pre- and post-execution events
In some cases, it may be useful to execute pieces of code before or after invocation of a command (checking GDPR consent, logging error messages, etc).
This can be accomplished by registering pre- and post-execution events, which
are classes which implement either IPreExecutionEvent
or
IPostExecutionEvent
, respectively.
public class MyPreExecutionEvent : IPreExecutionEvent
{
public Task<Result> BeforeExecutionAsync(ICommandContext context, CancellationToken ct = default)
{
// ...
}
}
...
services.AddPreExecutionEvent<MyPreExecutionEvent>();
If you return an error in a pre-execution event, the command invocation is cancelled, and never progresses to the real execution stage. If you return an error in a post-execution event, this is treated as if the command itself had failed, which may be useful for things like scrubbing database transactions.
Note that if you register multiple pre- or post-execution events, they will run sequentially within the same service scope. Order is not guaranteed, but typically ends up being the same as registration order. Every event will get a chance to run even if one of them fails, but failure of any of the events is considered a collective failure. In the case of pre-execution events, this will cause the command invocation to be cancelled.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.1 is compatible. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- FuzzySharp (>= 2.0.2)
- Humanizer.Core (>= 2.14.1)
- NGettext (>= 0.6.7)
- Remora.Commands (>= 10.0.5)
- Remora.Discord.Gateway (>= 12.0.2)
- Remora.Extensions.Options.Immutable (>= 1.0.8)
- System.ComponentModel.Annotations (>= 5.0.0)
-
net6.0
- FuzzySharp (>= 2.0.2)
- Humanizer.Core (>= 2.14.1)
- NGettext (>= 0.6.7)
- Remora.Commands (>= 10.0.5)
- Remora.Discord.Gateway (>= 12.0.2)
- Remora.Extensions.Options.Immutable (>= 1.0.8)
- System.ComponentModel.Annotations (>= 5.0.0)
-
net7.0
- FuzzySharp (>= 2.0.2)
- Humanizer.Core (>= 2.14.1)
- NGettext (>= 0.6.7)
- Remora.Commands (>= 10.0.5)
- Remora.Discord.Gateway (>= 12.0.2)
- Remora.Extensions.Options.Immutable (>= 1.0.8)
- System.ComponentModel.Annotations (>= 5.0.0)
-
net8.0
- FuzzySharp (>= 2.0.2)
- Humanizer.Core (>= 2.14.1)
- NGettext (>= 0.6.7)
- Remora.Commands (>= 10.0.5)
- Remora.Discord.Gateway (>= 12.0.2)
- Remora.Extensions.Options.Immutable (>= 1.0.8)
- System.ComponentModel.Annotations (>= 5.0.0)
NuGet packages (6)
Showing the top 5 NuGet packages that depend on Remora.Discord.Commands:
Package | Downloads |
---|---|
Remora.Discord
Metapackage for Remora.Discord's various components |
|
Remora.Discord.Interactivity
Framework for using Discord's interaction-driven message components |
|
Remora.Discord.Extensions
Utilities and components which extend upon Remora.Discord's base resources |
|
AraHaan.Remora.Extensions
A package that extends Remora.Discord with additional functionality. Extensions: - AddRoles (extends IDiscordRestGuildAPI to allow adding discord roles in bulk) - RemoveRoles (extends IDiscordRestGuildAPI to allow removing discord roles in bulk) - RunBotConsoleAsync (extends IHostBuilder to allow an cleanup operation to be done on application shutdown, requires a type to derive from IBotServiceConfigurator) - DownloadAsync (extends DownloadAsync to download a discord attackment to a stream) - DownloadStringAsync (extends DownloadAsync to download a discord attackment to a string) - DownloadToFileAsync (extends DownloadAsync to download a discord attackment to a file) - AddDiscordGatewayClientOptions (extends IServiceCollection to allow adding the gateway client options using a factory) - AddSlashUpdateService (extends IServiceCollection to allow adding the SlashUpdateService background service to the service collection) - Configure<T> (extends IServiceProvider to allow the client options to be configured after the service provider is created) Types: - AraHaan.Remora.Extensions.Hosting.Host (A special host class that makes the IBotServiceConfigurator system work) - Note: When using this type ensure that "using Microsoft.Extensions.Hosting" is not used otherwise it will conflict. I have told Microsoft about my need to extend this but they said that they do not think it's needed. - AraHaan.Remora.Extensions.Hosting.BotServiceConfiguratorBase (A base class for types to provide code that should run before configure of the services, code to configure the services, and code to run after shutdown of the generic host aka Microsoft.Extensions.Hosting) - AraHaan.Remora.Extensions.Options.SlashUpdateServiceOptions (An options type used to configure the SlashUpdateService) - AraHaan.Remora.Extensions.Services.SlashUpdateService (An BackgroundService used to update Discord slash commands) |
|
VTP.RemoraHelpSystem
Provides a simple, modular help system for Remora.Discord. |
GitHub repositories (1)
Showing the top 1 popular GitHub repositories that depend on Remora.Discord.Commands:
Repository | Stars |
---|---|
angelobreuer/Lavalink4NET
Lavalink4NET is a Lavalink wrapper with node clustering, caching and custom players for .NET with support for Discord.Net, DSharpPlus, Remora, and NetCord.
|
Version | Downloads | Last updated | |
---|---|---|---|
28.1.0 | 32,766 | 5/28/2024 | |
28.0.2 | 25,122 | 2/5/2024 | |
28.0.1 | 46,813 | 11/14/2023 | |
28.0.0 | 29,295 | 7/24/2023 | |
27.0.0 | 18,578 | 5/11/2023 | |
26.2.3 | 1,928 | 3/20/2023 | |
26.2.2 | 2,424 | 1/19/2023 | |
26.2.1 | 1,733 | 1/10/2023 | |
26.2.0 | 2,122 | 12/28/2022 | |
26.1.1 | 2,044 | 12/13/2022 | |
26.1.0 | 1,755 | 12/13/2022 | |
26.0.0 | 1,175 | 12/10/2022 | |
25.3.0 | 2,152 | 10/30/2022 | |
25.2.4 | 18,394 | 9/2/2022 | |
25.2.3 | 2,057 | 8/19/2022 | |
25.2.2 | 2,350 | 7/28/2022 | |
25.2.1 | 1,751 | 7/26/2022 | |
25.2.0 | 1,578 | 7/26/2022 | |
25.1.1 | 5,431 | 6/29/2022 | |
25.1.0 | 1,610 | 6/27/2022 | |
25.0.3 | 1,888 | 6/23/2022 | |
25.0.2 | 2,175 | 6/20/2022 | |
25.0.1 | 1,640 | 6/19/2022 | |
25.0.0 | 1,581 | 6/18/2022 | |
24.0.0 | 1,706 | 6/14/2022 | |
23.1.1 | 1,639 | 6/8/2022 | |
23.1.0 | 1,636 | 6/3/2022 | |
23.0.2 | 1,667 | 5/25/2022 | |
23.0.1 | 1,647 | 5/23/2022 | |
23.0.0 | 1,793 | 5/15/2022 | |
22.0.0 | 1,724 | 5/10/2022 | |
21.0.1 | 2,656 | 5/8/2022 | |
21.0.0 | 1,687 | 5/3/2022 | |
20.2.2 | 1,971 | 4/28/2022 | |
20.2.1 | 1,567 | 4/28/2022 | |
20.2.0 | 1,600 | 4/25/2022 | |
20.1.4 | 2,397 | 4/18/2022 | |
20.1.3 | 1,620 | 4/18/2022 | |
20.1.2 | 2,851 | 3/21/2022 | |
20.1.1 | 2,682 | 3/17/2022 | |
20.1.0 | 1,602 | 3/15/2022 | |
20.0.1 | 3,081 | 2/20/2022 | |
20.0.0 | 1,716 | 2/19/2022 | |
20.0.0-rc1 | 675 | 2/14/2022 | |
19.0.3 | 1,690 | 2/14/2022 | |
19.0.2 | 1,914 | 1/27/2022 | |
19.0.1 | 1,123 | 1/18/2022 | |
19.0.0 | 777 | 1/17/2022 | |
18.0.0 | 774 | 1/17/2022 | |
17.0.0 | 1,685 | 1/11/2022 | |
16.1.0 | 34,574 | 1/2/2022 | |
16.0.3 | 1,003 | 1/1/2022 | |
16.0.2 | 1,268 | 12/23/2021 | |
16.0.1 | 471 | 12/23/2021 | |
16.0.0 | 494 | 12/21/2021 | |
15.0.0 | 676 | 12/16/2021 | |
14.0.4 | 508 | 12/11/2021 | |
14.0.3 | 526 | 12/5/2021 | |
14.0.2 | 2,312 | 11/26/2021 | |
14.0.1 | 6,357 | 11/24/2021 | |
14.0.0 | 1,450 | 11/20/2021 | |
13.2.2 | 1,272 | 11/9/2021 | |
13.2.1 | 605 | 11/7/2021 | |
13.2.0 | 582 | 11/6/2021 | |
13.0.0 | 532 | 11/3/2021 | |
12.1.0 | 721 | 10/30/2021 | |
12.0.1 | 605 | 10/30/2021 | |
12.0.0 | 644 | 10/28/2021 | |
11.0.4 | 2,858 | 10/15/2021 | |
11.0.3 | 1,218 | 10/7/2021 | |
11.0.1 | 746 | 10/3/2021 | |
11.0.0 | 601 | 10/2/2021 | |
10.2.1 | 598 | 9/30/2021 | |
10.2.0 | 579 | 9/27/2021 | |
10.1.0 | 526 | 9/26/2021 | |
10.0.7 | 562 | 9/26/2021 | |
10.0.6 | 640 | 9/24/2021 | |
10.0.5 | 603 | 9/23/2021 | |
10.0.4 | 576 | 9/16/2021 | |
10.0.3 | 733 | 9/15/2021 | |
10.0.2 | 725 | 9/8/2021 | |
10.0.1 | 1,605 | 9/4/2021 | |
10.0.0 | 596 | 9/4/2021 | |
9.1.1 | 758 | 8/26/2021 | |
9.1.0 | 602 | 8/26/2021 | |
9.0.1 | 1,709 | 8/21/2021 | |
9.0.0 | 589 | 8/21/2021 | |
8.3.1 | 791 | 8/18/2021 | |
8.3.0 | 626 | 8/12/2021 | |
8.2.2 | 592 | 8/11/2021 | |
8.2.1 | 585 | 8/11/2021 | |
8.2.0 | 599 | 8/11/2021 | |
8.1.0 | 432 | 8/9/2021 | |
8.0.1 | 693 | 8/2/2021 | |
8.0.0 | 616 | 8/2/2021 | |
7.0.0 | 674 | 8/2/2021 | |
6.0.0 | 690 | 7/31/2021 | |
5.1.0 | 730 | 7/31/2021 | |
5.0.0 | 648 | 7/29/2021 | |
4.1.1 | 630 | 7/28/2021 | |
4.1.0 | 489 | 7/28/2021 | |
4.0.5 | 658 | 7/27/2021 | |
4.0.4 | 630 | 7/22/2021 | |
4.0.3 | 641 | 7/17/2021 | |
4.0.2 | 599 | 7/14/2021 | |
4.0.1 | 698 | 7/12/2021 | |
4.0.0 | 600 | 7/11/2021 | |
3.10.13 | 623 | 7/5/2021 | |
3.10.12 | 515 | 7/3/2021 | |
3.10.11 | 460 | 7/1/2021 | |
3.10.10 | 821 | 6/14/2021 | |
3.10.9 | 435 | 6/10/2021 | |
3.10.9-beta1 | 382 | 5/30/2021 | |
3.10.8 | 715 | 5/28/2021 | |
3.10.7 | 648 | 5/23/2021 | |
3.10.6 | 636 | 5/20/2021 | |
3.10.5 | 417 | 5/11/2021 | |
3.10.4 | 501 | 5/11/2021 | |
3.10.3 | 626 | 5/4/2021 | |
3.10.2 | 614 | 4/22/2021 | |
3.10.1 | 585 | 4/15/2021 | |
3.10.0 | 625 | 4/10/2021 | |
3.9.0 | 426 | 4/8/2021 | |
3.8.0 | 598 | 4/5/2021 | |
3.7.5 | 639 | 4/4/2021 | |
3.7.4 | 588 | 3/29/2021 | |
3.7.3 | 586 | 3/29/2021 | |
3.7.2 | 620 | 3/28/2021 | |
3.7.1 | 568 | 3/27/2021 | |
3.7.0 | 587 | 3/27/2021 | |
3.6.0 | 597 | 3/26/2021 | |
3.5.4 | 574 | 3/25/2021 | |
3.5.3 | 611 | 3/25/2021 | |
3.5.2 | 451 | 3/22/2021 | |
3.5.1 | 647 | 3/16/2021 | |
3.5.0 | 589 | 3/16/2021 | |
3.4.2 | 616 | 3/14/2021 | |
3.4.1 | 591 | 3/13/2021 | |
3.4.0 | 637 | 3/11/2021 | |
3.3.1 | 480 | 3/11/2021 | |
3.3.0 | 680 | 3/6/2021 | |
3.2.2 | 623 | 3/1/2021 | |
3.2.1 | 699 | 3/1/2021 | |
3.2.0 | 453 | 2/28/2021 | |
3.1.2 | 602 | 2/28/2021 | |
3.1.1 | 453 | 2/24/2021 | |
3.1.0 | 491 | 2/23/2021 | |
3.0.0 | 447 | 2/23/2021 | |
2.0.6 | 592 | 2/22/2021 | |
2.0.5 | 538 | 2/22/2021 | |
2.0.4 | 564 | 2/21/2021 | |
2.0.3 | 610 | 2/13/2021 | |
2.0.2 | 596 | 2/12/2021 | |
2.0.1 | 410 | 2/11/2021 | |
2.0.0 | 423 | 2/10/2021 | |
1.3.13 | 454 | 2/6/2021 | |
1.3.12 | 466 | 2/5/2021 | |
1.3.11 | 416 | 1/29/2021 | |
1.3.10 | 405 | 1/27/2021 | |
1.3.9 | 469 | 1/21/2021 | |
1.3.8 | 468 | 1/21/2021 | |
1.3.7 | 456 | 1/20/2021 | |
1.3.6 | 471 | 1/17/2021 | |
1.3.5 | 519 | 1/10/2021 | |
1.3.4 | 525 | 1/10/2021 | |
1.3.3 | 427 | 1/10/2021 | |
1.3.2 | 493 | 1/9/2021 | |
1.3.1 | 532 | 1/1/2021 | |
1.3.0 | 539 | 1/1/2021 | |
1.2.1 | 495 | 12/30/2020 | |
1.2.0 | 462 | 12/27/2020 | |
1.1.2 | 434 | 12/26/2020 | |
1.1.1 | 440 | 12/26/2020 | |
1.1.0 | 522 | 12/26/2020 | |
1.0.1 | 595 | 12/25/2020 | |
1.0.0 | 446 | 12/25/2020 | |
1.0.0-beta9 | 315 | 12/18/2020 | |
1.0.0-beta8 | 304 | 12/10/2020 | |
1.0.0-beta7 | 319 | 11/26/2020 | |
1.0.0-beta6 | 298 | 11/15/2020 | |
1.0.0-beta5 | 358 | 11/14/2020 | |
1.0.0-beta4 | 337 | 11/9/2020 | |
1.0.0-beta11 | 276 | 12/23/2020 |
Update dependencies.
Implement support for user applications.
Implement support for parsing partial messages.
Update maximum command length.