@@ -2,17 +2,17 @@ | |||
## 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. | |||
[RequireUserPermission]: xref:Discord.Commands.RequireUserPermissionAttribute | |||
@@ -20,8 +20,8 @@ custom preconditions. | |||
## 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. | |||
[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? | |||
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. | |||
[!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? | |||
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). | |||
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? | |||
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. | |||
1. `RunMode.Sync` (default) | |||
1. `RunMode.Sync` (default) | |||
2. `RunMode.Async` | |||
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`. | |||
# [CommandAttribute](#tab/cmdattrib) | |||
@@ -94,10 +94,10 @@ the [DefaultRunMode] flag under `CommandServiceConfig`. | |||
*** | |||
> [!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, | |||
> 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. | |||
> | |||
> 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? | |||
`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 | |||
return a successful [ExecuteResult] regardless of the execution. | |||
The following are the known caveats with `RunMode.Async`, | |||
1. You can potentially introduce race condition. | |||
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). | |||
4. Exceptions are swallowed. | |||
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. | |||
For #4, exceptions are caught in [CommandService#Log] event under | |||
For #4, exceptions are caught in [CommandService#Log] event under | |||
[LogMessage.Exception] as [CommandException]. | |||
[Task.Run]: https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.run | |||
@@ -2,7 +2,7 @@ | |||
## 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". | |||
- Example: [Discord API](https://discord.gg/jkrBmQR) | |||
* A **Channel** ([IChannel]) represents either a voice or text channel. | |||
@@ -14,11 +14,11 @@ channels, and are often referred to as "servers". | |||
## Channel Types | |||
### Message Channels | |||
* A **Text channel** ([ITextChannel]) is a message channel from a | |||
* A **Text channel** ([ITextChannel]) is a message channel from a | |||
Guild. | |||
* 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. | |||
* A **Private channel** ([IPrivateChannel]) is a DM or a Group. | |||
* 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. | |||
- This can be any channels that may exist 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. | |||
[IGuildChannel]: xref:Discord.IGuildChannel | |||
@@ -52,12 +52,12 @@ holds one or more sub-channels. | |||
## Activity Types | |||
* 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. | |||
* 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. | |||
* 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. | |||
[Game]: xref:Discord.Game | |||
@@ -1,10 +1,10 @@ | |||
# Legacy Questions | |||
## 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. | |||
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 | |||
## 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). | |||
[DependencyInjection]: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection |
@@ -3,15 +3,15 @@ | |||
## How should I safely check a type? | |||
> [!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. | |||
> | |||
> 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: | |||
@@ -25,15 +25,15 @@ A good and safe casting example: | |||
> [!TIP] | |||
> The [GetChannel] method by default returns an [IChannel]. | |||
> 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. | |||
Any implementation of [IMessageChannel] has a [SendMessageAsync] | |||
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. | |||
[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? | |||
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. | |||
[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, | |||
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. | |||
## 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)`. | |||
[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? | |||
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)] | |||
[AddReactionAsync]: xref:Discord.IUserMessage.AddReactionAsync* | |||
## 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. | |||
## Can I opt-out of preemptive rate limits? | |||
Unfortunately, not at the moment. See [#401](https://github.com/RogueException/Discord.Net/issues/401). | |||
[IChannel]: xref:Discord.IChannel | |||
[ICategoryChannel]: xref:Discord.ICategoryChannel | |||
@@ -3,35 +3,35 @@ | |||
## My client keeps returning 401 upon logging in! | |||
> [!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. | |||
> | |||
> Logging in under a user account may result in account | |||
> Logging in under a user account may result in account | |||
> termination! | |||
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. | |||
[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? | |||
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. | |||
[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? | |||
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). | |||
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. | |||
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. | |||
[MessageCacheSize]: xref:Discord.WebSocket.DiscordSocketConfig.MessageCacheSize | |||
@@ -1,81 +1,84 @@ | |||
# Basic Concepts / Getting 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. | |||
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) | |||
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. | |||
[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 | |||
[interface]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/ | |||
## 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. | |||
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 | |||
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. | |||
[permission calculator]: https://finitereality.github.io/permissions-calculator | |||
## 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. | |||
 | |||
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). | |||
 | |||
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. | |||
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. | |||
## How do I get the role ID? | |||
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. | |||
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. | |||
## 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). | |||
[Discord API]: https://discord.gg/jkrBmQR |