* FAQ rework, replacing outdated info, better interaction faq * Update docs/faq/basics/getting-started.md Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update docs/faq/basics/getting-started.md Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update docs/faq/int_framework/general.md Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * fix TOC reference Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> Co-authored-by: Quin Lynch <lynchquin@gmail.com>tags/3.4.0
@@ -1,12 +1,12 @@ | |||||
--- | --- | ||||
uid: FAQ.Commands.DI | |||||
title: Questions about Dependency Injection with Commands | |||||
uid: FAQ.Basics.DI | |||||
title: Questions about Dependency Injection. | |||||
--- | --- | ||||
# Dependency-injection-related Questions | # Dependency-injection-related Questions | ||||
In the following section, you will find common questions and answers | In the following section, you will find common questions and answers | ||||
to utilizing dependency injection with @Discord.Commands, as well as | |||||
to utilizing dependency injection with @Discord.Commands and @Discord.Interactions, as well as | |||||
common troubleshooting steps regarding DI. | common troubleshooting steps regarding DI. | ||||
## What is a service? Why does my module not hold any data after execution? | ## What is a service? Why does my module not hold any data after execution? | ||||
@@ -22,8 +22,7 @@ Service is often used to hold data externally so that they persist | |||||
throughout execution. Think of it like a chest that holds | throughout execution. Think of it like a chest that holds | ||||
whatever you throw at it that won't be affected by anything unless | whatever you throw at it that won't be affected by anything unless | ||||
you want it to. Note that you should also learn Microsoft's | you want it to. Note that you should also learn Microsoft's | ||||
implementation of [Dependency Injection] \([video]) before proceeding, | |||||
as well as how it works in [Discord.Net](xref:Guides.TextCommands.DI#usage-in-modules). | |||||
implementation of [Dependency Injection] \([video]) before proceeding. | |||||
A brief example of service and dependency injection can be seen below. | A brief example of service and dependency injection can be seen below. | ||||
@@ -32,18 +31,12 @@ A brief example of service and dependency injection can be seen below. | |||||
[Dependency Injection]: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection | [Dependency Injection]: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection | ||||
[video]: https://www.youtube.com/watch?v=QtDTfn8YxXg | [video]: https://www.youtube.com/watch?v=QtDTfn8YxXg | ||||
## Why is my `CommandService` complaining about a missing dependency? | |||||
## Why is my Command/Interaction Service complaining about a missing dependency? | |||||
If you encounter an error similar to `Failed to create MyModule, | If you encounter an error similar to `Failed to create MyModule, | ||||
dependency MyExternalDependency was not found.`, you may have | dependency MyExternalDependency was not found.`, you may have | ||||
forgotten to add the external dependency to the dependency container. | forgotten to add the external dependency to the dependency container. | ||||
Starting from Discord.Net 2.0, all dependencies required by each | |||||
module must be present when the module is loaded into the | |||||
[CommandService]. This means when loading the module, you must pass a | |||||
valid [IServiceProvider] with the dependency loaded before the module | |||||
can be successfully registered. | |||||
For example, if your module, `MyModule`, requests a `DatabaseService` | For example, if your module, `MyModule`, requests a `DatabaseService` | ||||
in its constructor, the `DatabaseService` must be present in the | in its constructor, the `DatabaseService` must be present in the | ||||
[IServiceProvider] when registering `MyModule`. | [IServiceProvider] when registering `MyModule`. | ||||
@@ -51,4 +44,3 @@ in its constructor, the `DatabaseService` must be present in the | |||||
[!code-csharp[Missing Dependencies](samples/missing-dep.cs)] | [!code-csharp[Missing Dependencies](samples/missing-dep.cs)] | ||||
[IServiceProvider]: xref:System.IServiceProvider | [IServiceProvider]: xref:System.IServiceProvider | ||||
[CommandService]: xref:Discord.Commands.CommandService |
@@ -11,18 +11,32 @@ introduction to the Discord API ecosystem. | |||||
## How do I add my bot to my server/guild? | ## How do I add my bot to my server/guild? | ||||
You can do so by using the [permission calculator] provided | |||||
by [FiniteReality]. | |||||
This tool allows you to set permissions that the bot will be assigned | |||||
with, and invite the bot into your guild. With this method, bots will | |||||
also be assigned a unique role that a regular user cannot use; this | |||||
is what we call a `Managed` role. Because you cannot assign this | |||||
role to any other users, it is much safer than creating a single | |||||
role which, intentionally or not, can be applied to other users | |||||
to escalate their privilege. | |||||
[FiniteReality]: https://github.com/FiniteReality/permissions-calculator | |||||
[permission calculator]: https://finitereality.github.io/permissions-calculator | |||||
Inviting your bot can be done by using the OAuth2 url generator provided by the [Discord Developer Portal]. | |||||
Permissions can be granted by selecting the `bot` scope in the scopes section. | |||||
 | |||||
A permissions tab will appear below the scope selection, | |||||
from which you can pick any permissions your bot may require to function. | |||||
When invited, the role this bot is granted will include these permissions. | |||||
If you grant no permissions, no role will be created for your bot upon invitation as there is no need for one. | |||||
 | |||||
When done selecting permissions, you can use the link below in your browser to invite the bot | |||||
to servers where you have the `Manage Server` permission. | |||||
 | |||||
If you are planning to play around with slash/context commands, | |||||
make sure to check the `application commands` scope before inviting your bot! | |||||
> [!NOTE] | |||||
> You do not have to kick and reinvite your bot to update permissions/scopes later on. | |||||
> Simply reusing the invite link with provided scopes/perms will update it accordingly. | |||||
[Discord Developer Portal]: https://discord.com/developers/applications/ | |||||
## What is a token? | ## What is a token? | ||||
@@ -11,8 +11,8 @@ public class CommandHandler | |||||
public CommandHandler(DiscordSocketClient client) | public CommandHandler(DiscordSocketClient client) | ||||
{ | { | ||||
_services = new ServiceCollection() | _services = new ServiceCollection() | ||||
.AddService<CommandService>() | |||||
.AddService(client) | |||||
.AddSingleton<CommandService>() | |||||
.AddSingleton(client) | |||||
// We are missing DatabaseService! | // We are missing DatabaseService! | ||||
.BuildServiceProvider(); | .BuildServiceProvider(); | ||||
} | } | ||||
@@ -25,5 +25,8 @@ public class CommandHandler | |||||
// registered in this instance of _services. | // registered in this instance of _services. | ||||
await _commands.AddModulesAsync(Assembly.GetEntryAssembly(), _services); | await _commands.AddModulesAsync(Assembly.GetEntryAssembly(), _services); | ||||
// ... | // ... | ||||
// The same approach applies to the interaction service. | |||||
// Make sure to resolve these issues! | |||||
} | } | ||||
} | |||||
} |
@@ -1,34 +1,54 @@ | |||||
--- | --- | ||||
uid: FAQ.Commands.Interactions | |||||
title: Interaction service | |||||
uid: FAQ.Interactions.Framework | |||||
title: Interaction Framework | |||||
--- | --- | ||||
# Interaction commands in services | |||||
# The Interaction Framework | |||||
A chapter talking about the interaction service framework. | |||||
For questions about interactions in general, refer to the [Interactions FAQ] | |||||
Common misconceptions and questions about the Interaction Framework. | |||||
## How can I restrict some of my commands so only specific users can execute them? | |||||
Based on how you want to implement the restrictions, you can use the | |||||
built-in `RequireUserPermission` precondition, which allows you to | |||||
restrict the command based on the user's current permissions in the | |||||
guild or channel (*e.g., `GuildPermission.Administrator`, | |||||
`ChannelPermission.ManageMessages`*). | |||||
[RequireUserPermission]: xref:Discord.Commands.RequireUserPermissionAttribute | |||||
> [!NOTE] | |||||
> There are many more preconditions to use, including being able to make some yourself. | |||||
> Examples on self-made preconditions can be found | |||||
> [here](https://github.com/discord-net/Discord.Net/blob/dev/samples/InteractionFramework/Attributes/RequireOwnerAttribute.cs) | |||||
## Why do preconditions not hide my commands? | |||||
In the current permission design by Discord, | |||||
it is not very straight forward to limit vision of slash/context commands to users. | |||||
If you want to hide commands, you should take a look at the commands' `DefaultPermissions` parameter. | |||||
## Module dependencies aren't getting populated by Property Injection? | ## Module dependencies aren't getting populated by Property Injection? | ||||
Make sure the properties are publicly accessible and publicly settable. | Make sure the properties are publicly accessible and publicly settable. | ||||
## How do I use this * interaction specific method/property? | |||||
If your interaction context holds a down-casted version of the interaction object, you need to up-cast it. | |||||
Ideally, use pattern matching to make sure its the type of interaction you are expecting it to be. | |||||
[!code-csharp[Property Injection](samples/propertyinjection.cs)] | |||||
## `InteractionService.ExecuteAsync()` always returns a successful result, how do i access the failed command execution results? | ## `InteractionService.ExecuteAsync()` always returns a successful result, how do i access the failed command execution results? | ||||
If you are using `RunMode.Async` you need to setup your post-execution pipeline around `CommandExecuted` events. | |||||
If you are using `RunMode.Async` you need to setup your post-execution pipeline around | |||||
`..Executed` events exposed by the Interaction Service. | |||||
## How do I check if the executing user has * permission? | ## How do I check if the executing user has * permission? | ||||
Refer to the [documentation about preconditions] | Refer to the [documentation about preconditions] | ||||
[documentation about preconditions]: xref:Guides.ChatCommands.Preconditions | |||||
## How do I send the HTTP Response from inside the command modules. | ## How do I send the HTTP Response from inside the command modules. | ||||
Set the `RestResponseCallback` property of [InteractionServiceConfig] with a delegate for handling HTTP Responses and use | Set the `RestResponseCallback` property of [InteractionServiceConfig] with a delegate for handling HTTP Responses and use | ||||
`RestInteractionModuleBase` to create your command modules. `RespondAsync()` and `DeferAsync()` methods of this module base will use the | |||||
`RestInteractionModuleBase` to create your command modules. `RespondWithModalAsync()`, `RespondAsync()` and `DeferAsync()` methods of this module base will use the | |||||
`RestResponseCallback` to create interaction responses. | `RestResponseCallback` to create interaction responses. | ||||
## Is there a cleaner way of creating parameter choices other than using `[Choice]`? | ## Is there a cleaner way of creating parameter choices other than using `[Choice]`? | ||||
@@ -49,4 +69,3 @@ It compares the _target base type_ key of the | |||||
[TypeConverter]: xref:Discord.Interactions.TypeConverter | [TypeConverter]: xref:Discord.Interactions.TypeConverter | ||||
[Interactions FAQ]: xref: FAQ.Basics.Interactions | [Interactions FAQ]: xref: FAQ.Basics.Interactions | ||||
[InteractionServiceConfig]: xref:Discord.Interactions.InteractionServiceConfig | [InteractionServiceConfig]: xref:Discord.Interactions.InteractionServiceConfig | ||||
[documentation about preconditions]: xref: Guides.ChatCommands.Preconditions |
@@ -1,11 +1,13 @@ | |||||
--- | --- | ||||
uid: FAQ.Basics.InteractionBasics | |||||
title: Basics of interactions, common practice | |||||
uid: FAQ.Interactions.General | |||||
title: Interactions | |||||
--- | --- | ||||
# Interactions basics, where to get started | |||||
# Interaction basics | |||||
This section answers basic questions and common mistakes in handling application commands, and responding to them. | |||||
This chapter mostly refers to interactions in general, | |||||
and will include questions that are common among users of the Interaction Framework | |||||
as well as users that register and handle commands manually. | |||||
## What's the difference between RespondAsync, DeferAsync and FollowupAsync? | ## What's the difference between RespondAsync, DeferAsync and FollowupAsync? | ||||
@@ -24,33 +26,20 @@ DeferAsync will not send out a response, RespondAsync will. | |||||
## Im getting System.TimeoutException: 'Cannot respond to an interaction after 3 seconds!' | ## Im getting System.TimeoutException: 'Cannot respond to an interaction after 3 seconds!' | ||||
This happens because your computers clock is out of sync or your trying to respond after 3 seconds. If your clock is out of sync and you cant fix it, you can set the `UseInteractionSnowflakeDate` to false in the config. | |||||
This happens because your computer's clock is out of sync or you're trying to respond after 3 seconds. | |||||
If your clock is out of sync and you can't fix it, you can set the `UseInteractionSnowflakeDate` to false in the [DiscordSocketConfig]. | |||||
## Bad form Exception when I try to create my commands, why do I get this? | |||||
[!code-csharp[Interaction Sync](samples/interactionsyncing.cs)] | |||||
Bad form exceptions are thrown if the slash, user or message command builder has invalid values. | |||||
The following options could resolve your error. | |||||
[DiscordClientConfig]: xref:Discord.WebSocket.DiscordSocketConfig | |||||
#### Is your command name lowercase? | |||||
## How do I use this * interaction specific method/property? | |||||
If your command name is not lowercase, it is not seen as a valid command entry. | |||||
`Avatar` is invalid; `avatar` is valid. | |||||
#### Are your values below or above the required amount? (This also applies to message components) | |||||
Discord expects all values to be below maximum allowed. | |||||
Going over this maximum amount of characters causes an exception. | |||||
If your interaction context holds a down-casted version of the interaction object, you need to up-cast it. | |||||
Ideally, use pattern matching to make sure its the type of interaction you are expecting it to be. | |||||
> [!NOTE] | > [!NOTE] | ||||
> All maximum and minimum value requirements can be found in the [Discord Developer Docs]. | |||||
> For components, structure documentation is found [here]. | |||||
[Discord Developer Docs]: https://discord.com/developers/docs/interactions/application-commands#application-commands | |||||
[here]: https://discord.com/developers/docs/interactions/message-components#message-components | |||||
#### Is your subcommand branching correct? | |||||
Branching structure is covered properly here: xref:Guides.SlashCommands.SubCommand | |||||
> Further documentation on pattern matching can be found [here](xref:Guides.Entities.Casting). | |||||
## My interaction commands are not showing up? | ## My interaction commands are not showing up? | ||||
@@ -65,16 +54,6 @@ Did you register a guild command (should be instant), or waited more than an hou | |||||
- Do you have the application commands scope checked when adding your bot to guilds? | - Do you have the application commands scope checked when adding your bot to guilds? | ||||
 | |||||
## There are many options for creating commands, which do I use? | |||||
[!code-csharp[Register examples](samples/registerint.cs)] | |||||
> [!NOTE] | |||||
> You can use bulkoverwrite even if there are no commands in guild, nor globally. | |||||
> The bulkoverwrite method disposes the old set of commands and replaces it with the new. | |||||
## Do I need to create commands on startup? | ## Do I need to create commands on startup? | ||||
If you are registering your commands for the first time, it is required to create them once. | If you are registering your commands for the first time, it is required to create them once. |
@@ -0,0 +1,45 @@ | |||||
--- | |||||
uid: FAQ.Interactions.Manual | |||||
title: Manual handling | |||||
--- | |||||
# Manually handing interactions. | |||||
This section talks about the manual building and responding to interactions. | |||||
If you are using the interaction framework (highly recommended) this section does not apply to you. | |||||
## Bad form Exception when I try to create my commands, why do I get this? | |||||
Bad form exceptions are thrown if the slash, user or message command builder has invalid values. | |||||
The following options could resolve your error. | |||||
#### Is your command name lowercase? | |||||
If your command name is not lowercase, it is not seen as a valid command entry. | |||||
`Avatar` is invalid; `avatar` is valid. | |||||
#### Are your values below or above the required amount? (This also applies to message components) | |||||
Discord expects all values to be below maximum allowed. | |||||
Going over this maximum amount of characters causes an exception. | |||||
> [!NOTE] | |||||
> All maximum and minimum value requirements can be found in the [Discord Developer Docs]. | |||||
> For components, structure documentation is found [here]. | |||||
[Discord Developer Docs]: https://discord.com/developers/docs/interactions/application-commands#application-commands | |||||
[here]: https://discord.com/developers/docs/interactions/message-components#message-components | |||||
#### Is your subcommand branching correct? | |||||
Branching structure is covered properly here: xref:Guides.SlashCommands.SubCommand | |||||
 | |||||
## There are many options for creating commands, which do I use? | |||||
[!code-csharp[Register examples](samples/registerint.cs)] | |||||
> [!NOTE] | |||||
> You can use bulkoverwrite even if there are no commands in guild, nor globally. | |||||
> The bulkoverwrite method disposes the old set of commands and replaces it with the new. |
@@ -0,0 +1,6 @@ | |||||
DiscordSocketConfig config = new() | |||||
{ | |||||
UseInteractionSnowflakeDate = false | |||||
}; | |||||
DiscordSocketclient client = new(config); |
@@ -0,0 +1,8 @@ | |||||
public class MyModule | |||||
{ | |||||
// Intended. | |||||
public InteractionService Service { get; set; } | |||||
// Will not work. A private setter cannot be accessed by the serviceprovider. | |||||
private InteractionService Service { get; private set; } | |||||
} |
@@ -8,15 +8,32 @@ title: Questions about Legacy Versions | |||||
This section refers to legacy library-related questions that do not | This section refers to legacy library-related questions that do not | ||||
apply to the latest or recent version of the Discord.Net library. | apply to the latest or recent version of the Discord.Net library. | ||||
## Migrating your commands to application commands. | |||||
The new interaction service was designed to act like the previous service for text-based commands. | |||||
Your pre-existing code will continue to work, but you will need to migrate your modules and response functions to use the new | |||||
interaction service methods. Documentation on this can be found in the [Guides](xref:Guides.IntFw.Intro). | |||||
## Gateway event parameters changed, why? | |||||
With 3.0, a higher focus on [Cacheable]'s was introduced. | |||||
[Cacheable]'s get an entity from cache, rather than making an API call to retrieve it's data. | |||||
The entity can be retrieved from cache by calling `GetOrDownloadAsync()` on the [Cacheable] type. | |||||
> [!NOTE] | |||||
> GetOrDownloadAsync will download the entity if its not available directly from the cache. | |||||
[Cacheable]: xref:Discord.Cacheable | |||||
## X, Y, Z does not work! It doesn't return a valid value anymore. | ## X, Y, Z does not work! It doesn't return a valid value anymore. | ||||
If you are currently using an older version of the stable branch, | If you are currently using an older version of the stable branch, | ||||
please upgrade to the latest pre-release version to ensure maximum | |||||
please upgrade to the latest release version to ensure maximum | |||||
compatibility. Several features may be broken in older | compatibility. Several features may be broken in older | ||||
versions and will likely not be fixed in the version branch due to | versions and will likely not be fixed in the version branch due to | ||||
their breaking nature. | their breaking nature. | ||||
Visit the repo's [release tag] to see the latest public pre-release. | |||||
Visit the repo's [release tag] to see the latest public release. | |||||
[release tag]: https://github.com/discord-net/Discord.Net/releases | [release tag]: https://github.com/discord-net/Discord.Net/releases | ||||
@@ -1,6 +1,6 @@ | |||||
--- | --- | ||||
uid: FAQ.Commands.General | |||||
title: General Questions about chat Commands | |||||
uid: FAQ.TextCommands.General | |||||
title: General Questions about Text Commands | |||||
--- | --- | ||||
# Chat Command-related Questions | # Chat Command-related Questions | ||||
@@ -10,21 +10,16 @@ answered regarding general command usage when using @Discord.Commands. | |||||
## How can I restrict some of my commands so only specific users can execute them? | ## How can I restrict some of my commands so only specific users can execute them? | ||||
Based on how you want to implement the restrictions, you can use the | |||||
built-in [RequireUserPermission] precondition, which allows you to | |||||
You can use the built-in `RequireUserPermission` precondition, which allows you to | |||||
restrict the command based on the user's current permissions in the | restrict the command based on the user's current permissions in the | ||||
guild or channel (*e.g., `GuildPermission.Administrator`, | guild or channel (*e.g., `GuildPermission.Administrator`, | ||||
`ChannelPermission.ManageMessages`*). | `ChannelPermission.ManageMessages`*). | ||||
If, however, you wish to restrict the commands based on the user's | |||||
role, you can either create your custom precondition or use | |||||
Joe4evr's [Preconditions Addons] that provides a few custom | |||||
preconditions that aren't provided in the stock library. | |||||
Its source can also be used as an example for creating your | |||||
custom preconditions. | |||||
> [!NOTE] | |||||
> There are many more preconditions to use, including being able to make some yourself. | |||||
> Precondition documentation is covered [here](xref:Guides.TextCommands.Preconditions) | |||||
[RequireUserPermission]: xref:Discord.Commands.RequireUserPermissionAttribute | [RequireUserPermission]: xref:Discord.Commands.RequireUserPermissionAttribute | ||||
[Preconditions Addons]: https://github.com/Joe4evr/Discord.Addons/tree/master/src/Discord.Addons.Preconditions | |||||
## Why am I getting an error about `Assembly.GetEntryAssembly`? | ## Why am I getting an error about `Assembly.GetEntryAssembly`? | ||||
@@ -6,15 +6,19 @@ | |||||
topicUid: FAQ.Basics.BasicOp | topicUid: FAQ.Basics.BasicOp | ||||
- name: Client Basics | - name: Client Basics | ||||
topicUid: FAQ.Basics.ClientBasics | topicUid: FAQ.Basics.ClientBasics | ||||
- name: Interactions | |||||
topicUid: FAQ.Basics.InteractionBasics | |||||
- name: Commands | |||||
items: | |||||
- name: String commands | |||||
topicUid: FAQ.Commands.General | |||||
- name: Interaction commands | |||||
topicUid: FAQ.Commands.Interactions | |||||
- name: Dependency Injection | - name: Dependency Injection | ||||
topicUid: FAQ.Commands.DI | |||||
topicUid: FAQ.Basics.DI | |||||
- name: Interactions | |||||
items: | |||||
- name: Starting out | |||||
topicUid: FAQ.Interactions.General | |||||
- name: Interaction Service/Framework | |||||
topicUid: FAQ.Interactions.Framework | |||||
- name: Manual handling | |||||
topicUid: FAQ.Interactions.Manual | |||||
- name: Text Commands | |||||
items: | |||||
- name: Text Command basics | |||||
topicUid: FAQ.TextCommands.General | |||||
- name: Legacy or Upgrade | - name: Legacy or Upgrade | ||||
topicUid: FAQ.Legacy | topicUid: FAQ.Legacy |