| @@ -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 | |||