diff --git a/docs/faq/commands/dependency-injection.md b/docs/faq/basics/dependency-injection.md similarity index 71% rename from docs/faq/commands/dependency-injection.md rename to docs/faq/basics/dependency-injection.md index d6b7f8b58..fe5686797 100644 --- a/docs/faq/commands/dependency-injection.md +++ b/docs/faq/basics/dependency-injection.md @@ -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 diff --git a/docs/faq/basics/getting-started.md b/docs/faq/basics/getting-started.md index dc4b11548..6774a36f9 100644 --- a/docs/faq/basics/getting-started.md +++ b/docs/faq/basics/getting-started.md @@ -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. + +![Scopes](images/scopes.png) + +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. + +![Permissions](images/permissions.png) + +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. + +![Invite](images/link.png) + +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? diff --git a/docs/faq/basics/images/link.png b/docs/faq/basics/images/link.png new file mode 100644 index 000000000..dd6b520ab Binary files /dev/null and b/docs/faq/basics/images/link.png differ diff --git a/docs/faq/basics/images/permissions.png b/docs/faq/basics/images/permissions.png new file mode 100644 index 000000000..6bd52c754 Binary files /dev/null and b/docs/faq/basics/images/permissions.png differ diff --git a/docs/faq/basics/images/scopes.png b/docs/faq/basics/images/scopes.png new file mode 100644 index 000000000..8511908d5 Binary files /dev/null and b/docs/faq/basics/images/scopes.png differ diff --git a/docs/faq/commands/samples/DI.cs b/docs/faq/basics/samples/DI.cs similarity index 100% rename from docs/faq/commands/samples/DI.cs rename to docs/faq/basics/samples/DI.cs diff --git a/docs/faq/commands/samples/missing-dep.cs b/docs/faq/basics/samples/missing-dep.cs similarity index 82% rename from docs/faq/commands/samples/missing-dep.cs rename to docs/faq/basics/samples/missing-dep.cs index d3fb9085b..4fd034ef8 100644 --- a/docs/faq/commands/samples/missing-dep.cs +++ b/docs/faq/basics/samples/missing-dep.cs @@ -11,8 +11,8 @@ public class CommandHandler public CommandHandler(DiscordSocketClient client) { _services = new ServiceCollection() - .AddService() - .AddService(client) + .AddSingleton() + .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! } -} \ No newline at end of file +} diff --git a/docs/faq/commands/interaction.md b/docs/faq/int_framework/framework.md similarity index 52% rename from docs/faq/commands/interaction.md rename to docs/faq/int_framework/framework.md index db61bc3f5..793b44d3e 100644 --- a/docs/faq/commands/interaction.md +++ b/docs/faq/int_framework/framework.md @@ -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 diff --git a/docs/faq/basics/interactions.md b/docs/faq/int_framework/general.md similarity index 54% rename from docs/faq/basics/interactions.md rename to docs/faq/int_framework/general.md index 33b89ac2d..c3157e608 100644 --- a/docs/faq/basics/interactions.md +++ b/docs/faq/int_framework/general.md @@ -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? -![Scope check](images/scope.png) - -## 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. diff --git a/docs/faq/basics/images/scope.png b/docs/faq/int_framework/images/scope.png similarity index 100% rename from docs/faq/basics/images/scope.png rename to docs/faq/int_framework/images/scope.png diff --git a/docs/faq/int_framework/manual.md b/docs/faq/int_framework/manual.md new file mode 100644 index 000000000..a47ca0c7a --- /dev/null +++ b/docs/faq/int_framework/manual.md @@ -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 + +![Scope check](images/scope.png) + +## 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. diff --git a/docs/faq/int_framework/samples/interactionsyncing.cs b/docs/faq/int_framework/samples/interactionsyncing.cs new file mode 100644 index 000000000..64066194a --- /dev/null +++ b/docs/faq/int_framework/samples/interactionsyncing.cs @@ -0,0 +1,6 @@ +DiscordSocketConfig config = new() +{ + UseInteractionSnowflakeDate = false +}; + +DiscordSocketclient client = new(config); diff --git a/docs/faq/int_framework/samples/propertyinjection.cs b/docs/faq/int_framework/samples/propertyinjection.cs new file mode 100644 index 000000000..fcacd52d1 --- /dev/null +++ b/docs/faq/int_framework/samples/propertyinjection.cs @@ -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; } +} diff --git a/docs/faq/basics/samples/registerint.cs b/docs/faq/int_framework/samples/registerint.cs similarity index 100% rename from docs/faq/basics/samples/registerint.cs rename to docs/faq/int_framework/samples/registerint.cs diff --git a/docs/faq/misc/legacy.md b/docs/faq/misc/legacy.md index fbfb41ac2..0b0b51159 100644 --- a/docs/faq/misc/legacy.md +++ b/docs/faq/misc/legacy.md @@ -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 diff --git a/docs/faq/commands/general.md b/docs/faq/text_commands/general.md similarity index 89% rename from docs/faq/commands/general.md rename to docs/faq/text_commands/general.md index cff078746..202ceb299 100644 --- a/docs/faq/commands/general.md +++ b/docs/faq/text_commands/general.md @@ -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`? diff --git a/docs/faq/commands/samples/Remainder.cs b/docs/faq/text_commands/samples/Remainder.cs similarity index 100% rename from docs/faq/commands/samples/Remainder.cs rename to docs/faq/text_commands/samples/Remainder.cs diff --git a/docs/faq/commands/samples/runmode-cmdattrib.cs b/docs/faq/text_commands/samples/runmode-cmdattrib.cs similarity index 100% rename from docs/faq/commands/samples/runmode-cmdattrib.cs rename to docs/faq/text_commands/samples/runmode-cmdattrib.cs diff --git a/docs/faq/commands/samples/runmode-cmdconfig.cs b/docs/faq/text_commands/samples/runmode-cmdconfig.cs similarity index 100% rename from docs/faq/commands/samples/runmode-cmdconfig.cs rename to docs/faq/text_commands/samples/runmode-cmdconfig.cs diff --git a/docs/faq/toc.yml b/docs/faq/toc.yml index 2f04dc98c..97e327aba 100644 --- a/docs/faq/toc.yml +++ b/docs/faq/toc.yml @@ -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