diff --git a/DisCatSharp.Docs/articles/application_commands/intro.md b/DisCatSharp.Docs/articles/application_commands/intro.md index 605a61951..286240fe7 100644 --- a/DisCatSharp.Docs/articles/application_commands/intro.md +++ b/DisCatSharp.Docs/articles/application_commands/intro.md @@ -1,133 +1,133 @@ --- uid: application_commands_intro title: Application Commands Introduction --- >[!NOTE] > This article assumes you've recently read the article on *[writing your first bot](xref:basics_first_bot)*. # Introduction to App Commands Discord provides built-in commands called: *Application Commands*.
Be sure to install the `DisCatSharp.ApplicationCommands` package from NuGet before continuing. At the moment it is possible to create such commands: - Slash commands - User context menu commands - Message context menu commands ## Writing an Application Commands ### Creation of the first commands >[!NOTE] > In order for the bot to be able to create commands in the guild, it must be added to a guild with `applications.commands` scope. -Each command is a method with the attribute [SlashCommand](xref:DisCatSharp.ApplicationCommands.SlashCommandAttribute) or [ContextMenu](xref:DisCatSharp.ApplicationCommands.ContextMenuAttribute). They must be in classes that inherit from [ApplicationCommandsModule](xref:DisCatSharp.ApplicationCommands.ApplicationCommandsModule). -Also, the first argument to the method must be [InteractionContext](xref:DisCatSharp.ApplicationCommands.InteractionContext) or [ContextMenuContext](xref:DisCatSharp.ApplicationCommands.ContextMenuContext). +Each command is a method with the attribute [SlashCommand](xref:DisCatSharp.ApplicationCommands.Attributes.SlashCommandAttribute) or [ContextMenu](xref:DisCatSharp.ApplicationCommands.Attributes.ContextMenuAttribute). They must be in classes that inherit from [ApplicationCommandsModule](xref:DisCatSharp.ApplicationCommands.ApplicationCommandsModule). +Also, the first argument to the method must be [InteractionContext](xref:DisCatSharp.ApplicationCommands.Context.InteractionContext) or [ContextMenuContext](xref:DisCatSharp.ApplicationCommands.Context.ContextMenuContext). Simple slash command: ```cs public class MyCommand : ApplicationCommandsModule { [SlashCommand("my_command", "This is description of the command.")] public async Task MySlashCommand(InteractionContext context) { } } ``` Simple context menu command: ```cs public class MySecondCommand : ApplicationCommandsModule { [ContextMenu(ApplicationCommandType.User, "My Command")] public async Task MyContextMenuCommand(ContextMenuContext context) { } } ``` Now let's add some actions to the commands, for example, send a reply: ```cs await context.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder() { Content = "Hello :3" }); ``` If the command will be executed for more than 3 seconds, we must response at the beginning of execution and edit it at the end. ```cs await context.CreateResponseAsync(InteractionResponseType.DeferredChannelMessageWithSource, new DiscordInteractionResponseBuilder()); await Task.Delay(5000); // Simulating a long command execution. await ctx.EditResponseAsync(new DiscordWebhookBuilder() { Content = "Hello :3" }); ``` >[!NOTE] > Note that you can make your commands static, but then you cannot use [Dependency Injection](xref:commands_dependency_injection) in them. ### Registration of commands After writing the commands, we must register them. For this we need a [DiscordClient](xref:DisCatSharp.DiscordClient). ```cs var appCommands = client.UseApplicationCommands(); appCommands.RegisterGlobalCommands(); appCommands.RegisterGlobalCommands(); ``` Simple, isn't it? You can register global and guild commands. Global commands will be available on all guilds of which the bot is a member. Guild commands will only appear in a specific guild. >[!NOTE] >Global commands are updated within an hour, so it is recommended to use guild commands for testing and development. To register guild commands, it is enough to specify the Id of the guild as the first argument of the registration method. ```cs var appCommands = client.UseApplicationCommands(); appCommands.RegisterGuildCommands(); appCommands.RegisterGuildCommands(); ``` ## Command Groups Sometimes we may need to combine slash commands into groups. -In this case, we need to wrap our class with commands in another class and add the [SlashCommandGroup](xref:DisCatSharp.ApplicationCommands.SlashCommandGroupAttribute) attribute. +In this case, we need to wrap our class with commands in another class and add the [SlashCommandGroup](xref:DisCatSharp.ApplicationCommands.Attributes.SlashCommandGroupAttribute) attribute. ```cs public class MyCommand : ApplicationCommandsModule { [SlashCommandGroup("my_command", "This is description of the command group.")] public class MyCommandGroup : ApplicationCommandsModule { [SlashCommand("first", "This is description of the command.")] public async Task MySlashCommand(InteractionContext context) { await context.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder() { Content = "This is first subcommand." }); } [SlashCommand("second", "This is description of the command.")] public async Task MySecondCommand(InteractionContext context) { await context.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder() { Content = "This is second subcommand." }); } } } ``` Commands will now be available via `/my_command first` and `/my_command second`. Also, note that both classes must inherit [ApplicationCommandsModule](xref:DisCatSharp.ApplicationCommands.ApplicationCommandsModule). diff --git a/DisCatSharp.Docs/articles/application_commands/options.md b/DisCatSharp.Docs/articles/application_commands/options.md index 6fc3cc253..f0d2f8f43 100644 --- a/DisCatSharp.Docs/articles/application_commands/options.md +++ b/DisCatSharp.Docs/articles/application_commands/options.md @@ -1,251 +1,251 @@ --- uid: application_commands_options title: Application Commands Options --- # Slash Commands options For slash commands, you can create options. They allow users to submit additional information to commands. Command options can be of the following types: - string - int - long - double - bool - [DiscordUser](xref:DisCatSharp.Entities.DiscordUser) - [DiscordRole](xref:DisCatSharp.Entities.DiscordRole) - [DiscordChannel](xref:DisCatSharp.Entities.DiscordChannel) - [DiscordAttachment](xref:DisCatSharp.Entities.DiscordAttachment) - mentionable (ulong) - Enum ## Basic usage >[!NOTE] >Options can only be added in the slash commands. Context menus do not support this! -All of options must contain the [Option](xref:DisCatSharp.ApplicationCommands.OptionAttribute) attribute. -They should be after [InteractionContext](xref:DisCatSharp.ApplicationCommands.InteractionContext). +All of options must contain the [Option](xref:DisCatSharp.ApplicationCommands.Attributes.OptionAttribute) attribute. +They should be after [InteractionContext](xref:DisCatSharp.ApplicationCommands.Context.InteractionContext). ```cs public class MyCommand : ApplicationCommandsModule { [SlashCommand("my_command", "This is description of the command.")] public static async Task MySlashCommand(InteractionContext context, [Option("argument", "This is description of the option.")] string firstParam) { await context.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder() { Content = firstParam }); } } ``` ## Choices Sometimes, we need to allow users to choose from several pre-created options. We can of course add a string or long parameter and let users guess the options, but why when we can make things more convenient? We have 3 ways to make choices: - Enums -- [Choice Attribute](xref:DisCatSharp.ApplicationCommands.ChoiceAttribute) -- [Choice Providers](xref:DisCatSharp.ApplicationCommands.IChoiceProvider) +- [Choice Attribute](xref:DisCatSharp.ApplicationCommands.Attributes.ChoiceAttribute) +- [Choice Providers](xref:DisCatSharp.ApplicationCommands.Attributes.IChoiceProvider) ### Enums This is the easiest option. We just need to specify the required Enum as a command parameter. ```cs public class MyCommand : ApplicationCommandsModule { [SlashCommand("my_command", "This is description of the command.")] public static async Task MySlashCommand(InteractionContext context, [Option("enum_param", "Description")] MyEnum enumParameter) { } } public enum MyEnum { FirstOption, SecondOption } ``` In this case, the user will be shown this as options: `FirstOption` and `SecondOption`. Therefore, if you want to define different names for options without changing the Enum, you can add a special attribute: ```cs public enum MyEnum { [ChoiceName("First option")] FirstOption, [ChoiceName("Second option")] SecondOption } ``` ### Choice Attribute With this way, you can get rid of unnecessary conversions within the command. -To do this, you need to add one or more [Choice Attributes](xref:DisCatSharp.ApplicationCommands.ChoiceAttribute) before the [Option](xref:DisCatSharp.ApplicationCommands.OptionAttribute) attribute +To do this, you need to add one or more [Choice Attributes](xref:DisCatSharp.ApplicationCommands.Attributes.ChoiceAttribute) before the [Option](xref:DisCatSharp.ApplicationCommands.Attributes.OptionAttribute) attribute ```cs [SlashCommand("my_command", "This is description of the command.")] public static async Task MySlashCommand(InteractionContext context, [Choice("First option", 1)] [Choice("Second option", 2)] [Option("option", "Description")] long firstParam) { } ``` -As the first parameter, [Choice](xref:DisCatSharp.ApplicationCommands.ChoiceAttribute) takes a name that will be visible to the user, and the second - a value that will be passed to the command. +As the first parameter, [Choice](xref:DisCatSharp.ApplicationCommands.Attributes.ChoiceAttribute) takes a name that will be visible to the user, and the second - a value that will be passed to the command. You can also use strings. ### Choice Provider Perhaps the most difficult way. It consists in writing a method that will generate a list of options when registering commands. This way we don't have to list all of them in the code when there are many of them. -To create your own provider, you need to create a class that inherits [IChoiceProvider](xref:DisCatSharp.ApplicationCommands.IChoiceProvider) and contains the `Provider()` method. +To create your own provider, you need to create a class that inherits [IChoiceProvider](xref:DisCatSharp.ApplicationCommands.Attributes.IChoiceProvider) and contains the `Provider()` method. ```cs public class MyChoiceProvider : IChoiceProvider { public Task> Provider() { } } ``` As seen above, the method should return a list of [DiscordApplicationCommandOptionChoice](xref:DisCatSharp.Entities.DiscordApplicationCommandOptionChoice). Now we need to create a list and add items to it: ```cs var options = new List { new DiscordApplicationCommandOptionChoice("First option", 1), new DiscordApplicationCommandOptionChoice("Second option", 2) }; return Task.FromResult(options.AsEnumerable()); ``` Of course you can generate this list as you like. The main thing is that the method should return this list. Now let's add our new provider to the command. ```cs [SlashCommand("my_command", "This is description of the command.")] public static async Task MySlashCommand(InteractionContext context, [ChoiceProvider(typeof(MyChoiceProvider))] [Option("option", "Description")] long option) { } ``` All the code that we got: ```cs public class MyCommand : ApplicationCommandsModule { [SlashCommand("my_command", "This is description of the command.")] public static async Task MySlashCommand(InteractionContext context, [ChoiceProvider(typeof(MyChoiceProvider))] [Option("option", "Description")] long option) { } } public class MyChoiceProvider : IChoiceProvider { public Task> Provider() { var options = new List { new DiscordApplicationCommandOptionChoice("First option", 1), new DiscordApplicationCommandOptionChoice("Second option", 2) }; return Task.FromResult(options.AsEnumerable()); } } ``` That's all, for a better example for [ChoiceProvider](xref:DisCatSharp.ApplicationCommands.IChoiceProvider) refer to the examples. ## Autocomplete Autocomplete works in the same way as ChoiceProvider, with one difference: the method that creates the list of choices is triggered not once when the commands are registered, but whenever the user types a command. It is advisable to use this method exactly when you have a list that will be updated while the bot is running. In other cases, when the choices will not change, it is advisable to use the previous methods. Creating an autocomplete is similar to creating a ChoiceProvider with a few changes: ```cs public class MyAutocompleteProvider : IAutocompleteProvider { public async Task> Provider(AutocompleteContext ctx) { var options = new List { new DiscordApplicationCommandAutocompleteChoice("First option", 1), new DiscordApplicationCommandAutocompleteChoice("Second option", 2) }; return Task.FromResult(options.AsEnumerable()); } } ``` -The changes are that instead of [IChoiceProvider](xref:DisCatSharp.ApplicationCommands.IChoiceProvider), the class inherits [IAutocompleteProvider](xref:DisCatSharp.ApplicationCommands.Attributes.IAutocompleteProvider), and the Provider method should return a list with [DiscordApplicationCommandAutocompleteChoice](xref:DisCatSharp.Entities.DiscordApplicationCommandAutocompleteChoice). +The changes are that instead of [IChoiceProvider](xref:DisCatSharp.ApplicationCommands.Attributes.IChoiceProvider), the class inherits [IAutocompleteProvider](xref:DisCatSharp.ApplicationCommands.Attributes.IAutocompleteProvider), and the Provider method should return a list with [DiscordApplicationCommandAutocompleteChoice](xref:DisCatSharp.Entities.DiscordApplicationCommandAutocompleteChoice). Now we add it to the command: ```cs [SlashCommand("my_command", "This is description of the command.")] public static async Task MySlashCommand(InteractionContext context, [Autocomplete(typeof(MyAutocompleteProvider))] [Option("option", "Description", true)] long option) { } ``` -Note that we have not only replaced [ChoiceProvider](xref:DisCatSharp.ApplicationCommands.ChoiceProviderAttribute) with [Autocomplete](xref:DisCatSharp.ApplicationCommands.Attributes.AutocompleteAttribute), but also added `true` to [Option](xref:DisCatSharp.ApplicationCommands.OptionAttribute). +Note that we have not only replaced [ChoiceProvider](xref:DisCatSharp.ApplicationCommands.Attributes.ChoiceProviderAttribute) with [Autocomplete](xref:DisCatSharp.ApplicationCommands.Attributes.AutocompleteAttribute), but also added `true` to [Option](xref:DisCatSharp.ApplicationCommands.Attributes.OptionAttribute). ## Channel types Sometimes we may need to give users the ability to select only a certain type of channels, for example, only text, or voice channels. This can be done by adding the [ChannelTypes](xref:DisCatSharp.ApplicationCommands.Attributes.ChannelTypesAttribute) attribute to the option with the [DiscordChannel](xref:DisCatSharp.Entities.DiscordChannel) type. ```cs [SlashCommand("my_command", "This is description of the command.")] public static async Task MySlashCommand(InteractionContext context, [Option("channel", "You can select only text channels."), ChannelTypes(ChannelType.Text)] DiscordChannel channel) { } ``` This will make it possible to select only text channels. ## MinimumValue / MaximumValue Attribute Sometimes we may need to give users the ability to select only a certain range of values. This can be done by adding the [MinimumValue](xref:DisCatSharp.ApplicationCommands.Attributes.MinimumValueAttribute) and [MaximumValue](xref:DisCatSharp.ApplicationCommands.Attributes.MaximumValueAttribute) attribute to the option. It can be used only for the types `double`, `int` and `long` tho. ```cs [SlashCommand("my_command", "This is description of the command.")] public static async Task MySlashCommand(InteractionContext context, [Option("number", "You can select only a certain range."), MinimumValue(50), MaximumValue(100)] int numbers) { } ``` ## MinimumLength / MaximumLength Attribute Sometimes we may need to limit the user to a certain string length. This can be done by adding the [MinimumLength](xref:DisCatSharp.ApplicationCommands.Attributes.MinimumLengthAttribute) and [MaximumLength](xref:DisCatSharp.ApplicationCommands.Attributes.MaximumLengthAttribute) attribute to the option. It can be used only for the type `string`. ```cs [SlashCommand("my_command", "This is description of the command.")] public static async Task MySlashCommand(InteractionContext context, [Option("text", "You can only send text with a length between 10 and 50 characters."), MinimumLength(10), MaximumLength(50)] string text) { } ``` diff --git a/DisCatSharp.Docs/articles/application_commands/translations/using.md b/DisCatSharp.Docs/articles/application_commands/translations/using.md index 78f4577bb..dba6a0c9e 100644 --- a/DisCatSharp.Docs/articles/application_commands/translations/using.md +++ b/DisCatSharp.Docs/articles/application_commands/translations/using.md @@ -1,197 +1,197 @@ --- uid: application_commands_translations_using title: Using Translations --- # Using Translations ## Why Do We Outsource Translation In External JSON Files Pretty simple: It's common to have translations external stored. This makes it easier to modify them, while keeping the code itself clean. ## Adding Translations Translations are added the same way like permissions are added to Application Commands: ```cs const string TRANSLATION_PATH = "translations/"; Client.GetApplicationCommands().RegisterGuildCommands(1215484634894646844, translations => { string json = File.ReadAllText(TRANSLATION_PATH + "my_command.json"); translations.AddTranslation(json); }); Client.GetApplicationCommands().RegisterGuildCommands(1215484634894646844, translations => { string json = File.ReadAllText(TRANSLATION_PATH + "my_simple_command.json"); translations.AddTranslation(json); }); ``` > [!WARNING] > If you add a translation to a class, you have to supply translations for every command in this class. Otherwise it will fail. ## Creating The Translation JSON We split the translation in two categories. One for slash command groups and one for normal slash commands and context menu commands. The `name` key in the JSON will be mapped to the command / option / choice names internally. ### Translation For Slash Command Groups Imagine, your class look like the following example: ```cs public class MyCommand : ApplicationCommandsModule { [SlashCommandGroup("my_command", "This is description of the command group.")] public class MyCommandGroup : ApplicationCommandsModule { [SlashCommand("first", "This is description of the command.")] public async Task MySlashCommand(InteractionContext context) { await context.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder() { Content = "This is first subcommand." }); } [SlashCommand("second", "This is description of the command.")] public async Task MySecondCommand(InteractionContext context, [Option("value", "Some string value.")] string value) { await context.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder() { Content = "This is second subcommand. The value was " + value }); } } } ``` The translation json is a object of [Command Group Objects](xref:application_commands_translations_reference#command-group-object) A correct translation json for english and german would look like that: ```json [ { "name": "my_command", "name_translations": { "en-US": "my_command", "de": "mein_befehl" }, "description_translations": { "en-US": "This is description of the command group.", "de": "Das ist die description der Befehl Gruppe." }, "commands": [ { "name": "first", "type": 1, // Type 1 for slash command "name_translations": { "en-US": "first", "de": "erste" }, "description_translations": { "en-US": "This is description of the command.", "de": "Das ist die Beschreibung des Befehls." } }, { "name": "second", "type": 1, // Type 1 for slash command "name_translations": { "en-US": "second", "de": "zweite" }, "description_translations": { "en-US": "This is description of the command.", "de": "Das ist die Beschreibung des Befehls." }, "options": [ { "name": "value", "name_translations": { "en-US": "value", "de": "wert" }, "description_translations": { "en-US": "Some string value.", "de": "Ein string Wert." } } ] } ] } ] ``` ### Translation For Slash Commands & Context Menu Commands Now imagine, that your class look like this example: ```cs public class MySimpleCommands : ApplicationCommandsModule { [SlashCommand("my_command", "This is description of the command.")] public async Task MySlashCommand(InteractionContext context) { } [ContextMenu(ApplicationCommandType.User, "My Command")] public async Task MyContextMenuCommand(ContextMenuContext context) { } } ``` The slash command is a simple [Command Object](xref:application_commands_translations_reference#command-object). Same goes for the context menu command, but note that it can't have a description. Slash Commands has the [type](xref:application_commands_translations_reference#application-command-type) `1` and context menu commands the [type](xref:application_commands_translations_reference#application-command-type) `2` or `3`. We use this to determine, where the translation belongs to. A correct json for this example would look like that: ```json [ { "name":"my_command", "type": 1, // Type 1 for slash command "name_translations":{ "en-US":"my_command", "de":"mein_befehl" }, "description_translations":{ "en-US":"This is description of the command.", "de":"Das ist die Beschreibung des Befehls." } }, { "name":"My Command", "type": 2, // Type 2 for user context menu command "name_translations":{ "en-US":"My Command", "de":"Mein Befehl" } } ] ``` ## Available Locales Discord has a limited choice of locales, in particular, the ones you can select in the client. To see the available locales, visit [this](xref:application_commands_translations_reference#valid-locales) page. ## Can We Get The User And Guild Locale? Yes, you can! Discord sends the user on all [interaction types](xref:DisCatSharp.InteractionType), except `Ping`. -We introduced two new properties `Locale` and `GuildLocale` on [InteractionContext](xref:DisCatSharp.ApplicationCommands.InteractionContext), [ContextMenuContext](xref:DisCatSharp.ApplicationCommands.ContextMenuContext), [AutoCompleteContext](xref:DisCatSharp.ApplicationCommands.AutocompleteContext) and [DiscordInteraction](xref:DisCatSharp.Entities.DiscordInteraction). +We introduced two new properties `Locale` and `GuildLocale` on [InteractionContext](xref:DisCatSharp.ApplicationCommands.Context.InteractionContext), [ContextMenuContext](xref:DisCatSharp.ApplicationCommands.Context.ContextMenuContext), [AutoCompleteContext](xref:DisCatSharp.ApplicationCommands.Context.AutocompleteContext) and [DiscordInteraction](xref:DisCatSharp.Entities.DiscordInteraction). `Locale` is the locale of the user and always represented. `GuildLocale` is only represented, when the interaction is **not** in a DM. Furthermore we cache known user locales on the [DiscordUser](xref:DisCatSharp.Entities.DiscordUser#DisCatSharp_Entities_DiscordUser_Locale) object. diff --git a/DisCatSharp.Docs/articles/important_changes/10_0_0.md b/DisCatSharp.Docs/articles/important_changes/10_0_0.md index 3185e016f..ed1299ac3 100644 --- a/DisCatSharp.Docs/articles/important_changes/10_0_0.md +++ b/DisCatSharp.Docs/articles/important_changes/10_0_0.md @@ -1,25 +1,25 @@ --- uid: important_changes_10_0_0 title: Version 10.0.0 --- # Upgrade from **9.9.0** to **10.0.0** ## What is new in DisCatSharp? - Advanced dependency injection system - Support for API v10 - Message content intent - Properly working application command localization - Optimized lib code - Pre-implementation of upcoming things -- Support for [Channel Type](xref:DisCatSharp.ChannelType) `Forum` (WIP) +- Support for [Channel Type](xref:DisCatSharp.Enums.ChannelType) `Forum` (WIP) ## What changed? To get message content with API v10, you have to enable the message content intent in the developer portal AND specify the [DiscordIntent](xref:DisCatSharp.DiscordIntents) `MessageContent`. Otherwise you won't receive message contents from guild messages where the bot isn't mentioned. ## Backwards Compatibility You can always choose to use a previous API version. I.e. if you want to use API V9, you can use `DiscordIntents.AllV9Less` to enable all intents that are valid for this version. diff --git a/DisCatSharp.Docs/faq.md b/DisCatSharp.Docs/faq.md index a39994696..a9dec19b5 100644 --- a/DisCatSharp.Docs/faq.md +++ b/DisCatSharp.Docs/faq.md @@ -1,84 +1,84 @@ --- uid: faq title: Frequently Asked Questions --- # Frequently Asked Questions ### Code I copied from an article isn't compiling or working as expected. Why? *Please use the code snippets as a reference; don't blindly copy-paste code!* The snippets of code in the articles are meant to serve as examples to help you understand how to use a part of the library.
Although most will compile and work at the time of writing, changes to the library over time can make some snippets obsolete.
Many issues can be resolved with Intellisense by searching for similarly named methods and verifying method parameters. ### I'm targeting Mono and have exceptions, crashes, or other problems. As mentioned in the [preamble](xref:preamble), the Mono runtime is inherently unstable and has numerous flaws.
Because of this we do not support Mono in any way, nor will we support any other projects which use it. Instead, we recommend using either the latest LTS release or most recent stable version of [.NET Core](https://dotnet.microsoft.com/download). ### Connecting to a voice channel with VoiceNext will either hang or throw an exception. To troubleshoot, please ensure that: * You are using the latest version of DisCatSharp. * You have properly enabled VoiceNext with your instance of @DisCatSharp.DiscordClient. * You are *not* using VoiceNext in an event handler. * You have [opus and libsodium](xref:voicenext_prerequisites) available in your target environment. ### Why am I getting *heartbeat skipped* message in my console? There are two possible reasons: #### Connection issue between your bot application and Discord. Check your internet connection and ensure that the machine your bot is hosted on has a stable internet connection.
If your local network has no issues, the problem could be with either Discord or Cloudflare. In which case, it's out of your control. #### Complex, long-running code in an event handler. Any event handlers that have the potential to run for more than a few seconds could cause a deadlock, and cause several heartbeats to be skipped. Please take a look at our short article on [handling exceptions](xref:beyond_basics_events) to learn how to avoid this. ### Why am I getting a 4XX error and how can I fix it? HTTP Error Code|Cause|Resolution :---:|:---|:--- `401`|Invalid token.|Verify your token and make sure no errors were made.
The client secret found on the 'general information' tab of your application page *is not* your token. `403`|Not enough permissions.|Verify permissions and ensure your bot account has a role higher than the target user.
Administrator permissions *do not* bypass the role hierarchy. `404`|Requested object not found.|This usually means the entity does not exist. You should reattempt then inform your user. ### I cannot modify a specific user or role. Why is this? In order to modify a user, the highest role of your bot account must be higher than the target user.
Changing the properties of a role requires that your bot account have a role higher than that role. ### Does CommandsNext support dependency injection? It does! Please take a look at our [article](xref:commands_dependency_injection) on the subject. ### Can I use a user token? Automating a user account is against Discord's [Terms of Service](https://dis.gd/terms) and is not supported by DisCatSharp. ### How can I set a custom status? If you mean a *true* custom status like this: ![help](/images/faq_01.png) No, you cannot. Discord does not allow bots to use custom statuses.
However, if you meant an activity like this: ![Bot Presence](/images/faq_02.png) You can use either of the following -* The overload for [ConnectAsync](xref:DisCatSharp.DiscordClient#DisCatSharp_DiscordClient_ConnectAsync_DiscordActivity_System_Nullable_UserStatus__System_Nullable_DateTimeOffset__)([DiscordActivity](xref:DisCatSharp.Entities.DiscordActivity), System.Nullable{UserStatus}, System.Nullable{DateTimeOffset}) which accepts a [DiscordActivity](xref:DisCatSharp.Entities.DiscordActivity). -* [UpdateStatusAsync](xref:DisCatSharp.DiscordClient#DisCatSharp_DiscordClient_UpdateStatusAsync_DiscordActivity_System_Nullable_UserStatus__System_Nullable_DateTimeOffset__)([DiscordActivity](xref:DisCatSharp.Entities.DiscordActivity), System.Nullable{UserStatus}, System.Nullable{DateTimeOffset}) OR [UpdateStatusAsync](xref:DisCatSharp.DiscordShardedClient#DisCatSharp_DiscordShardedClient_UpdateStatusAsync_DiscordActivity_System_Nullable_UserStatus__System_Nullable_DateTimeOffset__)(DiscordActivity, System.Nullable{[UserStatus](xref:DisCatSharp.Entities.UserStatus)}, System.Nullable{DateTimeOffset}) (for the sharded client) at any point after `Ready` has been fired. +* The overload for [ConnectAsync](xref:DisCatSharp.DiscordClient#DisCatSharp_DiscordClient_ConnectAsync_DisCatSharp_Entities_DiscordActivity_System_Nullable_DisCatSharp_Entities_UserStatus__System_Nullable_DateTimeOffset__)([DiscordActivity](xref:DisCatSharp.Entities.DiscordActivity), System.Nullable{UserStatus}, System.Nullable{DateTimeOffset}) which accepts a [DiscordActivity](xref:DisCatSharp.Entities.DiscordActivity). +* [UpdateStatusAsync](xref:DisCatSharp.DiscordClient#DisCatSharp_DiscordClient_UpdateStatusAsync_DisCatSharp_Entities_DiscordActivity_System_Nullable_DisCatSharp_Entities_UserStatus__System_Nullable_DateTimeOffset__)([DiscordActivity](xref:DisCatSharp.Entities.DiscordActivity), System.Nullable{UserStatus}, System.Nullable{DateTimeOffset}) OR [UpdateStatusAsync](xref:DisCatSharp.DiscordShardedClient#DisCatSharp_DiscordShardedClient_UpdateStatusAsync_DisCatSharp_Entities_DiscordActivity_System_Nullable_DisCatSharp_Entities_UserStatus__System_Nullable_DateTimeOffset__)(DiscordActivity, System.Nullable{[UserStatus](xref:DisCatSharp.Entities.UserStatus)}, System.Nullable{DateTimeOffset}) (for the sharded client) at any point after `Ready` has been fired. ### Am I able to retrieve a @DisCatSharp.Entities.DiscordRole by name? Yes. Use LINQ on the `Roles` property of your instance of [DiscordGuild](xref:DisCatSharp.Entities.DiscordGuild) and compare against the `Name` of each [DiscordRole](xref:DisCatSharp.Entities.DiscordRole). ### Why are you using Newtonsoft.Json when System.Text.Json is available Yes `System.Text.Json` is available to use but it still doesn't stand up to what we currently need which is why we still use Newtonsoft.Json. Maybe in time we can switch to your favorite Json Deserializer but for right now we will be using Newtonsoft.Json for the foreseeable future. ### Why the hell are my events not firing? This is because in the Discord V8+ API, they require @DisCatSharp.DiscordIntents to be enabled on [DiscordConfiguration](xref:DisCatSharp.DiscordConfiguration) and the Discord Application Portal. We have an [article](xref:beyond_basics_intents) that covers all that has to be done to set this up.