| @@ -2,17 +2,17 @@ | |||||
| ## How can I restrict some of my commands so only certain users can execute them? | ## How can I restrict some of my commands so only certain 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` etc.*). | |||||
| If, however, you wish to restrict the commands based on the user's | |||||
| role, you can either create your own 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 own | |||||
| 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` etc.*). | |||||
| If, however, you wish to restrict the commands based on the user's | |||||
| role, you can either create your own 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 own | |||||
| custom preconditions. | custom preconditions. | ||||
| [RequireUserPermission]: xref:Discord.Commands.RequireUserPermissionAttribute | [RequireUserPermission]: xref:Discord.Commands.RequireUserPermissionAttribute | ||||
| @@ -20,8 +20,8 @@ custom preconditions. | |||||
| ## I'm getting an error about `Assembly#GetEntryAssembly`. | ## I'm getting an error about `Assembly#GetEntryAssembly`. | ||||
| You may be confusing [CommandService#AddModulesAsync] with | |||||
| [CommandService#AddModuleAsync]. The former is used to add modules | |||||
| You may be confusing [CommandService#AddModulesAsync] with | |||||
| [CommandService#AddModuleAsync]. The former is used to add modules | |||||
| via the assembly, while the latter is used to add a single module. | via the assembly, while the latter is used to add a single module. | ||||
| [CommandService#AddModulesAsync]: xref:Discord.Commands.CommandService.AddModulesAsync* | [CommandService#AddModulesAsync]: xref:Discord.Commands.CommandService.AddModulesAsync* | ||||
| @@ -29,10 +29,10 @@ via the assembly, while the latter is used to add a single module. | |||||
| ## What does [Remainder] do in the command signature? | ## What does [Remainder] do in the command signature? | ||||
| The [RemainderAttribute] leaves the string unparsed, meaning you | |||||
| don't have to add quotes around the text for the text to be | |||||
| recognized as a single object. Please note that if your method has | |||||
| multiple parameters, the remainder attribute can only be applied to | |||||
| The [RemainderAttribute] leaves the string unparsed, meaning you | |||||
| don't have to add quotes around the text for the text to be | |||||
| recognized as a single object. Please note that if your method has | |||||
| multiple parameters, the remainder attribute can only be applied to | |||||
| the last parameter. | the last parameter. | ||||
| [!code-csharp[Remainder](samples/commands/Remainder.cs)] | [!code-csharp[Remainder](samples/commands/Remainder.cs)] | ||||
| @@ -41,17 +41,17 @@ the last parameter. | |||||
| ## What is a service? Why does my module not hold any data after execution? | ## What is a service? Why does my module not hold any data after execution? | ||||
| In Discord.NET, modules are created similarly to ASP.NET, meaning | |||||
| that they have a transient nature. This means that they are spawned | |||||
| every time when a request is received, and are killed from memory | |||||
| when the execution finishes. This is why you cannot store persistent | |||||
| data inside a module. To workaround this, consider using a service. | |||||
| Service is often used to hold data externally, so that they will | |||||
| 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 | |||||
| In Discord.NET, modules are created similarly to ASP.NET, meaning | |||||
| that they have a transient nature. This means that they are spawned | |||||
| every time when a request is received, and are killed from memory | |||||
| when the execution finishes. This is why you cannot store persistent | |||||
| data inside a module. To workaround this, consider using a service. | |||||
| Service is often used to hold data externally, so that they will | |||||
| 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](../guides/commands/commands.md#usage-in-modules). | as how it works in [Discord.NET](../guides/commands/commands.md#usage-in-modules). | ||||
| A brief example of service and dependency injection can be seen below. | A brief example of service and dependency injection can be seen below. | ||||
| @@ -63,22 +63,22 @@ A brief example of service and dependency injection can be seen below. | |||||
| ## I have a long-running Task in my command, and Discord.NET keeps saying that a `MessageReceived` handler is blocking the gateway. What gives? | ## I have a long-running Task in my command, and Discord.NET keeps saying that a `MessageReceived` handler is blocking the gateway. What gives? | ||||
| By default, all commands are executed on the same thread as the | |||||
| gateway task, which is responsible for keeping the connection from | |||||
| your client to Discord alive. By default, when you execute a command, | |||||
| this blocks the gateway from communicating for as long as the command | |||||
| task is being executed. The library will warn you about any long | |||||
| running event handler (in this case, the command handler) that | |||||
| persists for **more than 3 seconds**. | |||||
| By default, all commands are executed on the same thread as the | |||||
| gateway task, which is responsible for keeping the connection from | |||||
| your client to Discord alive. By default, when you execute a command, | |||||
| this blocks the gateway from communicating for as long as the command | |||||
| task is being executed. The library will warn you about any long | |||||
| running event handler (in this case, the command handler) that | |||||
| persists for **more than 3 seconds**. | |||||
| To resolve this, the library has designed a flag called [RunMode]. | |||||
| To resolve this, the library has designed a flag called [RunMode]. | |||||
| There are 2 main `RunMode`s. | There are 2 main `RunMode`s. | ||||
| 1. `RunMode.Sync` (default) | |||||
| 1. `RunMode.Sync` (default) | |||||
| 2. `RunMode.Async` | 2. `RunMode.Async` | ||||
| You can set the `RunMode` either by specifying it individually via | You can set the `RunMode` either by specifying it individually via | ||||
| the `CommandAttribute`, or by setting the global default with | |||||
| the `CommandAttribute`, or by setting the global default with | |||||
| the [DefaultRunMode] flag under `CommandServiceConfig`. | the [DefaultRunMode] flag under `CommandServiceConfig`. | ||||
| # [CommandAttribute](#tab/cmdattrib) | # [CommandAttribute](#tab/cmdattrib) | ||||
| @@ -94,10 +94,10 @@ the [DefaultRunMode] flag under `CommandServiceConfig`. | |||||
| *** | *** | ||||
| > [!IMPORTANT] | > [!IMPORTANT] | ||||
| > While specifying `RunMode.Async` allows the command to be spun off | |||||
| > While specifying `RunMode.Async` allows the command to be spun off | |||||
| > to a different thread instead of the gateway thread, | > to a different thread instead of the gateway thread, | ||||
| > keep in mind that there will be **potential consequences** | |||||
| > by doing so. Before applying this flag, please | |||||
| > keep in mind that there will be **potential consequences** | |||||
| > by doing so. Before applying this flag, please | |||||
| > consider whether it is necessary to do so. | > consider whether it is necessary to do so. | ||||
| > | > | ||||
| > Further details regarding `RunMode.Async` can be found below. | > Further details regarding `RunMode.Async` can be found below. | ||||
| @@ -108,28 +108,28 @@ the [DefaultRunMode] flag under `CommandServiceConfig`. | |||||
| ## How does `RunMode.Async` work, and why is Discord.NET *not* using it by default? | ## How does `RunMode.Async` work, and why is Discord.NET *not* using it by default? | ||||
| `RunMode.Async` works by spawning a new `Task` with an unawaited | |||||
| [Task.Run], essentially making `ExecuteAsyncInternalAsync`, the task | |||||
| that is used to invoke the command task, to be finished on a | |||||
| `RunMode.Async` works by spawning a new `Task` with an unawaited | |||||
| [Task.Run], essentially making `ExecuteAsyncInternalAsync`, the task | |||||
| that is used to invoke the command task, to be finished on a | |||||
| different thread. This means that [ExecuteAsync] will be forced to | different thread. This means that [ExecuteAsync] will be forced to | ||||
| return a successful [ExecuteResult] regardless of the execution. | return a successful [ExecuteResult] regardless of the execution. | ||||
| The following are the known caveats with `RunMode.Async`, | The following are the known caveats with `RunMode.Async`, | ||||
| 1. You can potentially introduce race condition. | 1. You can potentially introduce race condition. | ||||
| 2. Unnecessary overhead caused by [async state machine]. | 2. Unnecessary overhead caused by [async state machine]. | ||||
| 3. [ExecuteAsync] will immediately return [ExecuteResult] instead of | |||||
| other result types (this is particularly important for those who wish | |||||
| 3. [ExecuteAsync] will immediately return [ExecuteResult] instead of | |||||
| other result types (this is particularly important for those who wish | |||||
| to utilize [RuntimeResult] in 2.0). | to utilize [RuntimeResult] in 2.0). | ||||
| 4. Exceptions are swallowed. | 4. Exceptions are swallowed. | ||||
| However, there are ways to remedy some of these. | However, there are ways to remedy some of these. | ||||
| For #3, in Discord.NET 2.0, the library introduces a new event called | |||||
| [CommandExecuted], which is raised whenever the command is | |||||
| **successfully executed**. This event will be raised regardless of | |||||
| For #3, in Discord.NET 2.0, the library introduces a new event called | |||||
| [CommandExecuted], which is raised whenever the command is | |||||
| **successfully executed**. This event will be raised regardless of | |||||
| the `RunMode` type and will return the appropriate execution result. | the `RunMode` type and will return the appropriate execution result. | ||||
| For #4, exceptions are caught in [CommandService#Log] event under | |||||
| For #4, exceptions are caught in [CommandService#Log] event under | |||||
| [LogMessage.Exception] as [CommandException]. | [LogMessage.Exception] as [CommandException]. | ||||
| [Task.Run]: https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.run | [Task.Run]: https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.run | ||||
| @@ -2,7 +2,7 @@ | |||||
| ## Common Types | ## Common Types | ||||
| * A **Guild** ([IGuild]) is an isolated collection of users and | |||||
| * A **Guild** ([IGuild]) is an isolated collection of users and | |||||
| channels, and are often referred to as "servers". | channels, and are often referred to as "servers". | ||||
| - Example: [Discord API](https://discord.gg/jkrBmQR) | - Example: [Discord API](https://discord.gg/jkrBmQR) | ||||
| * A **Channel** ([IChannel]) represents either a voice or text channel. | * A **Channel** ([IChannel]) represents either a voice or text channel. | ||||
| @@ -14,11 +14,11 @@ channels, and are often referred to as "servers". | |||||
| ## Channel Types | ## Channel Types | ||||
| ### Message Channels | ### Message Channels | ||||
| * A **Text channel** ([ITextChannel]) is a message channel from a | |||||
| * A **Text channel** ([ITextChannel]) is a message channel from a | |||||
| Guild. | Guild. | ||||
| * A **DM channel** ([IDMChannel]) is a message channel from a DM. | * A **DM channel** ([IDMChannel]) is a message channel from a DM. | ||||
| * A **Group channel** ([IGroupChannel]) is a message channel from a | |||||
| Group. | |||||
| * A **Group channel** ([IGroupChannel]) is a message channel from a | |||||
| Group. | |||||
| - This is rarely used due to the bot's inability to join groups. | - This is rarely used due to the bot's inability to join groups. | ||||
| * A **Private channel** ([IPrivateChannel]) is a DM or a Group. | * A **Private channel** ([IPrivateChannel]) is a DM or a Group. | ||||
| * A **Message channel** ([IMessageChannel]) can be any of the above. | * A **Message channel** ([IMessageChannel]) can be any of the above. | ||||
| @@ -27,7 +27,7 @@ Group. | |||||
| * A **Guild channel** ([IGuildChannel]) is a guild channel in a guild. | * A **Guild channel** ([IGuildChannel]) is a guild channel in a guild. | ||||
| - This can be any channels that may exist in a guild. | - This can be any channels that may exist in a guild. | ||||
| * A **Voice channel** ([IVoiceChannel]) is a voice channel in a guild. | * A **Voice channel** ([IVoiceChannel]) is a voice channel in a guild. | ||||
| * A **Category channel** ([ICategoryChannel]) (2.0+) is a category that | |||||
| * A **Category channel** ([ICategoryChannel]) (2.0+) is a category that | |||||
| holds one or more sub-channels. | holds one or more sub-channels. | ||||
| [IGuildChannel]: xref:Discord.IGuildChannel | [IGuildChannel]: xref:Discord.IGuildChannel | ||||
| @@ -52,12 +52,12 @@ holds one or more sub-channels. | |||||
| ## Activity Types | ## Activity Types | ||||
| * A **Game** ([Game]) refers to a user's game activity. | * A **Game** ([Game]) refers to a user's game activity. | ||||
| * A **Rich Presence** ([RichGame]) refers to a user's detailed | |||||
| gameplay status. | |||||
| * A **Rich Presence** ([RichGame]) refers to a user's detailed | |||||
| gameplay status. | |||||
| - Visit [Rich Presence Intro] on Discord docs for more info. | - Visit [Rich Presence Intro] on Discord docs for more info. | ||||
| * A **Streaming Status** ([StreamingGame]) refers to user's activity | |||||
| * A **Streaming Status** ([StreamingGame]) refers to user's activity | |||||
| for streaming on services such as Twitch. | for streaming on services such as Twitch. | ||||
| * A **Spotify Status** ([SpotifyGame]) (2.0+) refers to a user's | |||||
| * A **Spotify Status** ([SpotifyGame]) (2.0+) refers to a user's | |||||
| activity for listening to a song on Spotify. | activity for listening to a song on Spotify. | ||||
| [Game]: xref:Discord.Game | [Game]: xref:Discord.Game | ||||
| @@ -1,10 +1,10 @@ | |||||
| # Legacy Questions | # Legacy Questions | ||||
| ## X, Y, Z does not work! It doesn't return a valid value anymore. | ## X, Y, Z does not work! It doesn't return a valid value anymore. | ||||
| If you're currently using an older version in stable branch, please | |||||
| upgrade to the latest pre-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 | |||||
| If you're currently using an older version in stable branch, please | |||||
| upgrade to the latest pre-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. | 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 pre-release. | ||||
| @@ -12,8 +12,8 @@ Visit the repo's [release tag] to see the latest public pre-release. | |||||
| [release tag]: https://github.com/RogueException/Discord.Net/releases | [release tag]: https://github.com/RogueException/Discord.Net/releases | ||||
| ## I came from an earlier version of Discord.NET 1.0, and DependencyMap doesn't seem to exist anymore in the later revision? What happened to it? | ## I came from an earlier version of Discord.NET 1.0, and DependencyMap doesn't seem to exist anymore in the later revision? What happened to it? | ||||
| The `DependencyMap` has been replaced with Microsoft's | |||||
| [DependencyInjection] Abstractions. An example usage can be seen | |||||
| The `DependencyMap` has been replaced with Microsoft's | |||||
| [DependencyInjection] Abstractions. An example usage can be seen | |||||
| [here](https://github.com/foxbot/DiscordBotBase/blob/csharp/src/DiscordBot/Program.cs#L36). | [here](https://github.com/foxbot/DiscordBotBase/blob/csharp/src/DiscordBot/Program.cs#L36). | ||||
| [DependencyInjection]: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection | [DependencyInjection]: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection | ||||
| @@ -3,15 +3,15 @@ | |||||
| ## How should I safely check a type? | ## How should I safely check a type? | ||||
| > [!WARNING] | > [!WARNING] | ||||
| > Direct casting (e.g. `(Type)type`) is **the least recommended** | |||||
| > way of casting, as it *can* throw an [InvalidCastException] | |||||
| > Direct casting (e.g. `(Type)type`) is **the least recommended** | |||||
| > way of casting, as it *can* throw an [InvalidCastException] | |||||
| > when the object isn't the desired type. | > when the object isn't the desired type. | ||||
| > | > | ||||
| > Please refer to [this post] for more details. | > Please refer to [this post] for more details. | ||||
| In Discord.NET, the idea of polymorphism is used throughout. You may | |||||
| need to cast the object as a certain type before you can perform any | |||||
| action. | |||||
| In Discord.NET, the idea of polymorphism is used throughout. You may | |||||
| need to cast the object as a certain type before you can perform any | |||||
| action. | |||||
| A good and safe casting example: | A good and safe casting example: | ||||
| @@ -25,15 +25,15 @@ A good and safe casting example: | |||||
| > [!TIP] | > [!TIP] | ||||
| > The [GetChannel] method by default returns an [IChannel]. | > The [GetChannel] method by default returns an [IChannel]. | ||||
| > This means channels such as [IVoiceChannel], [ICategoryChannel] | > This means channels such as [IVoiceChannel], [ICategoryChannel] | ||||
| > can be returned. This is why that you cannot send message | |||||
| > can be returned. This is why that you cannot send message | |||||
| > to channels like those. | > to channels like those. | ||||
| Any implementation of [IMessageChannel] has a [SendMessageAsync] | Any implementation of [IMessageChannel] has a [SendMessageAsync] | ||||
| method. You can get the channel via [GetChannel] under the client. | method. You can get the channel via [GetChannel] under the client. | ||||
| Remember, when using Discord.NET, polymorphism is a common recurring | |||||
| theme. This means an object may take in many shapes or form, which | |||||
| means casting is your friend. You should attempt to cast the channel | |||||
| as an [IMessageChannel] or any other entity that implements it to be | |||||
| Remember, when using Discord.NET, polymorphism is a common recurring | |||||
| theme. This means an object may take in many shapes or form, which | |||||
| means casting is your friend. You should attempt to cast the channel | |||||
| as an [IMessageChannel] or any other entity that implements it to be | |||||
| able to message. | able to message. | ||||
| [SendMessageAsync]: xref:Discord.IMessageChannel.SendMessageAsync* | [SendMessageAsync]: xref:Discord.IMessageChannel.SendMessageAsync* | ||||
| @@ -41,7 +41,7 @@ able to message. | |||||
| ## How can I tell if a message is from X, Y, Z channel? | ## How can I tell if a message is from X, Y, Z channel? | ||||
| You may check the message channel type. Visit [Glossary] to see the | |||||
| You may check the message channel type. Visit [Glossary] to see the | |||||
| various types of channels. | various types of channels. | ||||
| [Glossary]: Glossary.md#message-channels | [Glossary]: Glossary.md#message-channels | ||||
| @@ -50,13 +50,13 @@ various types of channels. | |||||
| There are 2 ways to do this. You can do either of the following, | There are 2 ways to do this. You can do either of the following, | ||||
| 1. Cast the user as an [IGuildUser] and use its [IGuild] property. | 1. Cast the user as an [IGuildUser] and use its [IGuild] property. | ||||
| 2. Cast the channel as an [IGuildChannel] and use | |||||
| 2. Cast the channel as an [IGuildChannel] and use | |||||
| its [IGuild] property. | its [IGuild] property. | ||||
| ## How do I add hyperlink text to an embed? | ## How do I add hyperlink text to an embed? | ||||
| Embeds can use standard [markdown] in the description field as well | |||||
| as in field values. With that in mind, links can be added with | |||||
| Embeds can use standard [markdown] in the description field as well | |||||
| as in field values. With that in mind, links can be added with | |||||
| `[text](link)`. | `[text](link)`. | ||||
| [markdown]: https://support.discordapp.com/hc/en-us/articles/210298617-Markdown-Text-101-Chat-Formatting-Bold-Italic-Underline- | [markdown]: https://support.discordapp.com/hc/en-us/articles/210298617-Markdown-Text-101-Chat-Formatting-Bold-Italic-Underline- | ||||
| @@ -64,26 +64,26 @@ as in field values. With that in mind, links can be added with | |||||
| ## How do I add reactions to a message? | ## How do I add reactions to a message? | ||||
| Any entities that implement [IUserMessage] has an [AddReactionAsync] | Any entities that implement [IUserMessage] has an [AddReactionAsync] | ||||
| method. This method expects an [IEmote] as a parameter. | |||||
| In Discord.Net, an Emote represents a server custom emote, while an | |||||
| Emoji is a Unicode emoji (standard emoji). Both [Emoji] and [Emote] | |||||
| implement [IEmote] and are valid options. | |||||
| method. This method expects an [IEmote] as a parameter. | |||||
| In Discord.Net, an Emote represents a server custom emote, while an | |||||
| Emoji is a Unicode emoji (standard emoji). Both [Emoji] and [Emote] | |||||
| implement [IEmote] and are valid options. | |||||
| [!code-csharp[Emoji](samples/basics/emoji.cs)] | [!code-csharp[Emoji](samples/basics/emoji.cs)] | ||||
| [AddReactionAsync]: xref:Discord.IUserMessage.AddReactionAsync* | [AddReactionAsync]: xref:Discord.IUserMessage.AddReactionAsync* | ||||
| ## Why am I getting so many preemptive rate limits when I try to add more than one reactions? | ## Why am I getting so many preemptive rate limits when I try to add more than one reactions? | ||||
| This is due to how HTML header works, mistreating | |||||
| 0.25sec/action to 1sec. This casues the lib to throw preemptive rate | |||||
| limit more frequently than it should for methods such as adding | |||||
| This is due to how HTML header works, mistreating | |||||
| 0.25sec/action to 1sec. This casues the lib to throw preemptive rate | |||||
| limit more frequently than it should for methods such as adding | |||||
| reactions. | reactions. | ||||
| ## Can I opt-out of preemptive rate limits? | ## Can I opt-out of preemptive rate limits? | ||||
| Unfortunately, not at the moment. See [#401](https://github.com/RogueException/Discord.Net/issues/401). | Unfortunately, not at the moment. See [#401](https://github.com/RogueException/Discord.Net/issues/401). | ||||
| [IChannel]: xref:Discord.IChannel | [IChannel]: xref:Discord.IChannel | ||||
| [ICategoryChannel]: xref:Discord.ICategoryChannel | [ICategoryChannel]: xref:Discord.ICategoryChannel | ||||
| @@ -3,35 +3,35 @@ | |||||
| ## My client keeps returning 401 upon logging in! | ## My client keeps returning 401 upon logging in! | ||||
| > [!WARNING] | > [!WARNING] | ||||
| > Userbot/selfbot (logging in with a user token) is not | |||||
| > Userbot/selfbot (logging in with a user token) is not | |||||
| > officially supported with this library. | > officially supported with this library. | ||||
| > | > | ||||
| > Logging in under a user account may result in account | |||||
| > Logging in under a user account may result in account | |||||
| > termination! | > termination! | ||||
| There are few possible reasons why this may occur. | There are few possible reasons why this may occur. | ||||
| 1. You are not using the appropriate [TokenType]. | |||||
| If you are using a bot account created from the Discord Developer | |||||
| portal, you should be using `TokenType.Bot`. | |||||
| 2. You are not using the correct login credentials. | |||||
| Please keep in mind that tokens start with `Mj*`. | |||||
| If it starts with any other characters, chances are, you might be | |||||
| using the *client secret*, which has nothing to do with the login | |||||
| 1. You are not using the appropriate [TokenType]. | |||||
| If you are using a bot account created from the Discord Developer | |||||
| portal, you should be using `TokenType.Bot`. | |||||
| 2. You are not using the correct login credentials. | |||||
| Please keep in mind that tokens start with `Mj*`. | |||||
| If it starts with any other characters, chances are, you might be | |||||
| using the *client secret*, which has nothing to do with the login | |||||
| token. | token. | ||||
| [TokenType]: xref:Discord.TokenType | [TokenType]: xref:Discord.TokenType | ||||
| ## How do I do X, Y, Z when my bot connects/logs on? Why do I get a `NullReferenceException` upon calling any client methods after connect? | ## How do I do X, Y, Z when my bot connects/logs on? Why do I get a `NullReferenceException` upon calling any client methods after connect? | ||||
| Your bot should **not** attempt to interact in any way with | |||||
| guilds/servers until the [Ready] event fires. When the bot | |||||
| connects, it first has to download guild information from | |||||
| Discord in order for you to get access to any server | |||||
| information; the client is not ready at this point. | |||||
| Technically, the [GuildAvailable] event fires once the data for a | |||||
| particular guild has downloaded; however, it's best to wait for all | |||||
| guilds to be downloaded. Once all downloads are complete, the [Ready] | |||||
| Your bot should **not** attempt to interact in any way with | |||||
| guilds/servers until the [Ready] event fires. When the bot | |||||
| connects, it first has to download guild information from | |||||
| Discord in order for you to get access to any server | |||||
| information; the client is not ready at this point. | |||||
| Technically, the [GuildAvailable] event fires once the data for a | |||||
| particular guild has downloaded; however, it's best to wait for all | |||||
| guilds to be downloaded. Once all downloads are complete, the [Ready] | |||||
| event is triggered, then you can proceed to do whatever you like. | event is triggered, then you can proceed to do whatever you like. | ||||
| [Ready]: xref:Discord.WebSocket.DiscordSocketClient.Ready | [Ready]: xref:Discord.WebSocket.DiscordSocketClient.Ready | ||||
| @@ -39,14 +39,15 @@ event is triggered, then you can proceed to do whatever you like. | |||||
| ## How do I get a message's previous content when that message is edited? | ## How do I get a message's previous content when that message is edited? | ||||
| If you need to do anything with messages (e.g. checking Reactions, | |||||
| checking the content of edited/deleted messages), you must set the | |||||
| [MessageCacheSize] in your [DiscordSocketConfig] settings in order to | |||||
| If you need to do anything with messages (e.g. checking Reactions, | |||||
| checking the content of edited/deleted messages), you must set the | |||||
| [MessageCacheSize] in your [DiscordSocketConfig] settings in order to | |||||
| use the cached message entity. Read more about it [here](../guides/concepts/events.md#cacheable). | use the cached message entity. Read more about it [here](../guides/concepts/events.md#cacheable). | ||||
| 1. Message Cache must be enabled. | 1. Message Cache must be enabled. | ||||
| 2. Hook the MessageUpdated event. This event provides a *before* and | |||||
| 2. Hook the MessageUpdated event. This event provides a *before* and | |||||
| *after* object. | *after* object. | ||||
| 3. Only messages received *after* the bot comes online will be | |||||
| 3. Only messages received *after* the bot comes online will be | |||||
| available in the cache. | available in the cache. | ||||
| [MessageCacheSize]: xref:Discord.WebSocket.DiscordSocketConfig.MessageCacheSize | [MessageCacheSize]: xref:Discord.WebSocket.DiscordSocketConfig.MessageCacheSize | ||||
| @@ -1,81 +1,84 @@ | |||||
| # Basic Concepts / Getting Started | # Basic Concepts / Getting Started | ||||
| ## How do I get started? | ## How do I get started? | ||||
| First of all, welcome! You may visit us on our Discord should you | |||||
| have any questions. Before you delve into using the library, | |||||
| however, you should have some decent understanding of the language | |||||
| you are about to use. This library touches on | |||||
| [Task-based Asynchronous Pattern] \(TAP), [polymorphism], [interface] | |||||
| and many more advanced topics extensively. Please make sure that you | |||||
| First of all, welcome! You may visit us on our Discord should you | |||||
| have any questions. Before you delve into using the library, | |||||
| however, you should have some decent understanding of the language | |||||
| you are about to use. This library touches on | |||||
| [Task-based Asynchronous Pattern] \(TAP), [polymorphism], [interface] | |||||
| and many more advanced topics extensively. Please make sure that you | |||||
| understand these topics to some extent before proceeding. | understand these topics to some extent before proceeding. | ||||
| Here are some examples: | Here are some examples: | ||||
| 1. [Official quick start guide](https://github.com/RogueException/Discord.Net/blob/dev/docs/guides/getting_started/samples/intro/structure.cs) | 1. [Official quick start guide](https://github.com/RogueException/Discord.Net/blob/dev/docs/guides/getting_started/samples/intro/structure.cs) | ||||
| 2. [Official template](https://github.com/foxbot/DiscordBotBase/tree/csharp/src/DiscordBot) | 2. [Official template](https://github.com/foxbot/DiscordBotBase/tree/csharp/src/DiscordBot) | ||||
| > [!TIP] | |||||
| > Please note that you should *not* try to blindly copy paste | |||||
| > the code. The examples are meant to be a template or a guide. | |||||
| > [!TIP] | |||||
| > Please note that you should *not* try to blindly copy paste | |||||
| > the code. The examples are meant to be a template or a guide. | |||||
| > It is not meant to be something that will work out of the box. | > It is not meant to be something that will work out of the box. | ||||
| [Task-based Asynchronous Pattern]: https://docs.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap | [Task-based Asynchronous Pattern]: https://docs.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap | ||||
| [polymorphism]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/polymorphism | [polymorphism]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/polymorphism | ||||
| [interface]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/ | [interface]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/ | ||||
| ## How do I add my bot to my server/guild? | ## How do I add my bot to my server/guild? | ||||
| You can do so by using the [permission calculator] provided | |||||
| You can do so by using the [permission calculator] provided | |||||
| by FiniteReality. | by FiniteReality. | ||||
| This tool allows you to set the permissions that the bot will be | |||||
| added with, and invite the bot into your guild. With this method, | |||||
| bots will also be assigned their own special roles that normal users | |||||
| This tool allows you to set the permissions that the bot will be | |||||
| added with, and invite the bot into your guild. With this method, | |||||
| bots will also be assigned their own special roles that normal users | |||||
| cannot use; this is what we call a `Managed` role, and this is a much | cannot use; this is what we call a `Managed` role, and this is a much | ||||
| safer method of permission management than to create a role that any | |||||
| safer method of permission management than to create a role that any | |||||
| users can be assigned to. | users can be assigned to. | ||||
| [permission calculator]: https://finitereality.github.io/permissions-calculator | [permission calculator]: https://finitereality.github.io/permissions-calculator | ||||
| ## What is a Client/User/Object ID? Is it the token? | ## What is a Client/User/Object ID? Is it the token? | ||||
| Each user and object on Discord has its own snowflake ID generated | |||||
| Each user and object on Discord has its own snowflake ID generated | |||||
| based on various conditions. | based on various conditions. | ||||
|  |  | ||||
| The ID can be seen by anyone; it is public. It is merely used to | |||||
| identify an object in the Discord ecosystem. Many things in the | |||||
| library require an ID to retrieve the said object. | |||||
| There are 2 ways to obtain the said ID. | |||||
| 1. Enable Discord's developer mode. With developer mode enabled, | |||||
| you can - as an example - right click on a guild and copy the guild | |||||
| id (please note that this does not apply to all objects, such as | |||||
| The ID can be seen by anyone; it is public. It is merely used to | |||||
| identify an object in the Discord ecosystem. Many things in the | |||||
| library require an ID to retrieve the said object. | |||||
| There are 2 ways to obtain the said ID. | |||||
| 1. Enable Discord's developer mode. With developer mode enabled, | |||||
| you can - as an example - right click on a guild and copy the guild | |||||
| id (please note that this does not apply to all objects, such as | |||||
| Role IDs \[see below], or DM channel IDs). | Role IDs \[see below], or DM channel IDs). | ||||
|  |  | ||||
| 2. Escape the object using `\` in front the object. For example, | |||||
| when you do `\@Example#1234` in chat, it will return the user ID of | |||||
| 2. Escape the object using `\` in front the object. For example, | |||||
| when you do `\@Example#1234` in chat, it will return the user ID of | |||||
| the aforementioned user. | the aforementioned user. | ||||
| A token is a credential used to log into an account. This information | |||||
| should be kept **private** and for your eyes only. Anyone with your | |||||
| token can log into your account. This applies to both user and bot | |||||
| accounts. That also means that you should never ever hardcode your | |||||
| token or add it into source control, as your identity may be stolen | |||||
| by scrape bots on the internet that scours through constantly to | |||||
| A token is a credential used to log into an account. This information | |||||
| should be kept **private** and for your eyes only. Anyone with your | |||||
| token can log into your account. This applies to both user and bot | |||||
| accounts. That also means that you should never ever hardcode your | |||||
| token or add it into source control, as your identity may be stolen | |||||
| by scrape bots on the internet that scours through constantly to | |||||
| obtain a token. | obtain a token. | ||||
| ## How do I get the role ID? | ## How do I get the role ID? | ||||
| Several common ways to do this: | Several common ways to do this: | ||||
| 1. Make the role mentionable and mention the role, and escape it | |||||
| 1. Make the role mentionable and mention the role, and escape it | |||||
| using the `\` character in front. | using the `\` character in front. | ||||
| 2. Inspect the roles collection within the guild via your debugger. | 2. Inspect the roles collection within the guild via your debugger. | ||||
| Please note that right-clicking on the role and copying the ID will | |||||
| Please note that right-clicking on the role and copying the ID will | |||||
| **not** work. It will only copy the message ID. | **not** work. It will only copy the message ID. | ||||
| ## I have more questions! | |||||
| ## I have more questions! | |||||
| Please visit us at #dotnet_discord-net at [Discord API]. | |||||
| Describe the problem in details to us, and preferably with the | |||||
| Please visit us at #dotnet_discord-net at [Discord API]. | |||||
| Describe the problem in details to us, and preferably with the | |||||
| problematic code uploaded onto [Hastebin](https://hastebin.com). | problematic code uploaded onto [Hastebin](https://hastebin.com). | ||||
| [Discord API]: https://discord.gg/jkrBmQR | [Discord API]: https://discord.gg/jkrBmQR | ||||