@@ -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 | |||
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. | |||
## 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 | |||
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 | |||
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. | |||
@@ -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 | |||
[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, | |||
dependency MyExternalDependency was not found.`, you may have | |||
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` | |||
in its constructor, the `DatabaseService` must be present in the | |||
[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)] | |||
[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? | |||
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 O2Auth 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 you have `Manage Server` permission of. | |||
 | |||
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? | |||
@@ -11,8 +11,8 @@ public class CommandHandler | |||
public CommandHandler(DiscordSocketClient client) | |||
{ | |||
_services = new ServiceCollection() | |||
.AddService<CommandService>() | |||
.AddService(client) | |||
.AddSingleton<CommandService>() | |||
.AddSingleton(client) | |||
// We are missing DatabaseService! | |||
.BuildServiceProvider(); | |||
} | |||
@@ -25,5 +25,8 @@ public class CommandHandler | |||
// registered in this instance of _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? | |||
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? | |||
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? | |||
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. | |||
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. | |||
## 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 | |||
[Interactions FAQ]: xref: FAQ.Basics.Interactions | |||
[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? | |||
@@ -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!' | |||
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 computers clock is out of sync or your 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] | |||
> 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? | |||
@@ -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? | |||
 | |||
## 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? | |||
If you are registering your commands for the first time, it is required to create them once. |
@@ -0,0 +1,45 @@ | |||
--- | |||
uid: FAQ.Interactions.Basics | |||
title: Interaction Basics | |||
--- | |||
# 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 | |||
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. | |||
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 | |||
versions and will likely not be fixed in the version branch due to | |||
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 | |||
@@ -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 | |||
@@ -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? | |||
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 | |||
guild or channel (*e.g., `GuildPermission.Administrator`, | |||
`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 | |||
[Preconditions Addons]: https://github.com/Joe4evr/Discord.Addons/tree/master/src/Discord.Addons.Preconditions | |||
## Why am I getting an error about `Assembly.GetEntryAssembly`? | |||
@@ -6,15 +6,19 @@ | |||
topicUid: FAQ.Basics.BasicOp | |||
- name: Client Basics | |||
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 | |||
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 | |||
topicUid: FAQ.Legacy |