diff --git a/.github/workflows/codacy.yml b/.github/workflows/codacy.yml index f5c6a07a..24f07884 100644 --- a/.github/workflows/codacy.yml +++ b/.github/workflows/codacy.yml @@ -39,7 +39,7 @@ jobs: # Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis - name: Run Codacy Analysis CLI - uses: codacy/codacy-analysis-cli-action@5cc54a75f9ad88159bb54046196d920e40e367a5 + uses: codacy/codacy-analysis-cli-action@v4.4.5 with: # Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository # You can also omit the token and run the tools that support default configurations diff --git a/README.md b/README.md index 834864d3..be235941 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,6 @@ The official Guide for Pycord, explaining Pycord's features and how to use them. -## NOTE -Currently deployed from https://github.com/Aiko-IT-Systems/pycord-guide/ - ## Purpose The Guide is meant to serve as a professional guide to **all** of Pycord's features. diff --git a/docs/extensions/bridge/index.mdx b/docs/extensions/bridge/index.mdx index df406d5c..d5068f5e 100644 --- a/docs/extensions/bridge/index.mdx +++ b/docs/extensions/bridge/index.mdx @@ -19,7 +19,6 @@ Let's say that you want to make a command that is both a Slash Command and a Pre This is where the `ext.bridge` module comes in. It allows you to use one callback to make both a Slash Command and a Prefixed Command. - ### Example Usage ```python @@ -45,6 +44,7 @@ bot.run("TOKEN") hello + Hello! @@ -58,6 +58,7 @@ bot.run("TOKEN") !hello + Hello! @@ -101,6 +102,7 @@ The cog will automatically split the Bridge Command into their Slash Command and hello + Hello! @@ -114,6 +116,7 @@ The cog will automatically split the Bridge Command into their Slash Command and !hello + Hello! @@ -123,6 +126,7 @@ The cog will automatically split the Bridge Command into their Slash Command and bye + Bye! @@ -136,6 +140,7 @@ The cog will automatically split the Bridge Command into their Slash Command and !bye + Bye! @@ -144,8 +149,6 @@ The cog will automatically split the Bridge Command into their Slash Command and You can defer if you want to communicate to the user that your bot is busy processing the command. This is done by using `ctx.defer()`. For the Slash Command implementation, `ctx.defer()` calls the function that gives out a "Bot is thinking" message. For the Prefixed Command implementation, `ctx.defer()` enables the typing indicator. - - ### Options Options are pretty straightforward. You just specify them like you do with prefixed commands, and you're all set! @@ -173,6 +176,7 @@ bot.run("TOKEN") sum + 4 @@ -186,6 +190,7 @@ bot.run("TOKEN") !sum 2 2 + 4 diff --git a/docs/extensions/commands/groups.mdx b/docs/extensions/commands/groups.mdx index f35adee9..8af52910 100644 --- a/docs/extensions/commands/groups.mdx +++ b/docs/extensions/commands/groups.mdx @@ -1,15 +1,15 @@ ---- -title: Command Groups ---- - +--- +title: Command Groups +--- + Command groups are a way to create subcommands for your commands. For example, `!afk set` or `!afk -remove`. - -## Syntax - -Creating a command group is very simple. - -```python title="Command Groups Example" +remove`. + +## Syntax + +Creating a command group is very simple. + +```python title="Command Groups Example" import discord from discord.ext import commands @@ -39,18 +39,16 @@ async def add(ctx, a: int, b: int): @math.command() async def subtract(ctx, a: int, b: int): - ... -``` - + ... +``` + To create a command group, the command's decorator must be `@bot.group`. Once you have a command with that decorator, you can use `@function.command()`, such as `@math.command()`. Now, you have subcommand -groups! - - - -:::info Related Topics - -- [Prefixed Commands](./prefixed-commands.mdx) -- [Cogs](../../popular-topics/cogs) - -::: +groups! + +:::info Related Topics + +* [Prefixed Commands](./prefixed-commands.mdx) +* [Cogs](../../popular-topics/cogs) + +::: diff --git a/docs/extensions/commands/help-command.mdx b/docs/extensions/commands/help-command.mdx index 7fe15791..9f55c0ce 100644 --- a/docs/extensions/commands/help-command.mdx +++ b/docs/extensions/commands/help-command.mdx @@ -26,8 +26,8 @@ Pycord bot. It is important to understand these two concepts before continuing. **Learning Resources**: -- [W3Schools - Python Subclassing](https://www.w3schools.com/python/python_classes.asp) -- [W3Schools - Python Inheritance](https://www.w3schools.com/python/python_inheritance.asp) +* [W3Schools - Python Subclassing](https://www.w3schools.com/python/python_classes.asp) +* [W3Schools - Python Inheritance](https://www.w3schools.com/python/python_inheritance.asp) ::: @@ -54,82 +54,77 @@ of making one with Pycord. Making a help command with subclassing and OOP will s There are two types of built-in help commands: -- [`DefaultHelpCommand`](https://docs.pycord.dev/en/stable/ext/commands/api.html#discord.ext.commands.DefaultHelpCommand) -- [`MinimalHelpCommand`](https://docs.pycord.dev/en/stable/ext/commands/api.html#discord.ext.commands.MinimalHelpCommand) +* [`DefaultHelpCommand`](https://docs.pycord.dev/en/stable/ext/commands/api.html#discord.ext.commands.DefaultHelpCommand) +* [`MinimalHelpCommand`](https://docs.pycord.dev/en/stable/ext/commands/api.html#discord.ext.commands.MinimalHelpCommand) `DefaultHelpCommand` is the command enabled by default. It isn't the best looking, but `MinimalHelpCommand` can help make it look a bit better. - + + ```python title="Default Help Command" + import discord + from discord.ext import commands -```python title="Default Help Command" -import discord -from discord.ext import commands + bot = commands.Bot(command_prefix='!', help_command=commands.DefaultHelpCommand()) # help_command is DefaultHelpCommand by default so it isn't necessary to enable it like this + # We enable it here for the sake of understanding -bot = commands.Bot(command_prefix='!', help_command=commands.DefaultHelpCommand()) # help_command is DefaultHelpCommand by default so it isn't necessary to enable it like this -# We enable it here for the sake of understanding + ... -... - -bot.run("token") -``` - - - - !help - - - - No Category: -
-
- !help Shows this message -
- !ping -
-
- Type !help command for more info on a command. -
- You can also type !help category for more info on a category. -
-
-
- -
- - -```python title="Minimal Help Command" -import discord -from discord.ext import commands - -bot = commands.Bot(command_prefix='!', help_command=commands.MinimalHelpCommand()) - -... - -bot.run("token") -``` + bot.run("token") + ``` - - - !help - - - Use !help \[command] for more info on a command. -
- You can also use !help \[category] for more info on a category. -
-
- - {" "} - No Category{" "} - -
- help ping -
-
+ + + !help + + + + + No Category: +
+
+ !help Shows this message +
+ !ping +
+
+ Type !help command for more info on a command. +
+ You can also type !help category for more info on a category. +
+
+
+
+ + + ```python title="Minimal Help Command" + import discord + from discord.ext import commands + + bot = commands.Bot(command_prefix='!', help_command=commands.MinimalHelpCommand()) + + ... + + bot.run("token") + ``` - + + + !help + + + Use !help [command] for more info on a command. +
+ You can also use !help [category] for more info on a category. +
+
+ No Category +
+ help ping +
+
+
## Updating Built-in Help Commands @@ -170,16 +165,13 @@ Finally, we set this as our new help command using `bot.help_command = MyNewHelp - Use !help \[command] for more info on a command. + Use !help [command] for more info on a command.
- You can also use !help \[category] for more info on a + You can also use !help [category] for more info on a category.

- - {" "} - No Category{" "} - + No Category
help ping
@@ -194,10 +186,10 @@ For this, we will subclass the `HelpCommand` class. There are 4 methods that we need to override: -- `HelpCommand.send_bot_help(mapping)` that gets called with `help` -- `HelpCommand.send_command_help(command)` that gets called with `help ` -- `HelpCommand.send_group_help(group)` that gets called with `help ` -- `HelpCommand.send_cog_help(cog)` that gets called with `help ` +* `HelpCommand.send_bot_help(mapping)` that gets called with `help` +* `HelpCommand.send_command_help(command)` that gets called with `help ` +* `HelpCommand.send_group_help(group)` that gets called with `help ` +* `HelpCommand.send_cog_help(cog)` that gets called with `help ` ### Bot Help @@ -219,27 +211,27 @@ bot.help_command = MyHelp() Let's go through the code. -- First, we create a new class called `MyHelp`. This class is a subclass of `HelpCommand`. +* First, we create a new class called `MyHelp`. This class is a subclass of `HelpCommand`. -- Next, we override the `send_bot_help` method. This method is responsible for sending the main help -command to the user. +* Next, we override the `send_bot_help` method. This method is responsible for sending the main help + command to the user. -- We create an embed with the title "Help". +* We create an embed with the title "Help". -- We iterate through `mapping.items()`, which returns a list of tuples, the first element being the -cog and the second element being a list of commands. +* We iterate through `mapping.items()`, which returns a list of tuples, the first element being the + cog and the second element being a list of commands. -- By using `self.get_command_signature(c)` we get the signature of the command, also known as the -`parameters` or `arguments`. +* By using `self.get_command_signature(c)` we get the signature of the command, also known as the + `parameters` or `arguments`. -- There is a chance that the cog is empty, so we use `if command_signatures:`. +* There is a chance that the cog is empty, so we use `if command_signatures:`. -- We get the name of the cog using `getattr(cog, "qualified_name", "No Category")`. This calls the -cog's attribute `qualified_name` which returns "No Category" if the cog has no name. +* We get the name of the cog using `getattr(cog, "qualified_name", "No Category")`. This calls the + cog's attribute `qualified_name` which returns "No Category" if the cog has no name. -- We add a field to the embed with the name of the cog and the value of the command signatures. +* We add a field to the embed with the name of the cog and the value of the command signatures. -- Finally, we send the embed to the channel. +* Finally, we send the embed to the channel. Let's improve the code a little. @@ -289,35 +281,35 @@ bot.help_command = MyHelp() Let's quickly go through the code we haven't discussed yet. -- In line 3, we create an embed with a title the signature of the command (so that the title of the -embed looks like ` [parameter]`), and a random color. +* In line 3, we create an embed with a title the signature of the command (so that the title of the + embed looks like ` [parameter]`), and a random color. -- In lines 4 and 5, we get the command's `help` description and add it to the embed. The help description -of a command can be specified in the docstrings of a command function. For example: +* In lines 4 and 5, we get the command's `help` description and add it to the embed. The help description + of a command can be specified in the docstrings of a command function. For example: - ```python - @bot.command() - async def ping(ctx): - """Returns the latency of the bot.""" - await ctx.send(f"Pong! {round(bot.latency * 1000)}ms") - ``` + ```python + @bot.command() + async def ping(ctx): + """Returns the latency of the bot.""" + await ctx.send(f"Pong! {round(bot.latency * 1000)}ms") + ``` -- Line 6 is shorthand for +* Line 6 is shorthand for - ```python - alias = command.aliases - if alias: - ... + ```python + alias = command.aliases + if alias: + ... - # is the same as + # is the same as - if alias := command.aliases: - ... - ``` + if alias := command.aliases: + ... + ``` - A very helpful (but not well-known) Python shorthand! + A very helpful (but not well-known) Python shorthand! -- In line 7, we get the aliases of the command and add them to the embed. +* In line 7, we get the aliases of the command and add them to the embed. ### Cog Help @@ -362,64 +354,63 @@ class MyHelp(commands.HelpCommand): Add all of these methods together, and you have a fully functioning help command!
-Click to see the final code for this section -
+ Click to see the final code for this section -:::note +
+ :::note -The following code has been slightly edited from the tutorial version. + The following code has been slightly edited from the tutorial version. -::: + ::: -```python title="Custom Help Command Example" -class SupremeHelpCommand(commands.HelpCommand): - def get_command_signature(self, command): - return '%s%s %s' % (self.context.clean_prefix, command.qualified_name, command.signature) + ```python title="Custom Help Command Example" + class SupremeHelpCommand(commands.HelpCommand): + def get_command_signature(self, command): + return '%s%s %s' % (self.context.clean_prefix, command.qualified_name, command.signature) - async def send_bot_help(self, mapping): - embed = discord.Embed(title="Help", color=discord.Color.blurple()) - for cog, commands in mapping.items(): - filtered = await self.filter_commands(commands, sort=True) - if command_signatures := [ - self.get_command_signature(c) for c in filtered - ]: - cog_name = getattr(cog, "qualified_name", "No Category") - embed.add_field(name=cog_name, value="\n".join(command_signatures), inline=False) + async def send_bot_help(self, mapping): + embed = discord.Embed(title="Help", color=discord.Color.blurple()) + for cog, commands in mapping.items(): + filtered = await self.filter_commands(commands, sort=True) + if command_signatures := [ + self.get_command_signature(c) for c in filtered + ]: + cog_name = getattr(cog, "qualified_name", "No Category") + embed.add_field(name=cog_name, value="\n".join(command_signatures), inline=False) - channel = self.get_destination() - await channel.send(embed=embed) + channel = self.get_destination() + await channel.send(embed=embed) - async def send_command_help(self, command): - embed = discord.Embed(title=self.get_command_signature(command) , color=discord.Color.blurple()) - if command.help: - embed.description = command.help - if alias := command.aliases: - embed.add_field(name="Aliases", value=", ".join(alias), inline=False) - - channel = self.get_destination() - await channel.send(embed=embed) + async def send_command_help(self, command): + embed = discord.Embed(title=self.get_command_signature(command) , color=discord.Color.blurple()) + if command.help: + embed.description = command.help + if alias := command.aliases: + embed.add_field(name="Aliases", value=", ".join(alias), inline=False) - async def send_help_embed(self, title, description, commands): # a helper function to add commands to an embed - embed = discord.Embed(title=title, description=description or "No help found...") + channel = self.get_destination() + await channel.send(embed=embed) - if filtered_commands := await self.filter_commands(commands): - for command in filtered_commands: - embed.add_field(name=self.get_command_signature(command), value=command.help or "No help found...") + async def send_help_embed(self, title, description, commands): # a helper function to add commands to an embed + embed = discord.Embed(title=title, description=description or "No help found...") - await self.get_destination().send(embed=embed) + if filtered_commands := await self.filter_commands(commands): + for command in filtered_commands: + embed.add_field(name=self.get_command_signature(command), value=command.help or "No help found...") - async def send_group_help(self, group): - title = self.get_command_signature(group) - await self.send_help_embed(title, group.help, group.commands) + await self.get_destination().send(embed=embed) - async def send_cog_help(self, cog): - title = cog.qualified_name or "No" - await self.send_help_embed(f'{title} Category', cog.description, cog.get_commands()) + async def send_group_help(self, group): + title = self.get_command_signature(group) + await self.send_help_embed(title, group.help, group.commands) -bot.help_command = SupremeHelpCommand() -``` + async def send_cog_help(self, cog): + title = cog.qualified_name or "No" + await self.send_help_embed(f'{title} Category', cog.description, cog.get_commands()) -
+ bot.help_command = SupremeHelpCommand() + ``` +
## Command Attributes @@ -455,11 +446,12 @@ class MyHelp(commands.HelpCommand): - !help update_pycord + !help update\_pycord + - Command 'update_pycord' not found. + Command 'update\_pycord' not found. @@ -472,8 +464,8 @@ Thanks to InterStella0 for making this guide amazing. :::info Related Topics -- [Subclassing Bots](../../Popular-Topics/subclassing-bots) -- [Prefixed Commands](./prefixed-commands) -- [Cogs](../../popular-topics/cogs) +* [Subclassing Bots](../../Popular-Topics/subclassing-bots) +* [Prefixed Commands](./prefixed-commands) +* [Cogs](../../popular-topics/cogs) ::: diff --git a/docs/extensions/commands/prefixed-commands.mdx b/docs/extensions/commands/prefixed-commands.mdx index 66496e7e..1ac1a62f 100644 --- a/docs/extensions/commands/prefixed-commands.mdx +++ b/docs/extensions/commands/prefixed-commands.mdx @@ -27,142 +27,146 @@ The syntax becomes a little more complicated when you want to have multiple comm disadvantages to this system. This is where the commands extension comes in. `ext.commands` has various advantages, such as: -- Simpler syntax -- Easier to use -- Easier to parse user input -- Comes with built-in help commands -- Comes with a built-in system for categorizing commands +* Simpler syntax +* Easier to use +* Easier to parse user input +* Comes with built-in help commands +* Comes with a built-in system for categorizing commands + ```python title="Prefixed Commands with Events" + import discord -```python title="Prefixed Commands with Events" -import discord + client = discord.Client() -client = discord.Client() + @client.event + async def on_message(message): + if message.content.startswith("!ping"): + await message.channel.send("Pong!") -@client.event -async def on_message(message): - if message.content.startswith("!ping"): - await message.channel.send("Pong!") + elif message.content.startswith("!announce"): + if len(message.content.split(" ")) < 3: + await message.channel.send("You need to specify a title and a message. Correct usage: `!announce Hello Hello everyone!`") + return - elif message.content.startswith("!announce"): - if len(message.content.split(" ")) < 3: - await message.channel.send("You need to specify a title and a message. Correct usage: `!announce Hello Hello everyone!`") - return + msg = message.content.split(" ", 2) + title = msg[1] + content = msg[2] - msg = message.content.split(" ", 2) - title = msg[1] - content = msg[2] + await message.channel.send("**{}**\n{}".format(title, content)) - await message.channel.send("**{}**\n{}".format(title, content)) + elif message.content.startswith("!"): + await message.channel.send("Unknown command.") + ``` - elif message.content.startswith("!"): - await message.channel.send("Unknown command.") -``` + + + !ping + - - - !ping - - - Pong! - - - !announce Hello Hello World! - - - Hello -
- Hello World! -
- - !help - - - Unknown Command. - -
+ + Pong! + + + + !announce Hello Hello World! + + + Hello + +
+ + Hello World! +
+ + + !help + + + + Unknown Command. + +
- -```python title="The Commands Extension" -import discord -from discord.ext import commands + + ```python title="The Commands Extension" + import discord + from discord.ext import commands -intents = discord.Intents.default() -intents.message_content = True + intents = discord.Intents.default() + intents.message_content = True -bot = commands.Bot(command_prefix="!", intents=intents) + bot = commands.Bot(command_prefix="!", intents=intents) -@bot.command() -async def ping(ctx): - await ctx.send("Pong!") + @bot.command() + async def ping(ctx): + await ctx.send("Pong!") -@bot.command() -async def announce(ctx, title, *, message): - await ctx.send("**{}**\n{}".format(title, message)) + @bot.command() + async def announce(ctx, title, *, message): + await ctx.send("**{}**\n{}".format(title, message)) -@bot.event -async def on_command_error(ctx, error): - if isinstance(error, commands.CommandNotFound): - await ctx.send("Unknown command.") -``` + @bot.event + async def on_command_error(ctx, error): + if isinstance(error, commands.CommandNotFound): + await ctx.send("Unknown command.") + ``` - - - !ping - - - Pong! - - - !announce Hello Hello World! - - - Hello -
- Hello World! -
- - !pycord - - - Unknown command. - - - !help - - - - No Category: -
-
- !help Shows this message -
+ + !ping + + + Pong! + + + !announce Hello Hello World! + + + Hello
- !announce -
-
- Type !help command for more info on a command. -
- You can also type !help category for more info on a category. -
-
-
- -
+ Hello World! +
+ + !pycord + + + Unknown command. + + + !help + + + + No Category: +
+
+ !help Shows this message +
+ !ping +
+ !announce +
+
+ Type !help command for more info on a command. +
+ You can also type !help category for more info on a category. +
+
+
-:::tip +
-The commands extension has many more uses. This example only showcases the basic features mentioned -in the previous example. Other things you can do with the commands extension include using a different -built-in help command and creating your own. The following tutorials showcase these. + :::tip -::: + The commands extension has many more uses. This example only showcases the basic features mentioned + in the previous example. Other things you can do with the commands extension include using a different + built-in help command and creating your own. The following tutorials showcase these. + ::: @@ -249,7 +253,7 @@ async def echo(ctx, *, message): `ctx` is the context of the message. `*` means that the parameter can be any number of words. `message` is the parameter. If you had not passed `*`, `message` would only have been one word. -For example, if a user had used `!echo hello world`, `message` would have been `hello`. Since we +For example, if a user had used `!echo hello world`, `message` would have been `hello`. Since we passed `*`, `message` is `hello world`, or the rest of the message. We can pass multiple parameters too! @@ -276,7 +280,6 @@ However, since Pycord parses the message at whitespaces, the title will end up b message "Greetings! Greetings to you all!". The user can prevent this by typing `!echo "Holiday Greetings!" Greetings to you all!`. - !echo #general Holiday Greetings! Greetings to you all! @@ -317,7 +320,7 @@ with `int(guess)`. :::info Related Topics -- [Command Groups](groups) -- [Rules and Common Practices](../../Getting-Started/rules-and-common-practices) +* [Command Groups](groups) +* [Rules and Common Practices](../../Getting-Started/rules-and-common-practices) ::: diff --git a/docs/extensions/pages/paginator-basics.mdx b/docs/extensions/pages/paginator-basics.mdx index 9dcce025..fecd805b 100644 --- a/docs/extensions/pages/paginator-basics.mdx +++ b/docs/extensions/pages/paginator-basics.mdx @@ -5,19 +5,23 @@ title: Paginator Basics # Paginator Basics ## [Page](https://docs.pycord.dev/en/stable/ext/pages/index.html#page) + This class contains two attributes: `content` and `embeds`, which correspond to the attributes of the same name on the `discord.Message` class. To create a new Page, use the following syntax: + ```py import discord page = Page(content="My Page Content", embeds=[discord.Embed(title="My First Embed Title")]) ``` ## [PageGroup](https://docs.pycord.dev/en/stable/ext/pages/index.html#pagegroup) + This class represents a group of pages. It uses most of the same parameters as `Paginator`, which allows each `PageGroup` to effectively have its own settings and behaviours. ## [Paginator](https://docs.pycord.dev/en/stable/ext/pages/index.html#paginator) + This is the main class for `ext.pages`, and is used to control most of the functionality of the extension. In its most basic form, with no arguments provided (default values listed below), a paginator can be created like so: @@ -60,40 +64,40 @@ to send a message or response with the paginator's contents. #### Depending on what's being passed to the `pages` parameter, the behaviour of the paginator may differ: -- Passing a list of `PageGroup` objects will essentially treat each `PageGroup` as its own Paginator, with most -`Paginator` attributes able to be set independently for each `PageGroup`. - - Each `PageGroup` accepts its own `pages` parameter, which inherits the same behaviour as the `pages` parameter +* Passing a list of `PageGroup` objects will essentially treat each `PageGroup` as its own Paginator, with most + `Paginator` attributes able to be set independently for each `PageGroup`. + * Each `PageGroup` accepts its own `pages` parameter, which inherits the same behaviour as the `pages` parameter of `Paginator`, except it cannot contain other `PageGroup` objects. -- If a page is a `Page` object, this will allow you to specify both the `discord.Message.content` and -`discord.Message.embeds` attributes for a page. - - **This is the preferred method of defining a page.** -- If a page is a string, this will be used for the `discord.Message.content` attribute. This type of page cannot have -any embeds. -- If a page is a list of embeds, this will be used for the `discord.Message.embeds` attribute. This type of page -cannot have any message content. -- If a page is a list of lists of embeds, each parent list item will create a page containing all embeds from its -child list. This type of page cannot have any message content. +* If a page is a `Page` object, this will allow you to specify both the `discord.Message.content` and + `discord.Message.embeds` attributes for a page. + * **This is the preferred method of defining a page.** +* If a page is a string, this will be used for the `discord.Message.content` attribute. This type of page cannot have + any embeds. +* If a page is a list of embeds, this will be used for the `discord.Message.embeds` attribute. This type of page + cannot have any message content. +* If a page is a list of lists of embeds, each parent list item will create a page containing all embeds from its + child list. This type of page cannot have any message content. #### Parameters for the `Paginator` class which have default values: -- `show_disabled` **:** `True` - - Show buttons that are disabled (i.e. can't be clicked) -- `author_check` **:** `True` - - Only the author can interact with the paginator. -- `timeout` **:** `180` *(seconds)* - - The paginator will time out and become inactive after this many seconds. -- `disable_on_timeout` **:** `True` - - If the paginator times out, it will be automatically disabled and all buttons will be unusable. -- `use_default_buttons` **:** `True` - - Use the default set of 4 buttons and a page indicator. -- `show_indicator` **:** `True` - - When using the default buttons, shows a middle 5th button with the current/total page numbers. + +* `show_disabled` **:** `True` + * Show buttons that are disabled (i.e. can't be clicked) +* `author_check` **:** `True` + * Only the author can interact with the paginator. +* `timeout` **:** `180` *(seconds)* + * The paginator will time out and become inactive after this many seconds. +* `disable_on_timeout` **:** `True` + * If the paginator times out, it will be automatically disabled and all buttons will be unusable. +* `use_default_buttons` **:** `True` + * Use the default set of 4 buttons and a page indicator. +* `show_indicator` **:** `True` + * When using the default buttons, shows a middle 5th button with the current/total page numbers. **For other parameters that can be set on initialization, please check the [API Reference](https://docs.pycord.dev/en/stable/ext/pages/index.html#paginator)** - - ## [PaginatorButton](https://docs.pycord.dev/en/stable/ext/pages/index.html#paginatorbutton) + This class represents a button used to navigate between the pages of a paginator. It's also used to create the page indicator. @@ -102,38 +106,39 @@ functionality you may need. To add custom buttons to the paginator instead of the default navigation buttons, you have two options to do so: -1. **Using the `custom_buttons` parameter of `Paginator`:** - ```py - import discord - from discord.ext.pages import PaginatorButton, Paginator - - buttons = [ - PaginatorButton("first", label="<<-", style=discord.ButtonStyle.green), - PaginatorButton("prev", label="<-", style=discord.ButtonStyle.green), - PaginatorButton("page_indicator", style=discord.ButtonStyle.gray, disabled=True), - PaginatorButton("next", label="->", style=discord.ButtonStyle.green), - PaginatorButton("last", label="->>", style=discord.ButtonStyle.green), - ] - paginator = Paginator( - pages=["Page 1", "Page 2", "Page 3"], - show_indicator=True, - use_default_buttons=False, - custom_buttons=buttons, - ) - ``` -2. **Using `Paginator.add_button()`:** - ```py - import discord - from discord.ext.pages import PaginatorButton, Paginator - - paginator = Paginator(pages=["Page 1", "Page 2", "Page 3"], use_default_buttons=False) - paginator.add_button(PaginatorButton("prev", label="<", style=discord.ButtonStyle.green)) - paginator.add_button(PaginatorButton("page_indicator", style=discord.ButtonStyle.gray, disabled=True)) - paginator.add_button(PaginatorButton("next", label=">", style=discord.ButtonStyle.green)) - ``` +1. **Using the `custom_buttons` parameter of `Paginator`:** + ```py + import discord + from discord.ext.pages import PaginatorButton, Paginator + + buttons = [ + PaginatorButton("first", label="<<-", style=discord.ButtonStyle.green), + PaginatorButton("prev", label="<-", style=discord.ButtonStyle.green), + PaginatorButton("page_indicator", style=discord.ButtonStyle.gray, disabled=True), + PaginatorButton("next", label="->", style=discord.ButtonStyle.green), + PaginatorButton("last", label="->>", style=discord.ButtonStyle.green), + ] + paginator = Paginator( + pages=["Page 1", "Page 2", "Page 3"], + show_indicator=True, + use_default_buttons=False, + custom_buttons=buttons, + ) + ``` +2. **Using `Paginator.add_button()`:** + ```py + import discord + from discord.ext.pages import PaginatorButton, Paginator + + paginator = Paginator(pages=["Page 1", "Page 2", "Page 3"], use_default_buttons=False) + paginator.add_button(PaginatorButton("prev", label="<", style=discord.ButtonStyle.green)) + paginator.add_button(PaginatorButton("page_indicator", style=discord.ButtonStyle.gray, disabled=True)) + paginator.add_button(PaginatorButton("next", label=">", style=discord.ButtonStyle.green)) + ``` If you want to use the default navigation buttons, but not all of them, you can also use `Paginator.remove_button()` to selectively remove them: + ```py from discord.ext.pages import Paginator @@ -142,8 +147,8 @@ paginator.remove_button("first") paginator.remove_button("last") ``` - ## [PaginatorMenu](https://docs.pycord.dev/en/stable/ext/pages/index.html#paginatormenu) + This class represents the `discord.Select` menu used to navigate between `PageGroup` instances. In most situations, you will not need to interact with this class directly. @@ -151,9 +156,11 @@ If you do subclass it, you'll likely want to call `super()` in your `__init__` m navigation functionality is retained. ## Usage Examples + For a comprehensive list of examples showing all `Paginator` functionality, please see the [example in cog form](https://github.com/Pycord-Development/pycord/blob/master/examples/views/paginator.py) in the repo. ## Support and Feedback + If you have any questions, suggestions, or feedback for `ext.pages`, please join the [Discord server](https://discord.gg/pycord). diff --git a/docs/extensions/pages/paginator-faq.mdx b/docs/extensions/pages/paginator-faq.mdx index d95c8c65..698e34c2 100644 --- a/docs/extensions/pages/paginator-faq.mdx +++ b/docs/extensions/pages/paginator-faq.mdx @@ -1,18 +1,20 @@ ---- -title: Paginator FAQ ---- - -# Paginator FAQ - -- **What's the difference between `Paginator.send()` and `Paginator.respond()`?** - - `Paginator.send()` is used to send a channel message (DMChannel or TextChannel) with the paginator. - - `Paginator.respond()` is used to send an interaction response (or followup) message with the paginator. - -- **How can the bot send a paginator to a different destination than where it was invoked?** - - Use the `target` parameter in `Paginator.send()` or `Paginator.respond()`. - - You can also set the `target_message` parameter to control what's shown as a response where the paginator was originally invoked. - - For `Paginator.respond()`, this parameter is required if `target` is set, as an interaction requires being responded to. -- **How can I change the paginator's behavior without re-creating and re-sending it?** - - Use the `Paginator.update()` method. -- **How can I make the bot actually do something with the contents of a page?** - - Use the (upcoming) `Paginator.page_action()` method. \ No newline at end of file +--- +title: Paginator FAQ +--- + +# Paginator FAQ + +* **What's the difference between `Paginator.send()` and `Paginator.respond()`?** + * `Paginator.send()` is used to send a channel message (DMChannel or TextChannel) with the paginator. + * `Paginator.respond()` is used to send an interaction response (or followup) message with the paginator. + +* **How can the bot send a paginator to a different destination than where it was invoked?** + * Use the `target` parameter in `Paginator.send()` or `Paginator.respond()`. + * You can also set the `target_message` parameter to control what's shown as a response where the paginator was originally invoked. + * For `Paginator.respond()`, this parameter is required if `target` is set, as an interaction requires being responded to. + +* **How can I change the paginator's behavior without re-creating and re-sending it?** + * Use the `Paginator.update()` method. + +* **How can I make the bot actually do something with the contents of a page?** + * Use the (upcoming) `Paginator.page_action()` method. diff --git a/docs/extensions/tasks/tasks.mdx b/docs/extensions/tasks/tasks.mdx index fea4db3e..32d4bbb7 100644 --- a/docs/extensions/tasks/tasks.mdx +++ b/docs/extensions/tasks/tasks.mdx @@ -55,6 +55,7 @@ class MyCog(commands.Cog): ``` As you'd expect this will increment a number and print it out every 5 seconds like so: + ```sh 0 # 5 seconds later @@ -73,14 +74,15 @@ As you've seen tasks can work in both outer scope and class contexts and the han ### [Creating a task](https://docs.pycord.dev/en/stable/ext/tasks/index.html#discord.ext.tasks.loop) A look at `discord.ext.tasks.loop`'s definition in the documentation reveals that: -1. As you've seen before it expects the time between each execution, that however doesn't have to be in seconds as -there are `seconds`, `minutes` and `hours` parameters to make it easier for us, they can also be floats in case you want -ultra-precision. -2. You can also pass in a `datetime.time` object or a sequence of them in the `time` parameter which will make it run -at the specified time(s). -3. You can pass in how many times a loop runs before it stops by passing in the `count` parameter, you can use `None` -to make it run forever which is also the default. -4. The loop function ***must*** be a coroutine. + +1. As you've seen before it expects the time between each execution, that however doesn't have to be in seconds as + there are `seconds`, `minutes` and `hours` parameters to make it easier for us, they can also be floats in case you want + ultra-precision. +2. You can also pass in a `datetime.time` object or a sequence of them in the `time` parameter which will make it run + at the specified time(s). +3. You can pass in how many times a loop runs before it stops by passing in the `count` parameter, you can use `None` + to make it run forever which is also the default. +4. The loop function ***must*** be a coroutine. These are all really useful, and they aren't the only parameters so if you want to know more about them check out the [docs](https://docs.pycord.dev/en/stable/ext/tasks/index.html#discord.ext.tasks.loop)! @@ -88,12 +90,13 @@ These are all really useful, and they aren't the only parameters so if you want ### Attributes A task has the following attributes: -- `current_loop`: The current loop the task is on. -- `hours`, `minutes`, `seconds`: attributes that represent the time between each execution. -- `time`: A list of datetime.time objects that represent the times the task will run, returns `None` if no datetime -objects were passed. -- `next_iteration`: A `datetime.datetime` object that represents the next time the next iteration of the task will -run, can return `None` if the task stopped running. + +* `current_loop`: The current loop the task is on. +* `hours`, `minutes`, `seconds`: attributes that represent the time between each execution. +* `time`: A list of datetime.time objects that represent the times the task will run, returns `None` if no datetime + objects were passed. +* `next_iteration`: A `datetime.datetime` object that represents the next time the next iteration of the task will + run, can return `None` if the task stopped running. These attributes serve as a really powerful asset to get info about your loop. @@ -105,6 +108,7 @@ also provide a refresher of how slash commands groups work in cogs. For the sake of this example let's pretend that we have a leaderboard module that does all the leaderboard handling for us and that computing the leaderboard is very expensive computationally wise, so we want to store one version of it that gets regularly updated instead of generating it every time someone calls the `/leaderboard view` command. + ```py from discord.ext import tasks, commands from discord.commands import SlashCommandGroup, CommandPermissions diff --git a/docs/getting-started/creating-your-first-bot.mdx b/docs/getting-started/creating-your-first-bot.mdx index 21472571..2693c9d5 100644 --- a/docs/getting-started/creating-your-first-bot.mdx +++ b/docs/getting-started/creating-your-first-bot.mdx @@ -21,14 +21,14 @@ away! Just like how you need to sign up to use Discord, your bot also has to be signed up. To do this, you should: -1. Go to the [Discord Developer Portal](https://discord.com/developers/applications) and click - on . -2. Give your bot a name, and click . -3. Now, you should see a page like this. - ![image](https://gblobscdn.gitbook.com/assets%2F-MjPk-Yu4sOq8KGrr_yG%2F-MjdW3OQnwUhacopqSWw%2F-Mjd_-mxrJCrzmaXrAg8%2Fimage.png?alt=media&token=b8e2ae6c-2290-4d37-ad7c-eb412f3fb00e) -4. Click on the tab on the left side of the screen. -5. Click on . -6. You can give it a name, change the Avatar, etc. +1. Go to the [Discord Developer Portal](https://discord.com/developers/applications) and click + on . +2. Give your bot a name, and click . +3. Now, you should see a page like this. + ![image](https://gblobscdn.gitbook.com/assets%2F-MjPk-Yu4sOq8KGrr_yG%2F-MjdW3OQnwUhacopqSWw%2F-Mjd_-mxrJCrzmaXrAg8%2Fimage.png?alt=media\&token=b8e2ae6c-2290-4d37-ad7c-eb412f3fb00e) +4. Click on the tab on the left side of the screen. +5. Click on . +6. You can give it a name, change the Avatar, etc. ## Inviting the bot @@ -50,7 +50,7 @@ Administrator permissions are fine. ::: -![image](https://gblobscdn.gitbook.com/assets%2F-MjPk-Yu4sOq8KGrr_yG%2F-Mk6tNY3LfDkjd6pqdpL%2F-Mk6tkdpddEWoa2jczZk%2Fimage.png?alt=media&token=52c8a29f-a798-48f8-a8c7-4ecca2681f79) +![image](https://gblobscdn.gitbook.com/assets%2F-MjPk-Yu4sOq8KGrr_yG%2F-Mk6tNY3LfDkjd6pqdpL%2F-Mk6tkdpddEWoa2jczZk%2Fimage.png?alt=media\&token=52c8a29f-a798-48f8-a8c7-4ecca2681f79) You can use this link to invite the bot. @@ -66,15 +66,15 @@ considered a snowflake. A Discord user ID is also a snowflake. Now, lets get your bot's token. To do this, you want to: -1. Go back to the tab. -2. Click on the button in the "Token" section. - ![image](https://gblobscdn.gitbook.com/assets%2F-MjPk-Yu4sOq8KGrr_yG%2F-MjdbU12JISJorAZxrKH%2F-MjdbpUsapzb5n15Po5P%2Fimage.png?alt=media&token=118e259f-940a-4f6c-b3a3-c29f3a54100d) +1. Go back to the tab. +2. Click on the button in the "Token" section. + ![image](https://gblobscdn.gitbook.com/assets%2F-MjPk-Yu4sOq8KGrr_yG%2F-MjdbU12JISJorAZxrKH%2F-MjdbpUsapzb5n15Po5P%2Fimage.png?alt=media\&token=118e259f-940a-4f6c-b3a3-c29f3a54100d) Now, you have your bot's token copied to your clipboard. :::danger -Do not, under any circumstances, give your token to anyone. Even if you are contacted by someone +Do not, under any circumstances, give your token to anyone. Even if you are contacted by someone claiming to be Discord staff, do not give them your bot's token. They are lying to you to try and gain access to your bot. If an unauthorized user gains access to your bot's token, they can access your bot and use it in malicious ways. @@ -90,25 +90,25 @@ getting leaked is to store it in `.env` files. You can store your tokens in `.env` files. This is a simple way to store sensitive information. -1. Create a file with the name `.env` (only the extension, with a dot/period at the start and without a name before it). -2. Define the token in the `.env` file (replace the example value with your token). - ```env title=".env" - TOKEN = NzkyNzE1NDU0MTk2MDg4ODQy.X-hvzA.Ovy4MCQywSkoMRRclStW4xAYK7I - ``` -3. Install [`python-dotenv`](https://pypi.org/project/python-dotenv/). - ```bash - python -m pip install python-dotenv - ``` -4. Load the token from the `.env` file. - ```python - import dotenv - dotenv.load_dotenv() - token = str(os.getenv("TOKEN")) - ``` -5. Pass your token as parameter when running the bot. - ```python - client.run(token) - ``` +1. Create a file with the name `.env` (only the extension, with a dot/period at the start and without a name before it). +2. Define the token in the `.env` file (replace the example value with your token). + ```env title=".env" + TOKEN = NzkyNzE1NDU0MTk2MDg4ODQy.X-hvzA.Ovy4MCQywSkoMRRclStW4xAYK7I + ``` +3. Install [`python-dotenv`](https://pypi.org/project/python-dotenv/). + ```bash + python -m pip install python-dotenv + ``` +4. Load the token from the `.env` file. + ```python + import dotenv + dotenv.load_dotenv() + token = str(os.getenv("TOKEN")) + ``` +5. Pass your token as parameter when running the bot. + ```python + client.run(token) + ``` :::tip @@ -151,7 +151,8 @@ bot.run(os.getenv('TOKEN')) # run the bot with the token Hey! -
+ +
Let's go through the code. First, the imports. @@ -177,8 +178,6 @@ In this line, we create a new instance of [`discord.Bot`](https://docs.pycord.de In this object, we can pass various parameters for configuration purposes, such as `owner_ids` and [`intents`](https://docs.pycord.dev/en/stable/api/data_classes.html#discord.Intents). - - ```py @bot.event async def on_ready(): @@ -213,26 +212,25 @@ will not limit your bot's abilities. The part where we load the token from the environmental variables is not required. You may use another way to keep your token secure, or, although not recommended, simply specify the token normally as a string, as shown below.
-A Basic Bot without securing the token -
- -```py -import discord + A Basic Bot without securing the token -bot = discord.Bot() +
+ ```py + import discord -@bot.event -async def on_ready(): - print(f"{bot.user} is ready and online!") + bot = discord.Bot() -@bot.slash_command(name="hello", description="Say hello to the bot") -async def hello(ctx: discord.ApplicationContext): - await ctx.send("Hey!") + @bot.event + async def on_ready(): + print(f"{bot.user} is ready and online!") -bot.run("TOKEN") -``` + @bot.slash_command(name="hello", description="Say hello to the bot") + async def hello(ctx: discord.ApplicationContext): + await ctx.send("Hey!") -
+ bot.run("TOKEN") + ``` +
::: @@ -249,7 +247,7 @@ to learn more about prefixed commands. [Cogs](../popular-topics/cogs) are a great way to organize your commands by putting them into groups called cogs. Cogs are separate files that your bot loads to get the commands inside. -You can read more about cogs, as well as learn how to use them and their benefits, +You can read more about cogs, as well as learn how to use them and their benefits, [here](../popular-topics/cogs). ### How do I add components, such as buttons and dropdown menus, to my bot? @@ -259,6 +257,6 @@ To learn more, read about Message Commands in our [interactions directory](../in :::info Related Topics -- [Prefixed Commands](../extensions/commands/prefixed-commands) +* [Prefixed Commands](../extensions/commands/prefixed-commands) ::: diff --git a/docs/getting-started/hosting-your-bot.mdx b/docs/getting-started/hosting-your-bot.mdx index b5764508..1453cdaf 100644 --- a/docs/getting-started/hosting-your-bot.mdx +++ b/docs/getting-started/hosting-your-bot.mdx @@ -21,13 +21,13 @@ Sure thing. When you run your bot, it first makes a connection to Discord's API. Pycord sends "heartbeats" to Discord. "heartbeats" are small packets sent at a set interval telling Discord that your bot is indeed still alive. If Discord doesn't receive a heartbeat after a certain amount of time, your bot is pronounced dead and buried in the graveyard (not really). It is, though, -taken offline and its connection with Discord is terminated. +taken offline and its connection with Discord is terminated. -Once you close the terminal that you've run your program on, the program is no longer running, and +Once you close the terminal that you've run your program on, the program is no longer running, and the bot stops sending heartbeats and can no longer process commands. This is why you have to constantly keep the process running. -This goes for all programs, in a different nature. If the code isn't compiled/built/assembled/interpreted, +This goes for all programs, in a different nature. If the code isn't compiled/built/assembled/interpreted, it can't be running. ## What is a Host? @@ -39,35 +39,38 @@ ones like GalaxyGate and DigitalOcean. There are three types of hosts. - - Shared hosting is a type of hosting where multiple people share one VPS. Getting a spot on - a shared host is usually cheap, sometimes even free. Shared hosts do not give you a lot of - resources, from less than a gigabyte of RAM (usually 512MB on free hosts) and half of a CPU - with very little storage. Shared hosting is usually used for website hosting and is not - recommended for hosting a Discord bot. - - - A virtual private server (VPS) is a virtual computer (virtual machine) that is rented out to - customers. Most people use a VPS for hosting their projects such as Discord bots. You can get - anywhere from less than a gigabyte of RAM and a less powerful CPU to just under one hundred - gigabytes of RAM, a (or multiple) powerful CPU(s), and a fair amount of storage. A VPS is the - best choice for most users and can be fairly cheap. - - - A dedicated host is a physical computer. You can buy these yourself or rent one from a hosting - provider. Dedicated hosts are often very expensive, but are also very powerful, having a - few hundred gigabytes of RAM and a few very powerful CPUs, along with a good amount of storage. - Dedicated hosts are usually used for very large projects and are overkill for something like - a Discord bot. - + + Shared hosting is a type of hosting where multiple people share one VPS. Getting a spot on + a shared host is usually cheap, sometimes even free. Shared hosts do not give you a lot of + resources, from less than a gigabyte of RAM (usually 512MB on free hosts) and half of a CPU + with very little storage. Shared hosting is usually used for website hosting and is not + recommended for hosting a Discord bot. + + + + A virtual private server (VPS) is a virtual computer (virtual machine) that is rented out to + customers. Most people use a VPS for hosting their projects such as Discord bots. You can get + anywhere from less than a gigabyte of RAM and a less powerful CPU to just under one hundred + gigabytes of RAM, a (or multiple) powerful CPU(s), and a fair amount of storage. A VPS is the + best choice for most users and can be fairly cheap. + + + + A dedicated host is a physical computer. You can buy these yourself or rent one from a hosting + provider. Dedicated hosts are often very expensive, but are also very powerful, having a + few hundred gigabytes of RAM and a few very powerful CPUs, along with a good amount of storage. + Dedicated hosts are usually used for very large projects and are overkill for something like + a Discord bot. + -
+ +
:::danger Make sure you choose a hosting provider you trust. Also make -sure the hosting provider you're looking at has good reviews on public forums. Googling along the -lines of "[host] review" should do the trick. A provider you don't trust can compromise your token. +sure the hosting provider you're looking at has good reviews on public forums. Googling along the +lines of "\[host] review" should do the trick. A provider you don't trust can compromise your token. ::: @@ -76,8 +79,8 @@ from a few dollars to hundreds or thousands of dollars. ## How to Host Your Bot -Once you rent or buy a VPS, you can get to work. Most hosting providers allow you to choose from a -wide range of operating systems, most allow you to choose one but some allow you to choose +Once you rent or buy a VPS, you can get to work. Most hosting providers allow you to choose from a +wide range of operating systems, most allow you to choose one but some allow you to choose multiple. Once that's ready, you have to SSH into the system. We won't get into SSH here, but you can read [this article from DigitalOcean](https://www.digitalocean.com/community/tutorials/ssh-essentials-working-with-ssh-servers-clients-and-keys). You can also use VNC, which is remote desktop software. If you are using an OS that does not have a @@ -86,7 +89,7 @@ likely use SSH. If you are using an OS that has a GUI, such as Windows Server, y Once you've decided on your operating system, you'll want to set it up and install Python. Once that's done, you can copy your bot's files to your remote system, install the required packages, and run -the bot. +the bot. :::warning @@ -104,6 +107,6 @@ a short time. :::info Related Topics -- [Creating Your First Bot](creating-your-first-bot) +* [Creating Your First Bot](creating-your-first-bot) ::: diff --git a/docs/getting-started/more-features.mdx b/docs/getting-started/more-features.mdx index 33d90f82..6708fec4 100644 --- a/docs/getting-started/more-features.mdx +++ b/docs/getting-started/more-features.mdx @@ -37,7 +37,7 @@ async def on_member_join(member): ) ``` -We use the [`discord.Bot.event` decorator](https://docs.pycord.dev/en/stable/api/clients.html#discord.Bot.event) to add the event handler. +We use the [`discord.Bot.event` decorator](https://docs.pycord.dev/en/stable/api/clients.html#discord.Bot.event) to add the event handler. The `on_member_join` event is called when a user joins the server. The `member` parameter is the user that joined. Different events have different names and parameters. You can find all of them [here](https://docs.pycord.dev/en/stable/api/data_classes.html#discord.Intents). @@ -72,47 +72,37 @@ Here, we check if the message is from the user that sent the command. We simply ## Styling Messages ### Embeds + Embeds are a Discord feature that allows applications to format their messages in cool embedded format, enabling your bot to lay out messages with a lot of text into neat fields. - + - - - The Pycord Guide is a detailed guide that explains how to use Pycord and all of its features. - - - The Getting Started section explains how you can get a brand new bot created and running from scratch. - - - Interactions with Pycord - - - Pycord's various Extensions - - - Other Popular Topics - - - We have so much more! Just explore, and you will find everything you need. If you want another page added, open an issue on the GitHub. - - - Created with 💖 by the Pycord Team & Contributors - - + + + The Pycord Guide is a detailed guide that explains how to use Pycord and all of its features. + + + The Getting Started section explains how you can get a brand new bot created and running from scratch. + + + Interactions with Pycord + + + Pycord's various Extensions + + + Other Popular Topics + + + We have so much more! Just explore, and you will find everything you need. If you want another page added, open an issue on the GitHub. + + + Created with 💖 by the Pycord Team & Contributors + + -
+
Creating embeds is simple! Just create an instance of [`discord.Embed`](https://docs.pycord.dev/en/stable/api/data_classes.html#discord.Embed) and edit it to your liking. Once you're done, send it! @@ -145,40 +135,31 @@ bot.run("TOKEN") ``` - -
- hello -
- Hello! Here's a cool embed. - - Embeds are super easy, barely an inconvenience. - - - A really nice field with some information. The description as well as the fields support markdown! - - Inline Field 1 - Inline Field 2 - Inline Field 3 - - Footer! No markdown here. - -
+ +
+ hello +
+ Hello! Here's a cool embed. + + Embeds are super easy, barely an inconvenience. + + + A really nice field with some information. The description as well as the fields support markdown! + + Inline Field 1 + Inline Field 2 + Inline Field 3 + + Footer! No markdown here. + +
-
+
This simple command sends replies to a [slash command](../interactions/application-commands/slash-commands) with an embed. Let's break it down: - + ```py embed = discord.Embed( title="My Amazing Embed", @@ -186,46 +167,48 @@ embed = discord.Embed( color=discord.Colour.blurple(), ) ``` - + This command creates an embed. We use the [`Embed`](https://docs.pycord.dev/en/stable/api/data_classes.html#discord.Embed) class to create an embed object with the title "My Amazing Embed", the description "Embeds are super easy, barely an inconvenience.", and the color `blurple`, Discord's main theme color. - + [discord.Colour](https://docs.pycord.dev/en/stable/api/data_classes.html#discord.Colour) is a class full of [classmethods](https://docs.python.org/3/library/functions.html#classmethod) that return color values. While the official, documented name of this is `discord.Colour`, `discord.Color` -works as well. - +works as well. + ```py embed.add_field(name="A Normal Field", value="A really nice field with some information. **The description as well as the fields support markdown!**") embed.add_field(name="Inline Field 1", value="Inline Field 1", inline=True) embed.add_field(name="Inline Field 2", value="Inline Field 2", inline=True) embed.add_field(name="Inline Field 3", value="Inline Field 3", inline=True) ``` - + This small section shows off embed fields. You can add fields to embeds with the [`add_field` method](https://docs.pycord.dev/en/stable/api/data_classes.html#discord.Embed.add_field) -of the [`discord.Embed`](https://docs.pycord.dev/en/stable/api/data_classes.html#discord.Embed) class. These consist of three +of the [`discord.Embed`](https://docs.pycord.dev/en/stable/api/data_classes.html#discord.Embed) class. These consist of three keyword arguments: `title`, `value`, and `inline`. `title` and `value` are both required arguments, which inline defaults to `False` if it's not defined. The `inline` argument specifies whether space will be divided among the inline fields. There could be a mix of fields where inline has different values too. - + ```py embed.set_footer(text="Footer! No markdown here.") # footers can have icons too embed.set_author(name="Pycord Team", icon_url="https://example.com/link-to-my-image.png") embed.set_thumbnail(url="https://example.com/link-to-my-thumbnail.png") embed.set_image(url="https://example.com/link-to-my-banner.png") ``` - + In this section, we're adding unique items to the embed. These items are: -- Footer - With the [`set_footer()`](https://docs.pycord.dev/en/stable/api/data_classes.html#discord.Embed.set_footer) -method, you can set a small footer that holds a message. This has `text` and `icon_url` kwargs. -- Author - With the [`set_author`](https://docs.pycord.dev/en/stable/api/data_classes.html#discord.Embed.set_author) -method, you can set an author for the embed. This is a small text field at the top of the embed. This -includes `name`, `url` and `icon_url` kwargs. -- Thumbnail - With the [`set_thumbnail`](https://docs.pycord.dev/en/stable/api/data_classes.html#discord.Embed.set_thumbnail) -method, you can set a small image to reside at the top-right of the embed. This has a single `url` kwarg. -- Image - With the [`set_image`](https://docs.pycord.dev/en/stable/api/data_classes.html#discord.Embed.set_image) -method, you can set an image to sit at the bottom of an embed. This has a single `url` kwarg. - + +* Footer - With the [`set_footer()`](https://docs.pycord.dev/en/stable/api/data_classes.html#discord.Embed.set_footer) + method, you can set a small footer that holds a message. This has `text` and `icon_url` kwargs. +* Author - With the [`set_author`](https://docs.pycord.dev/en/stable/api/data_classes.html#discord.Embed.set_author) + method, you can set an author for the embed. This is a small text field at the top of the embed. This + includes `name`, `url` and `icon_url` kwargs. +* Thumbnail - With the [`set_thumbnail`](https://docs.pycord.dev/en/stable/api/data_classes.html#discord.Embed.set_thumbnail) + method, you can set a small image to reside at the top-right of the embed. This has a single `url` kwarg. +* Image - With the [`set_image`](https://docs.pycord.dev/en/stable/api/data_classes.html#discord.Embed.set_image) + method, you can set an image to sit at the bottom of an embed. This has a single `url` kwarg. + There are a lot more methods and attributes you can use to configure embeds. Here, we just covered the basics. Also, remember that all of these values are not necessary in an embed. An embed may only contain a few of these. For example, only a description, a title and a description, and so on. - + ### Markdown + Markdown is a type of markup language that's limited in terms of formatting yet simple. Discord allows for a watered-down version of markdown to be in their messages. @@ -233,26 +216,27 @@ for a watered-down version of markdown to be in their messages. Text formatting can be used in messages and in most embed parts, as explained in the dedicated section below. - + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + +
*italics*__*underlined italics*__
**bold**__**underlined bold**__
***bold italics***__***underlined bold italics***__
__underlined__~~strikethrough~~
*italics****underlined italics***
**bold******underlined bold****
***bold italics********underlined bold italics*****
**underlined**~~strikethrough~~
#### Code Markdown @@ -328,49 +312,50 @@ Outside them, the link will still be clickable but the formatting will be ignore therefore the example above will look similarly to this: `[Pycord](https://pycord.dev/)` #### Embed Markdown - + Adding markdown to your embeds or messages will give your bot the sparkle it needs, however, markdown is limited inside embeds. Use the following table as a reference and keep in mind that embed title and filed names will always show in **bold**. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PartTextLink
Embed AuthorNoNo
Embed TitleYesNo
Embed DescriptionYesYes
Field NameYesNo
Field ValueYesYes
Embed FooterNoNo
PartTextLink
Embed AuthorNoNo
Embed TitleYesNo
Embed DescriptionYesYes
Field NameYesNo
Field ValueYesYes
Embed FooterNoNo
diff --git a/docs/getting-started/rules-and-common-practices.mdx b/docs/getting-started/rules-and-common-practices.mdx index 675b9fb2..98d1c1ff 100644 --- a/docs/getting-started/rules-and-common-practices.mdx +++ b/docs/getting-started/rules-and-common-practices.mdx @@ -34,7 +34,7 @@ information neatly is all you need to do. ::: Providing a Terms of Service for your bot is optional, though usually a best practice. It tells users -what they can and cannot do with your service, and makes it easier to settle disputes if someone +what they can and cannot do with your service, and makes it easier to settle disputes if someone disagrees with you. Read more in Discord's official [Legal Docs](https://discord.com/developers/docs/legal). @@ -53,7 +53,7 @@ of creating a Discord bot with Pycord. ### Bot Sharding -To any new or maybe even experienced bot developer, sharding a bot sounds beneficial once you hear +To any new or maybe even experienced bot developer, sharding a bot sounds beneficial once you hear about it. I'm here to tell you that it isn't a good idea to shard your bot. *Wait a minute, why would it be an option if it wasn't a good idea?* It's simple. I lied. Sort of. @@ -83,7 +83,7 @@ will be denied simply because you applied for an intent you didn't need. ### Subclassing -While it may take some time, subclassing a bot is very worth it. Once again, this was explained +While it may take some time, subclassing a bot is very worth it. Once again, this was explained elsewhere, so I won't go into the details, but I felt it fit here, so I put it here. Subclassing a bot makes it more flexible and allows it to do a lot more. Read more about subclassing @@ -91,7 +91,7 @@ bots [here](../Popular-Topics/subclassing-bots) ### Your Bot's Token -Your bot is only able to be run for one reason: its token. If you followed the +Your bot is only able to be run for one reason: its token. If you followed the [guide for creating your first bot](creating-your-first-bot), you should already know a bit about keeping that token safe. That's exactly what you want to do. @@ -113,13 +113,13 @@ Public or private, having a local Git repository connected to a remote one is a almost any application. For a lot of developers, it's like saving your work. If you do this, all of your bot's code won't be lost if your computer spontaneously combusts, or you smash it to bits from anger. You can simply grab the backup computer that everyone has lying around, and you're back -in business. +in business. ### Organization and Cleanliness -It is *extremely* important to have organized code. This includes commands, objects, functions, +It is *extremely* important to have organized code. This includes commands, objects, functions, and classes. If you don't have organized code, it will get progressively harder for you to recognize -it, and others won't be able to decipher it. +it, and others won't be able to decipher it. Make sure you utilize indents and spaces, as these are very important in making your code readable. @@ -140,7 +140,7 @@ class MyClass: return num1 - num2 ``` -See the difference? Now, which one looks more readable? Hopefully, you answered the second example. +See the difference? Now, which one looks more readable? Hopefully, you answered the second example. Python's [PEP8](https://www.python.org/dev/peps/pep-0008/) is a PEP (**Python Enhancement Proposal**) style guide for Python. It is the style guide that is used by most Python developers and programmers, providing a universal way to write and read code. @@ -157,25 +157,30 @@ out there, like MongoDB, SQLite, and PostgreSQL to name a few. All of these databases I named do the job well, and which one you use depends on what features you want out of a database. -<>{/* Maybe clarify these/add more options */} +<> + {/* Maybe clarify these/add more options */} + #### MongoDB MongoDB is a JSON-like format and if you already use JSON files, it shouldn't be too hard to migrate over to. #### SQLite + SQLite is based on SQL, a common relational data model. It's a lightweight, easy-to-use, portable database solution that works entirely on files. However, if for some reason you cannot read/write to and from a file, and you need to manage lots of data, SQLite might not be for you. -While SQLite is a part of the Python Standard Library as the `sqlite3` package, we recommend not using it as it is +While SQLite is a part of the Python Standard Library as the `sqlite3` package, we recommend not using it as it is synchronous and blocking. You should use an asynchronous alternative, such as [`aiosqlite`](https://pypi.org/project/aiosqlite/). #### PostgreSQL + PostgreSQL is also based on SQL, but it also has more features than SQLite. It's compliant with the SQL standard, open-source, and extensible. However, it's not that fast or simple compared to SQLite. #### MariaDB + MariaDB is also based on SQL and is a fork of the MySQL project. It's compliant with the SQL standard, it's also open source and is a complete drop-in replacement for any code with MySQL. You don't even need to change what package you're using! diff --git a/docs/installation.mdx b/docs/installation.mdx index 2145a073..ea983675 100644 --- a/docs/installation.mdx +++ b/docs/installation.mdx @@ -6,7 +6,7 @@ sidebar_position: 2 Before you can start using Pycord, you need to install the library. :::note -Python **3.8 or above** is required to use Pycord. +Python **3.9 or above** is required to use Pycord. ::: :::tip @@ -18,7 +18,7 @@ You can find instructions for that [here](More/virtual-environments). To install Pycord, you can use the following command in your terminal: - pip install py-cord +pip install py-cord :::tip Remember that you need to install `py-cord`, not `pycord`. @@ -27,7 +27,7 @@ Also, the `pip` command varies depending on your installation. For example, it m If you need voice support for your bot, you should run: - pip install "py-cord[voice]" +pip install "py-cord\[voice]" ## Migration @@ -35,17 +35,17 @@ If you need voice support for your bot, you should run: If you are upgrading from a previous version of Pycord, you can use the following command in your terminal to upgrade to the latest version: - pip install -U py-cord +pip install -U py-cord ### Migrating from other libraries If you are migrating from another library, say, `discord.py`, first of all, you need to uninstall it. - pip uninstall discord.py +pip uninstall discord.py Then, you can install Pycord, it's as simple as that!: - pip install py-cord +pip install py-cord :::caution Uninstalling `discord.py` *after* installing `py-cord` can cause issues. Make sure to uninstall it first! @@ -61,7 +61,7 @@ The development build comes with cutting edge features and new functionality, bu To install the development build, you can use the following command in your terminal: - pip install -U git+https://github.com/Pycord-Development/pycord +pip install -U git+[https://github.com/Pycord-Development/pycord](https://github.com/Pycord-Development/pycord) :::important Git is required to install this build. [Learn how you can install Git](./more/git). diff --git a/docs/interactions/application-commands/context-menus.mdx b/docs/interactions/application-commands/context-menus.mdx index 503f27f4..efad0e5d 100644 --- a/docs/interactions/application-commands/context-menus.mdx +++ b/docs/interactions/application-commands/context-menus.mdx @@ -17,7 +17,7 @@ import DiscordComponent, { defaultOptions } from "@site/src/components/DiscordCo When you right-click a message, you may see an option called "Apps". Hover over it, and you can see commands a bot can run with that message. These are called message commands. -When you right-click a user in the user list, you can once again see an option called "Apps". +When you right-click a user in the user list, you can once again see an option called "Apps". Hover over it, and you can see commands a bot can run with that message. These are called user commands. Together, these two are called Context Menus or Context Menu Commands. These commands work very much like normal commands, except they take a member or message. @@ -42,10 +42,11 @@ async def account_creation_date(ctx, member: discord.Member): # user commands r
- Account Creation Date + Account Creation Date
- {defaultOptions.profiles.bob.author}'s account was created on 2020-01-01 + + {defaultOptions.profiles.bob.author}'s account was created on 2020-01-01
@@ -61,25 +62,23 @@ async def get_message_id(ctx, message: discord.Message): # message commands ret Do. Or do not. There is no try. +
- + Get Message ID
+ Message ID: 930650407917748286
-
+
:::info Related Topics -- [Slash Commands](./slash-commands) -- [Interactions Index](../../interactions) +* [Slash Commands](./slash-commands) +* [Interactions Index](../../interactions) ::: diff --git a/docs/interactions/application-commands/localizations.mdx b/docs/interactions/application-commands/localizations.mdx index ab61e390..620cc69d 100644 --- a/docs/interactions/application-commands/localizations.mdx +++ b/docs/interactions/application-commands/localizations.mdx @@ -7,6 +7,7 @@ Localizations are a way to make your bot more accessible to your users. You can name, the names of any arguments, and any text that is displayed to the user. ## Syntax + ```python @bot.slash_command( name="ping", @@ -52,5 +53,4 @@ async def ping2(ctx, example: Option(str, "example", name_localizations={"en-GB" ``` - -- [`Locales`](https://discord.com/developers/docs/reference#locales) - List of valid locales recognized by Discord +* [`Locales`](https://discord.com/developers/docs/reference#locales) - List of valid locales recognized by Discord diff --git a/docs/interactions/application-commands/slash-commands.mdx b/docs/interactions/application-commands/slash-commands.mdx index 5a6049d5..a070868d 100644 --- a/docs/interactions/application-commands/slash-commands.mdx +++ b/docs/interactions/application-commands/slash-commands.mdx @@ -17,7 +17,6 @@ import DiscordComponent from "@site/src/components/DiscordComponent"; import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; - On March 24, 2021, Discord added Slash Commands to Discord as an easier, more efficient, and better way of using bot commands. Pycord has implemented Slash Commands into the library, so it's simple, efficient, and familiar. :::important @@ -52,6 +51,7 @@ bot.run("TOKEN") ping + Pong! Latency is 335ms. @@ -94,6 +94,7 @@ bot.run("TOKEN") ``` Or, you can instead manually make a `SlashCommandGroup` class like so: + ```python import discord @@ -157,92 +158,94 @@ Since you want different inputs from Options, you'll have to specify the type fo - -You could use Type Annotations and let Pycord figure out the option type or explicitly specified using the [`SlashCommandOptionType`](https://docs.pycord.dev/en/stable/api/enums.html#discord.SlashCommandOptionType) enum. - -```python -import discord - -bot = discord.Bot() - -@bot.command() -# pycord will figure out the types for you -async def add(ctx, first: discord.Option(int), second: discord.Option(int)): - # you can use them as they were actual integers - sum = first + second - await ctx.respond(f"The sum of {first} and {second} is {sum}.") - -@bot.command() -# this explicitly tells pycord what types the options are instead -async def join( - ctx, - first: discord.Option(discord.SlashCommandOptionType.string), - second: discord.Option(discord.SlashCommandOptionType.string) -): - joined = first + second - await ctx.respond(f"When you join \"{first}\" and \"{second}\", you get: \"{joined}\".") - -bot.run("TOKEN") -``` - - - -
- - add - -
- The sum of 1 and 1 is 2. -
- -
- - join - -
- When you join "Py" and "cord", you get: "Pycord". -
-
- + You could use Type Annotations and let Pycord figure out the option type or explicitly specified using the [`SlashCommandOptionType`](https://docs.pycord.dev/en/stable/api/enums.html#discord.SlashCommandOptionType) enum. + + ```python + import discord + + bot = discord.Bot() + + @bot.command() + # pycord will figure out the types for you + async def add(ctx, first: discord.Option(int), second: discord.Option(int)): + # you can use them as they were actual integers + sum = first + second + await ctx.respond(f"The sum of {first} and {second} is {sum}.") + + @bot.command() + # this explicitly tells pycord what types the options are instead + async def join( + ctx, + first: discord.Option(discord.SlashCommandOptionType.string), + second: discord.Option(discord.SlashCommandOptionType.string) + ): + joined = first + second + await ctx.respond(f"When you join \"{first}\" and \"{second}\", you get: \"{joined}\".") + + bot.run("TOKEN") + ``` + + + +
+ + add + +
+ + The sum of 1 and 1 is 2. +
+ + +
+ + join + +
+ + When you join "Py" and "cord", you get: "Pycord". +
+
- - -Instead of Type Annotations, you can also use the option decorator. This is usually done to have type-hinting. - -```python title="Slash Command Type" -import discord - -bot = discord.Bot() - -@bot.command() -@discord.option("first", type=discord.SlashCommandOptionType.string) # type = str also works -@discord.option("second", type=discord.SlashCommandOptionType.string) # type = str also works -async def join( - ctx, - first: str, - second: str, -): - joined = first + second - await ctx.respond(f"When you join \"{first}\" and \"{second}\", you get: \"{joined}\".") - -bot.run("TOKEN") -``` - - - -
- - join - -
- When you join "Py" and "cord", you get: "Pycord". -
-
+ + Instead of Type Annotations, you can also use the option decorator. This is usually done to have type-hinting. + + ```python title="Slash Command Type" + import discord + + bot = discord.Bot() + + @bot.command() + @discord.option("first", type=discord.SlashCommandOptionType.string) # type = str also works + @discord.option("second", type=discord.SlashCommandOptionType.string) # type = str also works + async def join( + ctx, + first: str, + second: str, + ): + joined = first + second + await ctx.respond(f"When you join \"{first}\" and \"{second}\", you get: \"{joined}\".") + + bot.run("TOKEN") + ``` + + + +
+ + join + +
+ + When you join "Py" and "cord", you get: "Pycord". +
+
## Autocomplete + Discord's autocomplete allows developers to determine option choices that are used in a slash command option. You can do this by defining a function: ```py @@ -272,7 +275,8 @@ async def animal_command( animal - You picked an animal type of Marine that led you to pick Shark! + + You picked an animal type of Marine that led you to pick Shark! @@ -284,8 +288,8 @@ Autocomplete can **only** be used with slash commands. :::info Related Topics -- [Interactions Index](../../interactions) -- [Rules and Common Practices](../../getting-started/rules-and-common-practices) -- [Cogs](../../popular-topics/cogs) +* [Interactions Index](../../interactions) +* [Rules and Common Practices](../../getting-started/rules-and-common-practices) +* [Cogs](../../popular-topics/cogs) ::: diff --git a/docs/interactions/index.mdx b/docs/interactions/index.mdx index a8a19b93..3de8adbf 100644 --- a/docs/interactions/index.mdx +++ b/docs/interactions/index.mdx @@ -19,26 +19,26 @@ Since then, Discord has added many types of Interactions, including: [**Application Commands**](https://discord.com/developers/docs/interactions/application-commands) -- [**Slash Commands**](https://discord.com/developers/docs/interactions/application-commands#slash-commands): -Commands that can be used with the `/` prefix. -- **Context Menu Commands**: Commands that can be used from the right-click menu. - - [**User Commands**](https://discord.com/developers/docs/interactions/application-commands#user-commands): - Commands that can be used on a user by alt-clicking/selecting them. - - [**Message Commands**](https://discord.com/developers/docs/interactions/application-commands#message-commands): - Commands that can be used on a message by alt-clicking/selecting it. +* [**Slash Commands**](https://discord.com/developers/docs/interactions/application-commands#slash-commands): + Commands that can be used with the `/` prefix. +* **Context Menu Commands**: Commands that can be used from the right-click menu. + * [**User Commands**](https://discord.com/developers/docs/interactions/application-commands#user-commands): + Commands that can be used on a user by alt-clicking/selecting them. + * [**Message Commands**](https://discord.com/developers/docs/interactions/application-commands#message-commands): + Commands that can be used on a message by alt-clicking/selecting it. [**UI Components**](https://discord.com/developers/docs/interactions/message-components) -- [**Buttons**](https://discord.com/developers/docs/interactions/message-components#buttons): -Buttons are attached to a message and can be clicked on to perform an action. -- [**Select Menus**](https://discord.com/developers/docs/interactions/message-components#select-menus): -Drop-down menus are used to select a number of options from a list. -- [**Modals**](https://discord.com/developers/docs/interactions/message-components#text-inputs): -Form-like modals can be used to ask for input from a user. +* [**Buttons**](https://discord.com/developers/docs/interactions/message-components#buttons): + Buttons are attached to a message and can be clicked on to perform an action. +* [**Select Menus**](https://discord.com/developers/docs/interactions/message-components#select-menus): + Drop-down menus are used to select a number of options from a list. +* [**Modals**](https://discord.com/developers/docs/interactions/message-components#text-inputs): + Form-like modals can be used to ask for input from a user. ## Application Commands -Application Commands are another set of new features that are intended to avoid compromising users' safety and privacy. +Application Commands are another set of new features that are intended to avoid compromising users' safety and privacy. They're relatively easy to add to your bot, and give people a simpler and safer way to use commands. ### [Slash Commands](https://docs.pycord.dev/en/stable/api/application_commands.html#discord.SlashCommand) @@ -60,6 +60,7 @@ Message Content intent. Using that as a reason will get your application denied. ping + Pong! Latency is 335ms. @@ -69,20 +70,20 @@ Message Content intent. Using that as a reason will get your application denied. This is what a Slash Command looks like. Not too different from a prefix command, apart from the note telling you who invoked it. A Slash Command's fields can accept any of the following: -- Members -- Roles -- Channels -- Attachments -- Text +* Members +* Roles +* Channels +* Attachments +* Text Just about as good as it gets. ### [Message](https://docs.pycord.dev/en/stable/api/application_commands.html#discord.MessageCommand) and [User](https://docs.pycord.dev/en/stable/api/application_commands.html#discord.UserCommand) Commands -Message Commands and User Commands were both introduced at around the same time, and are very similar to each other, so we'll be -introducing them together. These commands can be found in the `Apps` tab when alt-clicking. The only difference between the two is that -Message Commands only appear in the `Apps` tab of a message, while User Commands are found in the `Apps` tab of a user. Message Commands -can be used to quickly report a message, warn a user for a message, and other functions. Likewise, User Commands can be used to add a +Message Commands and User Commands were both introduced at around the same time, and are very similar to each other, so we'll be +introducing them together. These commands can be found in the `Apps` tab when alt-clicking. The only difference between the two is that +Message Commands only appear in the `Apps` tab of a message, while User Commands are found in the `Apps` tab of a user. Message Commands +can be used to quickly report a message, warn a user for a message, and other functions. Likewise, User Commands can be used to add a user to a ticket, warn a user, and more. Here's an example of a Message Command: @@ -91,12 +92,14 @@ Here's an example of a Message Command: Hello World! +
Reverse Message
+ Message 930650407917748286 reversed is "!dlroW olleH"
@@ -109,22 +112,27 @@ And here's an example of a User Command: {defaultOptions.profiles.dorukyum.author} has been on Discord for a long time +
User Age
- {defaultOptions.profiles.dorukyum.author} is 1 week old. + + {defaultOptions.profiles.dorukyum.author} is 1 week old.
+
User Age
+ {defaultOptions.profiles.bob.author} is 40 years old.
+ 🤔 @@ -138,32 +146,32 @@ Pretty cool, right? To learn more about these two, please read the [Context Menu Ever since Discord was created, apps on it have used prefix commands. Using prefixes meant that you would have to put a certain character (or string of characters) in front of your command, such as the exclamation mark in `!ping`. The way this -worked was that your bot would listen for messages, pick out the ones that had their specific prefix, and then respond to the command. -Now, Discord is encouraging developers to switch their bots over to Application Commands, which is a new system meant to preserve the -privacy and safety of their users. But why exactly is Discord making us switch? What's the better option, Application Commands or prefix +worked was that your bot would listen for messages, pick out the ones that had their specific prefix, and then respond to the command. +Now, Discord is encouraging developers to switch their bots over to Application Commands, which is a new system meant to preserve the +privacy and safety of their users. But why exactly is Discord making us switch? What's the better option, Application Commands or prefix commands? Below, we'll discuss everything you need to know. ### Discord's Decision -Application Commands were conceptualized partly due to privacy concerns. When Discord first began, they weren't entirely concerned about bots -having access to the content of every message that was being sent. However, as Discord grew, this became more of a problem. Hypothetically, bots -could simply log every message they're able to receive via the Discord API and hand their contents over to a company or other third party. This is -a problem, since that data is meant to be used only by Discord. As such, they locked down Message Content, and introduced Application Commands for +Application Commands were conceptualized partly due to privacy concerns. When Discord first began, they weren't entirely concerned about bots +having access to the content of every message that was being sent. However, as Discord grew, this became more of a problem. Hypothetically, bots +could simply log every message they're able to receive via the Discord API and hand their contents over to a company or other third party. This is +a problem, since that data is meant to be used only by Discord. As such, they locked down Message Content, and introduced Application Commands for bot developers to use instead. Prefix commands work by reading messages, as described before. Application Commands, however, don't -work this way; instead, they work by having your bot get information from Discord about when a command was used. This way, Discord can limit -Message Content only to bots that _absolutely_ depend on it, such as auto-moderation bots. +work this way; instead, they work by having your bot get information from Discord about when a command was used. This way, Discord can limit +Message Content only to bots that *absolutely* depend on it, such as auto-moderation bots. ### Who has to Use Application Commands -Any verified bot that does not have the Message Content intent must use Application Commands. Discord is allowing developers to submit -applications for the ability to use the intent; however, since they don't want to keep supporting prefix commands due to privacy concerns, -they will automatically decline any application that includes only that as a reason. So, if your bot doesn't have an auto-moderation feature +Any verified bot that does not have the Message Content intent must use Application Commands. Discord is allowing developers to submit +applications for the ability to use the intent; however, since they don't want to keep supporting prefix commands due to privacy concerns, +they will automatically decline any application that includes only that as a reason. So, if your bot doesn't have an auto-moderation feature (or any other functionality that requires Message Content), you're out of luck. -Unverified bots, however, don't have to use Application Commands. This is because the Message Content intent is a `Privileged Intent`, meaning that -it must be applied for only if your bot is verified or about to be verified. Unverified bots don't have to apply for Privileged Intents, so they can +Unverified bots, however, don't have to use Application Commands. This is because the Message Content intent is a `Privileged Intent`, meaning that +it must be applied for only if your bot is verified or about to be verified. Unverified bots don't have to apply for Privileged Intents, so they can use them freely. So, if your bot is made only for a couple of servers, you can choose between prefix commands and Application Commands. However, if you plan on expanding @@ -172,7 +180,7 @@ your bot's reach, it'll have to use Application Commands. ### What's the Better Option Choosing which is the better option is up to you, if you're starting small. If -you plan on growing your bot, however, you will have to use Application Commands. Since prefix commands are slowly being phased out by Discord, +you plan on growing your bot, however, you will have to use Application Commands. Since prefix commands are slowly being phased out by Discord, there isn't much of a choice for developers of larger bots. ## Message Components @@ -183,8 +191,8 @@ sleek, and downright awesome. ### [Views](https://docs.pycord.dev/en/stable/api/ui_kit.html#discord.ui.View) -Views are not an Application Command nor are they a Message Component. Views are the invisible placeholders, or grid, -that Message Components lie in. Views can have up to 5 [`Action Rows`](https://docs.pycord.dev/en/stable/api/models.html#discord.ActionRow), +Views are not an Application Command nor are they a Message Component. Views are the invisible placeholders, or grid, +that Message Components lie in. Views can have up to 5 [`Action Rows`](https://docs.pycord.dev/en/stable/api/models.html#discord.ActionRow), and Action Rows can have a maximum of 5 slots. Below, you can find a table showing how many slots a Message Interaction takes up. | Component | Slots | @@ -199,12 +207,13 @@ a combination of them, such as 20 Buttons and a Select Menu or 10 Buttons and 3 ### [Buttons](https://docs.pycord.dev/en/stable/api/ui_kit.html#discord.ui.Button) -Buttons are the first of the Message Components. They allow for quick responses to prompts, such as for canceling or continuing an action. +Buttons are the first of the Message Components. They allow for quick responses to prompts, such as for canceling or continuing an action. Of course, these aren't their only uses; people have created awesome things with Buttons, such as calculators, games, and more! Discord Buttons are awesome! +
Click me! @@ -220,7 +229,7 @@ This is what a Button looks like, very simple and modern. To learn more about Bu ### [Select Menus](https://docs.pycord.dev/en/stable/api/ui_kit.html#discord.ui.Select) -Select Menus are the second of Discord's Message Components. They allow users to select from a list of choices, which your bot can then use. +Select Menus are the second of Discord's Message Components. They allow users to select from a list of choices, which your bot can then use. Select Menus are good for things such as choosing features, pages of a help menu, and more. ![Select Menu Example Image](../assets/interactions/select-menus-example.png) @@ -231,12 +240,12 @@ Menus page](./ui-components/dropdowns.mdx). ### [Modal Dialogs](https://docs.pycord.dev/en/stable/api/ui_kit.html#discord.ui.Modal) -Text Modals are the most recently added Message Component in Discord. They're useful for text input and filling out forms, such as a -sign-up for your bot's service. These are meant to replace long bot setup processes by allowing users to fill out multiple text fields, +Text Modals are the most recently added Message Component in Discord. They're useful for text input and filling out forms, such as a +sign-up for your bot's service. These are meant to replace long bot setup processes by allowing users to fill out multiple text fields, which avoids having the user send multiple messages for the bot. Modals can be accessed by either invoking an Application Command or by interacting with another UI Component. ![Text Modal Example Image](../assets/interactions/modal-example.png) -This is what a Text Modal looks like, easy to use and one of the most useful Message Components yet. To learn more about Text Modals, +This is what a Text Modal looks like, easy to use and one of the most useful Message Components yet. To learn more about Text Modals, please visit our [Modal Dialogs page](./ui-components/modal-dialogs.mdx). diff --git a/docs/interactions/ui-components/buttons.mdx b/docs/interactions/ui-components/buttons.mdx index ed84dfff..fd83dad3 100644 --- a/docs/interactions/ui-components/buttons.mdx +++ b/docs/interactions/ui-components/buttons.mdx @@ -17,7 +17,6 @@ import DiscordComponent from "@site/src/components/DiscordComponent"; import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; - On May 26, 2021, Discord added a new interaction called buttons. Instead of reactions, bots could now send buttons and users could use them to interact with bots. This opened up a whole new world of possibilities for bots. Soon after, developers made calculators, polls, and games like blackjack, UNO, @@ -62,7 +61,9 @@ Using this command should return the following message: button
+ This is a button! +
Click me! @@ -91,8 +92,6 @@ about making your button do amazing things, while Pycord handles the rest! ## Button Styles - - | Name | Usage | Color | | --------- | ----------------------------------------------------------------------------------------- | ------- | | Primary | `discord.ButtonStyle.primary` / `discord.ButtonStyle.blurple` | Blurple | @@ -158,33 +157,29 @@ async def button(ctx): - -```python -class MyView(discord.ui.View): - @discord.ui.button(label="A button", style=discord.ButtonStyle.primary) - async def button_callback(self, button, interaction): - button.disabled = True # set button.disabled to True to disable the button - button.label = "No more pressing!" # change the button's label to something else - await interaction.response.edit_message(view=self) # edit the message's view -``` - + ```python + class MyView(discord.ui.View): + @discord.ui.button(label="A button", style=discord.ButtonStyle.primary) + async def button_callback(self, button, interaction): + button.disabled = True # set button.disabled to True to disable the button + button.label = "No more pressing!" # change the button's label to something else + await interaction.response.edit_message(view=self) # edit the message's view + ``` - -```python -class MyView(discord.ui.View): - @discord.ui.button(emoji="😀", label="Button 1", style=discord.ButtonStyle.primary) - async def button_callback(self, button, interaction): - self.disable_all_items() - await interaction.response.edit_message(view=self) - - @discord.ui.button(label="Button 2", style=discord.ButtonStyle.primary) - async def second_button_callback(self, button, interaction): - self.disable_all_items() - await interaction.response.edit_message(view=self) -``` - + ```python + class MyView(discord.ui.View): + @discord.ui.button(emoji="😀", label="Button 1", style=discord.ButtonStyle.primary) + async def button_callback(self, button, interaction): + self.disable_all_items() + await interaction.response.edit_message(view=self) + + @discord.ui.button(label="Button 2", style=discord.ButtonStyle.primary) + async def second_button_callback(self, button, interaction): + self.disable_all_items() + await interaction.response.edit_message(view=self) + ``` @@ -193,41 +188,38 @@ class MyView(discord.ui.View): Sometimes, you want to have a button that is disabled after a certain amount of time. This is where timeouts come in. - - -```python -class MyView(discord.ui.View): - async def on_timeout(self): - self.disable_all_items() - await self.message.edit(content="You took too long! Disabled all the components.", view=self) - - @discord.ui.button() - async def button_callback(self, button, interaction): - ... - -@bot.command() -async def button(ctx): - await ctx.send("Press the button!", view=MyView(timeout=30)) -``` - - - + + ```python + class MyView(discord.ui.View): + async def on_timeout(self): + self.disable_all_items() + await self.message.edit(content="You took too long! Disabled all the components.", view=self) + + @discord.ui.button() + async def button_callback(self, button, interaction): + ... + + @bot.command() + async def button(ctx): + await ctx.send("Press the button!", view=MyView(timeout=30)) + ``` + -```python -class MyView(discord.ui.View): - def __init__(self): - super().__init__(timeout=10) # specify the timeout here + + ```python + class MyView(discord.ui.View): + def __init__(self): + super().__init__(timeout=10) # specify the timeout here - async def on_timeout(self): - self.disable_all_items() - await self.message.edit(content="You took too long! Disabled all the components.", view=self) + async def on_timeout(self): + self.disable_all_items() + await self.message.edit(content="You took too long! Disabled all the components.", view=self) - @discord.ui.button() - async def button_callback(self, button, interaction): - ... -``` - - + @discord.ui.button() + async def button_callback(self, button, interaction): + ... + ``` + Here, we disable all buttons and select menus in the view. Then, we edit the message to show that the timeout was reached. @@ -296,8 +288,8 @@ We highly recommend you learn about basic Python concepts like classes and inher **Resources**: -- [W3Schools's Guide to Python Classes & Objects](https://www.w3schools.com/python/python_classes.asp) -- [W3Schools's Guide to Python Inheritance](https://www.w3schools.com/python/python_inheritance.asp) +* [W3Schools's Guide to Python Classes & Objects](https://www.w3schools.com/python/python_classes.asp) +* [W3Schools's Guide to Python Inheritance](https://www.w3schools.com/python/python_inheritance.asp) #### Do buttons need any special permissions? @@ -309,7 +301,7 @@ That is up to you. Buttons do provide a cleaner interface for your bot and are e :::info Related Topics -- [Slash Commands](../application-commands/slash-commands) -- [Interactions Index](../../interactions) +* [Slash Commands](../application-commands/slash-commands) +* [Interactions Index](../../interactions) ::: diff --git a/docs/interactions/ui-components/dropdowns.mdx b/docs/interactions/ui-components/dropdowns.mdx index a0f19579..12f0ac4f 100644 --- a/docs/interactions/ui-components/dropdowns.mdx +++ b/docs/interactions/ui-components/dropdowns.mdx @@ -3,11 +3,9 @@ title: Select Menus description: Learn all about implementing Select Menus or Dropdowns in your Discord Bot with Pycord. --- - import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; - Shortly after the buttons were added, Discord added their second message component: Select Menus. Select Menus allow users to choose from a list of items sent by a bot. These are a great substitute for having a user send a number that corresponds to an option. You can even allow users to select multiple options from the Select Menus. This guide will show you the easy and painless ways of using them with Pycord. ## Concept @@ -67,8 +65,6 @@ This decorator adds a select menu to the view. This decorator takes a few argume That was the decorator. Now, the function itself is pretty simple. It takes two parameters, not including `self`. The parameters are `select`: The select menu, and `interaction`: a [`discord.InteractionResponse`](https://docs.pycord.dev/en/stable/api/models.html#discord.InteractionResponse) object. Both of these are passed by Pycord, so you just need to specify them in the function! - - In the callback, you could do anything you want. You get the two parameters `select` and `interaction` to play around with. Here, we send a message using `await interaction.response.send_message` (where interaction is [`discord.InteractionResponse`](https://docs.pycord.dev/en/stable/api/models.html#discord.InteractionResponse)) with content `select.values[0]`, which sends the label of the first/only option the user selected. Obviously, this is only an example, and you could do just about anything you want. Finally, we create a global slash command called `flavour` that sends a message "Choose a flavor!" along with the view @@ -81,24 +77,25 @@ about making your code do amazing things, while Pycord handles the rest! #### Select Menu Properties -- `select_type`: The type of select to create. This must be a [`discord.ComponentType`](https://docs.pycord.dev/en/stable/api/enums.html#discord.ComponentType) value. -- `channel_types`: A list of channel types that can be selected in the menu. This is only valid for selects of `select_type` [`discord.ComponentType.channel_select`](https://docs.pycord.dev/en/stable/api/enums.html#discord.ComponentType). -- `options`: A list of [`discord.SelectOption`](https://docs.pycord.dev/en/stable/api/data_classes.html#discord.SelectOption) values. These are the options that can be selected in this menu. -- `placeholder` is the placeholder text shown in the select menu if no option is selected. -- `custom_id`: The ID of the select menu that gets received during an interaction. It is recommended not to set this to anything unless you are trying to create a persistent view. -- `row`: The relative row this select menu belongs to. A Discord component can only have 5 rows. By default, items are arranged automatically into those 5 rows. If you’d like to control the relative positioning of the row then passing an index is advised. For example, row=1 will show up before row=2. Defaults to None, which is automatic ordering. The row number must be between 0 and 4 (i.e. zero indexed). -- `min_values`: The minimum number of items that must be chosen for this select menu. Defaults to 1 and must be between 1 and 25. -- `max_values`: The maximum number of items that must be chosen for this select menu. Defaults to 1 and must be between 1 and 25. -- `disabled`: Whether the select is disabled or not. Defaults to False. +* `select_type`: The type of select to create. This must be a [`discord.ComponentType`](https://docs.pycord.dev/en/stable/api/enums.html#discord.ComponentType) value. +* `channel_types`: A list of channel types that can be selected in the menu. This is only valid for selects of `select_type` [`discord.ComponentType.channel_select`](https://docs.pycord.dev/en/stable/api/enums.html#discord.ComponentType). +* `options`: A list of [`discord.SelectOption`](https://docs.pycord.dev/en/stable/api/data_classes.html#discord.SelectOption) values. These are the options that can be selected in this menu. +* `placeholder` is the placeholder text shown in the select menu if no option is selected. +* `custom_id`: The ID of the select menu that gets received during an interaction. It is recommended not to set this to anything unless you are trying to create a persistent view. +* `row`: The relative row this select menu belongs to. A Discord component can only have 5 rows. By default, items are arranged automatically into those 5 rows. If you’d like to control the relative positioning of the row then passing an index is advised. For example, row=1 will show up before row=2. Defaults to None, which is automatic ordering. The row number must be between 0 and 4 (i.e. zero indexed). +* `min_values`: The minimum number of items that must be chosen for this select menu. Defaults to 1 and must be between 1 and 25. +* `max_values`: The maximum number of items that must be chosen for this select menu. Defaults to 1 and must be between 1 and 25. +* `disabled`: Whether the select is disabled or not. Defaults to False. #### Select Option Properties In the `options` parameter, you pass a list of [`discord.SelectOption`](https://docs.pycord.dev/en/stable/api/data_classes.html#discord.SelectOption) values. This class also has a few parameters: -- `default` (whether the option is selected by default) -- `description` (an additional description, if any) -- `emoji` (a string or an emoji object, if any) -- `label` (the name displayed to users, can be up to 100 characters) -- `value` (a special value of the option, defaults to the label). + +* `default` (whether the option is selected by default) +* `description` (an additional description, if any) +* `emoji` (a string or an emoji object, if any) +* `label` (the name displayed to users, can be up to 100 characters) +* `value` (a special value of the option, defaults to the label). ## Select Types @@ -188,32 +185,28 @@ async def select_menu(ctx): - -```python -class MyView(discord.ui.View): - @discord.ui.select(options = [...]) - async def select_callback(self, select, interaction): - select.disabled = True # set the status of the select as disabled - await interaction.response.edit_message(view=self) # edit the message to show the changes -``` - + ```python + class MyView(discord.ui.View): + @discord.ui.select(options = [...]) + async def select_callback(self, select, interaction): + select.disabled = True # set the status of the select as disabled + await interaction.response.edit_message(view=self) # edit the message to show the changes + ``` - -```python -class MyView(discord.ui.View): - @discord.ui.select(options = [...]) - async def first_select_callback(self, select, interaction): - self.disable_all_items() - await interaction.response.edit_message(view=self) # edit the message to show the changes - - @discord.ui.select(options = [...]) - async def second_select_callback(self, select, interaction): - self.disable_all_items() - await interaction.response.edit_message(view=self) -``` - + ```python + class MyView(discord.ui.View): + @discord.ui.select(options = [...]) + async def first_select_callback(self, select, interaction): + self.disable_all_items() + await interaction.response.edit_message(view=self) # edit the message to show the changes + + @discord.ui.select(options = [...]) + async def second_select_callback(self, select, interaction): + self.disable_all_items() + await interaction.response.edit_message(view=self) + ``` @@ -222,44 +215,41 @@ class MyView(discord.ui.View): You may want a select menu to automatically stop working after a certain amount of time. This is where timeouts come in. - - -```python -class MyView(discord.ui.View): - async def on_timeout(self): - self.disable_all_items() - await self.message.edit(content="You took too long! Disabled all the components.", view=self) - - @discord.ui.select(options = [...]) - async def select_callback(self, select, interaction): - ... - -@bot.command() -async def select(ctx): - await ctx.send(view=MyView(timeout=30)) # specify the timeout here -``` - - - - -```python -class MyView(discord.ui.View): - def __init__(self): - super().__init__(timeout=10) # specify the timeout here + + ```python + class MyView(discord.ui.View): + async def on_timeout(self): + self.disable_all_items() + await self.message.edit(content="You took too long! Disabled all the components.", view=self) + + @discord.ui.select(options = [...]) + async def select_callback(self, select, interaction): + ... + + @bot.command() + async def select(ctx): + await ctx.send(view=MyView(timeout=30)) # specify the timeout here + ``` + - async def on_timeout(self): - self.disable_all_items() - await self.message.edit(content="You took too long! Disabled all the components.", view=self) + + ```python + class MyView(discord.ui.View): + def __init__(self): + super().__init__(timeout=10) # specify the timeout here - @discord.ui.select(options = [...]) - async def select_callback(self, select, interaction): - ... -``` + async def on_timeout(self): + self.disable_all_items() + await self.message.edit(content="You took too long! Disabled all the components.", view=self) - + @discord.ui.select(options = [...]) + async def select_callback(self, select, interaction): + ... + ``` + -Here, we disable all buttons and select menus in the view. Then, we edit the message to show that the timeout was reached. +Here, we disable all buttons and select menus in the view. Then, we edit the message to show that the timeout was reached. :::note @@ -325,8 +315,8 @@ We highly recommend you learn about basic Python concepts like classes and inher **Resources**: -- [W3Schools's Guide to Python Classes & Objects](https://www.w3schools.com/python/python_classes.asp) -- [W3Schools's Guide to Python Inheritance](https://www.w3schools.com/python/python_inheritance.asp) +* [W3Schools's Guide to Python Classes & Objects](https://www.w3schools.com/python/python_classes.asp) +* [W3Schools's Guide to Python Inheritance](https://www.w3schools.com/python/python_inheritance.asp) #### Do select menus need any special permissions? @@ -334,7 +324,7 @@ No new permissions are needed in the bot or in the server. :::info Related Topics -- [Slash Commands](../application-commands/slash-commands) -- [Interactions Index](../../interactions) +* [Slash Commands](../application-commands/slash-commands) +* [Interactions Index](../../interactions) ::: diff --git a/docs/interactions/ui-components/modal-dialogs.mdx b/docs/interactions/ui-components/modal-dialogs.mdx index d13c9447..7952f51a 100644 --- a/docs/interactions/ui-components/modal-dialogs.mdx +++ b/docs/interactions/ui-components/modal-dialogs.mdx @@ -17,7 +17,7 @@ import DiscordComponent from "@site/src/components/DiscordComponent"; import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; -Modal Dialogs, also known as "modals", provide a form-like structure for bots to receive input from users. No extra permissions are needed for bots to send modal dialogs, so it becomes a convenient workaround for bots to receive longer input without needing the Message Content [intent](../../popular-topics/intents). +Modal Dialogs, also known as "modals", provide a form-like structure for bots to receive input from users. No extra permissions are needed for bots to send modal dialogs, so it becomes a convenient workaround for bots to receive longer input without needing the Message Content [intent](../../popular-topics/intents). ## Concept @@ -43,35 +43,32 @@ class MyModal(discord.ui.Modal): ``` - - -The `ctx` parameter we define in Application Commands receives an [`ApplicationContext`](https://docs.pycord.dev/en/stable/api/application_commands.html#discord.ApplicationContext) object. Using its `send_modal()` coroutine, you can send a Modal dialog to the user invoking the Application Command. - -```py -@bot.slash_command() -async def modal_slash(ctx: discord.ApplicationContext): - """Shows an example of a modal dialog being invoked from a slash command.""" - modal = MyModal(title="Modal via Slash Command") - await ctx.send_modal(modal) -``` - - - - -The `interaction` parameter we define in UI Components receives an [`Interaction`](https://docs.pycord.dev/en/stable/api/models.html#discord.Interaction) object. The `response` attribute of the object contains an [`InteractionResponse`](https://docs.pycord.dev/en/stable/api/models.html#discord.InteractionResponse) object, with various coroutines such as `send_message()` and `send_modal()`, which we utilize. - -```py -class MyView(discord.ui.View): - @discord.ui.button(label="Send Modal") - async def button_callback(self, button, interaction): - await interaction.response.send_modal(MyModal(title="Modal via Button")) - -@bot.slash_command() -async def send_modal(ctx): - await ctx.respond(view=MyView()) -``` - - + + The `ctx` parameter we define in Application Commands receives an [`ApplicationContext`](https://docs.pycord.dev/en/stable/api/application_commands.html#discord.ApplicationContext) object. Using its `send_modal()` coroutine, you can send a Modal dialog to the user invoking the Application Command. + + ```py + @bot.slash_command() + async def modal_slash(ctx: discord.ApplicationContext): + """Shows an example of a modal dialog being invoked from a slash command.""" + modal = MyModal(title="Modal via Slash Command") + await ctx.send_modal(modal) + ``` + + + + The `interaction` parameter we define in UI Components receives an [`Interaction`](https://docs.pycord.dev/en/stable/api/models.html#discord.Interaction) object. The `response` attribute of the object contains an [`InteractionResponse`](https://docs.pycord.dev/en/stable/api/models.html#discord.InteractionResponse) object, with various coroutines such as `send_message()` and `send_modal()`, which we utilize. + + ```py + class MyView(discord.ui.View): + @discord.ui.button(label="Send Modal") + async def button_callback(self, button, interaction): + await interaction.response.send_modal(MyModal(title="Modal via Button")) + + @bot.slash_command() + async def send_modal(ctx): + await ctx.respond(view=MyView()) + ``` + The above example uses an embed to display the results of the modal submission, but you can do anything you want with the text provided by the user. @@ -100,8 +97,8 @@ long = 2 :::info Related Topics -- [Slash Commands](../application-commands/slash-commands) -- [Buttons](./buttons) -- [Interactions Index](../../interactions) +* [Slash Commands](../application-commands/slash-commands) +* [Buttons](./buttons) +* [Interactions Index](../../interactions) ::: diff --git a/docs/introduction.mdx b/docs/introduction.mdx index 2e4dd4b3..547d83a2 100644 --- a/docs/introduction.mdx +++ b/docs/introduction.mdx @@ -10,19 +10,19 @@ Pycord is a modern, easy to use, feature-rich, and async ready API wrapper for D Pycord is an advanced and complex Python library. To take advantage of the full capabilities of Pycord, you will need to have a good understanding of Python. You should know the basics of Python and have an understanding of the following concepts: -- Variables -- Data Types -- Functions -- Packages -- Conditionals -- Loops -- Classes -- Object-Oriented Programming -- Inheritance -- Exception Handling -- Iterators -- Coroutines -- Async/Await +* Variables +* Data Types +* Functions +* Packages +* Conditionals +* Loops +* Classes +* Object-Oriented Programming +* Inheritance +* Exception Handling +* Iterators +* Coroutines +* Async/Await This list is not exhaustive, but it should give you a good idea of what you need to know to get started. @@ -32,18 +32,18 @@ When you see an ellipsis - that's the three dots - in this guide, it is a placeh Here are some good resources to get started or to freshen up your Python knowledge: -- [Official Beginner's Guide](https://wiki.python.org/moin/BeginnersGuide) -- [Official Tutorial](https://docs.python.org/3/tutorial/) -- [Automate the Boring Stuff, a free online book for complete beginners to programming](https://automatetheboringstuff.com/) -- [Learn Python in y Minutes, complete cheat sheet for people who know programming already](https://learnxinyminutes.com/docs/python3/) -- [Swaroopch's free Python book](http://python.swaroopch.com/) -- [Codeabbey, exercises for beginners](http://www.codeabbey.com/) +* [Official Beginner's Guide](https://wiki.python.org/moin/BeginnersGuide) +* [Official Tutorial](https://docs.python.org/3/tutorial/) +* [Automate the Boring Stuff, a free online book for complete beginners to programming](https://automatetheboringstuff.com/) +* [Learn Python in y Minutes, complete cheat sheet for people who know programming already](https://learnxinyminutes.com/docs/python3/) +* [Swaroopch's free Python book](http://python.swaroopch.com/) +* [Codeabbey, exercises for beginners](http://www.codeabbey.com/) ## Credits First of all, we would like to thank [Rapptz](https://github.com/Rapptz) for the original [discord.py](https://pypi.org/project/discord.py) library. Pycord is a maintained fork of this library. -We would also like to thank the [discord.js guide](https://discordjs.guide), which inspired this guide style-wise, and the [original Pycord Guide](https://namantech.me/pycord), which inspired some content in this guide. +We would also like to thank the [discord.js guide](https://discordjs.guide), which inspired this guide style-wise, and the now defunct [original Pycord Guide](https://web.archive.org/web/20220813041929/https://namantech.me/pycord/), which inspired some content in this guide. We created this guide using [Docusaurus v2](https://docusaurus.io), a modern static site generator for React. We would also like to thank Danktuary for his [`@discord-message-components/react`](https://www.npmjs.com/package/@discord-message-components/react) package, from which we took the Discord message components. diff --git a/docs/more/contributing.mdx b/docs/more/contributing.mdx index fde3eaaf..c4596ee2 100644 --- a/docs/more/contributing.mdx +++ b/docs/more/contributing.mdx @@ -16,8 +16,8 @@ import DiscordComponent from "@site/src/components/DiscordComponent"; This page outlines some of the basic syntax you need to know to contribute to the guide. We recommend you also check out: -- [Docusaurus's Docs](https://docusaurus.io/docs/) -- [Contributing Rules](https://github.com/Pycord-Development/guide/blob/master/.github/CONTRIBUTING.md) +* [Docusaurus's Docs](https://docusaurus.io/docs/) +* [Contributing Rules](https://github.com/Pycord-Development/guide/blob/master/.github/CONTRIBUTING.md) ## Info @@ -30,6 +30,7 @@ MDX allows you to use JSX in your markdown content. Let's visit the [`docs/`](https://github.com/Pycord-Development/guide/tree/master/docs) directory and check its file structure. We can see various folders and a few files in it. Let's talk a bit about the `introduction.mdx` file. At the top, you can see something like: + ```md --- title: Introduction @@ -113,72 +114,74 @@ We can use emojis too! :joy: ````
-Preview -
+ Preview -Markdown syntax is pretty easy. You can add **bold**, _italic_ and _underline_ text. You can use ~~strikethrough~~. You can use `inline code blocks`. +
+ Markdown syntax is pretty easy. You can add **bold**, *italic* and *underline* text. You can use ~~strikethrough~~. You can use `inline code blocks`. -```python -print("We can use code blocks like this.") -``` + ```python + print("We can use code blocks like this.") + ``` -You can add [links to other websites](https://pycord.dev). You can add images by adding ![alt text](@site/static/img/favicon.ico). + You can add [links to other websites](https://pycord.dev). You can add images by adding ![alt text](@site/static/img/favicon.ico). -- You can create -- unordered lists like this + * You can create + * unordered lists like this -1. Or ordered lists -2. Like this + 1. Or ordered lists -3. If you want markdown to automatically detect what number you are on, you can use `1.` -4. Like this + 2. Like this - # Headers + 3. If you want markdown to automatically detect what number you are on, you can use `1.` - ## Go + 4. Like this - ### Like + # Headers - #### This + ## Go -You can even use HTML in Markdown. + ### Like -This text is monospaced -Use
to add a break line. + #### This -> We can use blockquotes too. + You can even use HTML in Markdown. -2 ways to create tables: + This text is monospaced + Use
to add a break line. - - - - - - - - - -
HeaderHeader
CellCell
+ > We can use blockquotes too. -| Header | Header | -| ------ | ------ | -| Cell | Cell | + 2 ways to create tables: -Here's a line for us to start with. + + + + + -This line is separated from the one above by two new lines, so it will be a _separate paragraph_. + + + + +
HeaderHeader
CellCell
-This line is also a separate paragraph, but... -This line is only separated by a single newline, so it's a separate line in the _same paragraph_. + | Header | Header | + | ------ | ------ | + | Cell | Cell | -We can use emojis too! :joy: + Here's a line for us to start with. + + This line is separated from the one above by two new lines, so it will be a *separate paragraph*. + + This line is also a separate paragraph, but... + This line is only separated by a single newline, so it's a separate line in the *same paragraph*. -- [x] We can have task lists too -- [ ] This is a task -- [ ] That's not done yet + We can use emojis too! :joy: -
+ * [x] We can have task lists too + * [ ] This is a task + * [ ] That's not done yet +
## Admonitions @@ -230,53 +233,51 @@ You can edit an admonition's title by adding text after the `:::` and name, like ```
-Preview -
- -:::note - -Some **content** with _markdown_ `syntax`. + Preview -::: +
+ :::note -:::tip + Some **content** with *markdown* `syntax`. -Some **content** with _markdown_ `syntax`. + ::: -::: + :::tip -:::info + Some **content** with *markdown* `syntax`. -Some **content** with _markdown_ `syntax`. + ::: -::: + :::info -:::caution + Some **content** with *markdown* `syntax`. -Some **content** with _markdown_ `syntax`. + ::: -::: + :::caution -:::danger + Some **content** with *markdown* `syntax`. -Some **content** with _markdown_ `syntax`. + ::: -::: + :::danger -:::important + Some **content** with *markdown* `syntax`. -Remember that it's `:::important`, not `::: important` with a space! + ::: -::: + :::important -:::tip Cool Stuff + Remember that it's `:::important`, not `::: important` with a space! -You can edit an admonition's title by adding text after the `:::` and name, like this! + ::: -::: + :::tip Cool Stuff -
+ You can edit an admonition's title by adding text after the `:::` and name, like this! + ::: +
## Discord Message Components @@ -326,7 +327,7 @@ This is where you list a `DiscordMessage`. -
+
It has a pretty straightforward syntax. @@ -360,6 +361,7 @@ To make a message authored by a slash command, do the following: update
+ Updated dependencies to the latest version!
@@ -394,7 +396,9 @@ To make a message with buttons, do the following: work + Work Done! +
Work More @@ -408,51 +412,53 @@ To make a message with buttons, do the following: There are a few things you need to take care of: -1. Make sure that the spelling and grammar is perfect. We have a GitHub action configured that will warn you about spelling errors when you start a pull request. Make sure to commit your changes accordingly. +1. Make sure that the spelling and grammar is perfect. We have a GitHub action configured that will warn you about spelling errors when you start a pull request. Make sure to commit your changes accordingly. - As for the grammar, you should try reading the changes you have done and wait for reviews from others. + As for the grammar, you should try reading the changes you have done and wait for reviews from others. -2. A common mistake people make is incorrect header style. People often think that the less the important the topic is, the lower it's heading style should be. +2. A common mistake people make is incorrect header style. People often think that the less the important the topic is, the lower it's heading style should be. - ```md - [PAGE STARTS] - # Topic - ## Less Important Topic - ## Subtopic - ``` - ```md - [PAGE STARTS] - # About - [Introduction] + ```md + [PAGE STARTS] + # Topic + ## Less Important Topic + ## Subtopic + ``` - ## Installation - [Content] + ```md + [PAGE STARTS] + # About + [Introduction] - ### Windows - [Content] - ``` + ## Installation + [Content] - That's VERY wrong. Here's the correct example: + ### Windows + [Content] + ``` - ```md - [PAGE STARTS] - [Introduction] - ## Topic - ## Less Important Topic - ### Subtopic - ``` - ```md - [PAGE STARTS] - [Introduction] + That's VERY wrong. Here's the correct example: - ## About - [More Information] + ```md + [PAGE STARTS] + [Introduction] + ## Topic + ## Less Important Topic + ### Subtopic + ``` - ## Installation - [Content] + ```md + [PAGE STARTS] + [Introduction] - ### Windows - [Content] - ``` + ## About + [More Information] + + ## Installation + [Content] + + ### Windows + [Content] + ``` - Note that the `---`s at the beginning have been skipped here. + Note that the `---`s at the beginning have been skipped here. diff --git a/docs/more/git.mdx b/docs/more/git.mdx index 4bd09ce7..3c1d05ec 100644 --- a/docs/more/git.mdx +++ b/docs/more/git.mdx @@ -1,47 +1,47 @@ ---- +--- title: Installing Git -description: Learn how you can install Git on your system. ---- - -Git is software for tracking changes in any set of files (also known as a "version control" software), usually used for coordinating work among programmers collaboratively developing source code during software development. Its goals include speed, data integrity, and support for distributed, non-linear workflows (thousands of parallel branches running on different systems). - -Let's see how to install Git on different platforms. - -## Windows - -On Windows, Git can be installed via: - -- [Git for Windows](https://gitforwindows.org) -- [Git Scm](https://git-scm.com/download/windows) - -## Linux - -On Linux, Git is probably already installed in your distribution's repository. If not, you can install it via [Git for Linux](https://git-scm.com/download/linux). You can also install it via the built-in package manager on your Linux distro. - -## Mac - -You can install Git for your macOS computer via [Git for Mac](https://git-scm.com/download/mac). Alternatively, it can be also be installed from the Xcode Command Line Tools by installing Xcode from the App Store, or by running this: - - xcode-select --install - -## Using Package Managers - -You can also install Git using package managers. - -### Chocolatey - -If you use the Chocolatey package manager, you can install Git using: - - choco install git - -### Scoop - -If you use Scoop, you can install Git using: - - scoop install git - -### Brew - -If you're on macOS or Linux, you can install Git using: - - brew install git +description: Learn how you can install Git on your system. +--- + +Git is software for tracking changes in any set of files (also known as a "version control" software), usually used for coordinating work among programmers collaboratively developing source code during software development. Its goals include speed, data integrity, and support for distributed, non-linear workflows (thousands of parallel branches running on different systems). + +Let's see how to install Git on different platforms. + +## Windows + +On Windows, Git can be installed via: + +* [Git for Windows](https://gitforwindows.org) +* [Git Scm](https://git-scm.com/download/windows) + +## Linux + +On Linux, Git is probably already installed in your distribution's repository. If not, you can install it via [Git for Linux](https://git-scm.com/download/linux). You can also install it via the built-in package manager on your Linux distro. + +## Mac + +You can install Git for your macOS computer via [Git for Mac](https://git-scm.com/download/mac). Alternatively, it can be also be installed from the Xcode Command Line Tools by installing Xcode from the App Store, or by running this: + +xcode-select --install + +## Using Package Managers + +You can also install Git using package managers. + +### Chocolatey + +If you use the Chocolatey package manager, you can install Git using: + +choco install git + +### Scoop + +If you use Scoop, you can install Git using: + +scoop install git + +### Brew + +If you're on macOS or Linux, you can install Git using: + +brew install git diff --git a/docs/more/virtual-environments.mdx b/docs/more/virtual-environments.mdx index 811b6ea1..b0b8c7ea 100644 --- a/docs/more/virtual-environments.mdx +++ b/docs/more/virtual-environments.mdx @@ -4,6 +4,7 @@ description: Learn how to set up a virtual environment for Pycord. --- ## Setup + Sometimes you want to keep libraries from polluting system installs or use a different version of libraries than the ones installed on the system. You might also not have permissions to install libraries system-wide. For this purpose, the standard library as of Python 3.3 comes with a concept called “Virtual Environment”s to help maintain these separate versions. A more in-depth tutorial is found on [Virtual Environments and Packages](https://docs.python.org/3/tutorial/venv.html). @@ -16,24 +17,29 @@ Go to your project’s working directory: $ cd your-bot-source $ python3 -m venv venv ``` + Activate the virtual environment: ```bash $ source venv/bin/activate ``` + On Windows you activate it with: ```batch $ venv\Scripts\activate.bat ``` + Use pip like usual: ```bash $ pip install -U py-cord ``` + Congratulations. You now have a virtual environment all set up. ## Additional info + It can be useful to set up a requirements.txt, so you can just put all of your dependencies in there and have pip install it. For instance, if you wanted to have the latest 2.0 version of pycord and [pytz](https://github.com/stub42/pytz/blob/master/src/README.rst), just create a file named requirements.txt with the following contents: @@ -41,13 +47,16 @@ For instance, if you wanted to have the latest 2.0 version of pycord and [pytz]( py-cord>=2.0.0 pytz ``` + And then (in your virtual environment) you can just execute + ```bash pip install -r requirements.txt ``` To keep from committing your virtual environment to git, you can set up a .gitignore file with the following line (assuming you named your virtual environment venv like the above example): + ``` venv/ ``` diff --git a/docs/popular-topics/cogs.mdx b/docs/popular-topics/cogs.mdx index 28b34933..554011be 100644 --- a/docs/popular-topics/cogs.mdx +++ b/docs/popular-topics/cogs.mdx @@ -72,7 +72,7 @@ not work on its own. In your main bot file, you must add the following code: bot.load_extension('cogs.greetings') ``` -This loads the file `cogs/greetings.py` and adds it to the bot. +This loads the file `cogs/greetings.py` and adds it to the bot. The argument of `load_extension` should be your cog's path (e.g. cogs/greetings.py) without the file extension and with the `/` replaced with `.` @@ -97,9 +97,9 @@ is because cogs work slightly different from a regular file. ### The `self` variable -The self variable is a variable that represents a class. In the case of cogs, `self` represents +The self variable is a variable that represents a class. In the case of cogs, `self` represents the cog. In the `__init__` function, you can see that we have `self.bot = bot`. `bot` represents your -`discord.Bot` or `discord.ext.commands.Bot` instance, which is used for some functions. +`discord.Bot` or `discord.ext.commands.Bot` instance, which is used for some functions. This means that instead of using functions that would usually be accessed via `bot`, you now need to access them via `self.bot` @@ -111,7 +111,7 @@ wouldn't be able to access our bot instance. ### Creating Commands When creating prefixed commands, your decorator would usually be something like `@bot.command()`. If you're using -cogs, this isn't the case. In a cog, you can't access the bot instance outside of functions, so to +cogs, this isn't the case. In a cog, you can't access the bot instance outside of functions, so to register a function as a command, you must instead use `@commands.command()`. Similar to prefixed commands, you'll have to use either the `@discord.slash_command()`, `@discord.user_command()`, @@ -132,9 +132,9 @@ create a help command [here](../extensions/commands/help-command). :::info Related Topics -- [Creating a Help Command](../extensions/commands/help-command) -- [Rules and Common Practices](../getting-started/rules-and-common-practices) -- [Prefixed Commands](../extensions/commands/prefixed-commands) -- [Application Commands](../interactions#application-commands) +* [Creating a Help Command](../extensions/commands/help-command) +* [Rules and Common Practices](../getting-started/rules-and-common-practices) +* [Prefixed Commands](../extensions/commands/prefixed-commands) +* [Application Commands](../interactions#application-commands) ::: diff --git a/docs/popular-topics/error-handling.mdx b/docs/popular-topics/error-handling.mdx index d2dea731..26752160 100644 --- a/docs/popular-topics/error-handling.mdx +++ b/docs/popular-topics/error-handling.mdx @@ -12,12 +12,12 @@ import DiscordComponent, { defaultOptions } from "@site/src/components/DiscordCo ## About -When using the library, errors are frequently raised due to various reasons. These reasons range from the Discord API +When using the library, errors are frequently raised due to various reasons. These reasons range from the Discord API failing your bot's request due to missing permissions or an invalid syntax error. Before going into error handling, it's best that you learn the basic ways of handling errors. A good resource is: -* [W3Schools' Guide to Python Try-Except Statements](https://www.w3schools.com/python/python_try_except.asp) +* [W3Schools' Guide to Python Try-Except Statements](https://www.w3schools.com/python/python_try_except.asp) ## Basic Handling @@ -57,43 +57,52 @@ bot.run("TOKEN") If you respond within 30 seconds, the interaction will look like so: - -
- - feedback - -
- Hey, Dorukyum! Send your feedback within the next 30 seconds please! -
- - Great bot! - - - Thanks for the feedback! -
- Received feedback: Great bot! -
+ +
+ + feedback + +
+ + Hey, Dorukyum! Send your feedback within the next 30 seconds please! +
+ + + Great bot! + + + + Thanks for the feedback! + +
+ + Received feedback: Great bot! +
+
Otherwise, if you don't respond in time, the interaction will go as follows: - -
- - feedback - -
- Hey, Dorukyum! Send your feedback within the next 30 seconds please! -
- - Timed out, please try again! - + +
+ + feedback + +
+ + Hey, Dorukyum! Send your feedback within the next 30 seconds please! +
+ + + Timed out, please try again! +
+
-This basic method of error handling can be extended to handle +This basic method of error handling can be extended to handle many other errors including ones raised directly by py-cord. ## Per-Command Handling @@ -104,9 +113,9 @@ Each and every command can have it's own error handler made to handle specific e An example of per-command error handling is as follows: :::note Bridge Commands -As of writing this guide page, bridge commands do not currently support per-command error handling. +As of writing this guide page, bridge commands do not currently support per-command error handling. -For these types of commands, it is recommended to utilize global error handling +For these types of commands, it is recommended to utilize global error handling until [the feature](https://github.com/Pycord-Development/pycord/issues/1388) is added. ::: @@ -137,29 +146,33 @@ bot.run("TOKEN") If your ID is registered as the owner ID, you'll get the following: - -
- - secret - -
- Hey Dorukyum! This is a secret command! -
+ +
+ + secret + +
+ + Hey Dorukyum! This is a secret command! +
+
Any other user whose ID doesn't match the bot owner's will get the following: - -
- - secret - -
- Sorry, only the bot owner can use this command! -
+ +
+ + secret + +
+ + Sorry, only the bot owner can use this command! +
+
This local (per-command) error handler can also be used to handle the same types of errors that standard try-except @@ -168,7 +181,7 @@ statements can handle. This is done by using the same method as above with the ` ## Per-Cog Handling Adding error handlers per-command can be quite the task in terms of work if you have a lot. If you have happened to -group your commands in cogs, then you're in luck! You can create an error handler that is specific to a cog and +group your commands in cogs, then you're in luck! You can create an error handler that is specific to a cog and handles all errors raised by commands inside that cog. Here's an example of a bot with a cog that implements its own error handling: @@ -225,37 +238,43 @@ bot.run("TOKEN") If you use this command in a DM context, you'll get the following: - + + !avatar + + + +
+ !avatar - - -
- - !avatar - -
- - Here's your enlarged avatar, BobDotCom! - -
+
+
+ + + Here's your enlarged avatar, BobDotCom! + +
+
Otherwise, if used in a guild context: - + + !avatar + + + +
+ !avatar - - -
- - !avatar - -
- Sorry, you can only use this in private messages! -
+
+
+ + Sorry, you can only use this in private messages! +
+
Per-cog error handling comes in very handy as you can relegate all of your error handling to a single function instead @@ -264,7 +283,7 @@ of spreading it out across several per-command error handlers or inside the comm ## Global Handling If separating your error handling is not how you would like to handle errors, then global error handling is the way to -go. This method of handling allows you to relegate all handling to a single function that resides within your bot +go. This method of handling allows you to relegate all handling to a single function that resides within your bot instance. A non-subclassed bot would implement this like so: @@ -300,23 +319,27 @@ If you've subclassed your bot, the `on_application_command_error` event will be The error handling used above will yield this interaction if the command is used again too quickly: - -
- - ping - -
- Pong! 49 ms. -
- -
- - ping - -
- This command is currently on cooldown! -
+ +
+ + ping + +
+ + Pong! 49 ms. +
+ + +
+ + ping + +
+ + This command is currently on cooldown! +
+
The only issue regarding global error handling is that, if you have a large amount of commands, the global handler may @@ -331,8 +354,8 @@ passed at initialization through `self.bot`. If this is new to you, we recommend checking out these helpful resources to learn more about classes and cogs: -* [W3Schools' Guide to Python Classes & Objects](https://www.w3schools.com/python/python_classes.asp) -* [Our Cogs Guide Page](./cogs) +* [W3Schools' Guide to Python Classes & Objects](https://www.w3schools.com/python/python_classes.asp) +* [Our Cogs Guide Page](./cogs) #### How many errors can I handle in a single error handler? @@ -340,9 +363,10 @@ While all the examples in this guide page only handle one specific error and re- error handlers can be extended to catch many errors. In [basic handling](#basic) (i.e. try/except statements) you can do one of two things: -* Explicitly handle the errors you know might get raised and then have a broad `except Exception as exc:` statement -as a catch-all. -* Catch any and all errors via the catch-all statement mentioned above. + +* Explicitly handle the errors you know might get raised and then have a broad `except Exception as exc:` statement + as a catch-all. +* Catch any and all errors via the catch-all statement mentioned above. In [per-command](#percommand), [per-cog](#percog), and [global handling](#global), you can use elif clauses with the built-in isinstance function to catch specific errors. Atop of this, an else clause can be used to catch any other @@ -351,32 +375,33 @@ errors you either don't want to handle or want to relegate to a different error #### Can I use more than one type of error handler at once? Thankfully, all of these different ways of error handling can be mixed together, so you don't have to pick just one! -For commands that raise specific errors that no other commands will raise, you can use [per-command](#percommand). +For commands that raise specific errors that no other commands will raise, you can use [per-command](#percommand). For cogs that raise specific errors that no other cogs will raise, use [per-cog](#percog)! Lastly, for errors that -occur frequently across all commands and cogs, use [global handling](#global)! +occur frequently across all commands and cogs, use [global handling](#global)! -However, one important note to remember is that you should always raise the error again in an error handler if it +However, one important note to remember is that you should always raise the error again in an error handler if it isn't handled there! If you don't do this, the error will go ignored and your other handlers won't have a chance to do their work! #### What's the difference between slash and prefixed command error handling? Although most examples shown here use slash commands, the [per-cog handling](#percog) section presents a prefixed -command. The main difference you may notice is the change in command signature. +command. The main difference you may notice is the change in command signature. To make the distinguishing features apparent: -* Slash commands use `on_application_command_error(ctx: discord.ApplicationContext, error: discord.DiscordException)` -as presented in the [per-command](#percommand) and [global handling](#global) examples. -* Prefixed commands use `on_command_error(ctx: commands.Context, error: commands.CommandError)` as presented in the -[per-cog handling](#percog) example. + +* Slash commands use `on_application_command_error(ctx: discord.ApplicationContext, error: discord.DiscordException)` + as presented in the [per-command](#percommand) and [global handling](#global) examples. +* Prefixed commands use `on_command_error(ctx: commands.Context, error: commands.CommandError)` as presented in the + [per-cog handling](#percog) example. This distinction is made as both types of commands need their own system for handling errors that are specific to themselves. :::info Related Topics -* [Slash Commands](../interactions/application-commands/slash-commands) -* [Prefixed Commands](../extensions/commands/prefixed-commands) -* [Cogs](./cogs) +* [Slash Commands](../interactions/application-commands/slash-commands) +* [Prefixed Commands](../extensions/commands/prefixed-commands) +* [Cogs](./cogs) ::: diff --git a/docs/popular-topics/intents.mdx b/docs/popular-topics/intents.mdx index aa004c80..086db01b 100644 --- a/docs/popular-topics/intents.mdx +++ b/docs/popular-topics/intents.mdx @@ -20,25 +20,21 @@ Remember that [Privileged Intents](#what-are-privileged-intents) require you to + ```python + import discord -```python -import discord - -bot = discord.Bot(intents=discord.Intents.all()) -``` - + bot = discord.Bot(intents=discord.Intents.all()) + ``` - - -You can view a list of intents and the events they subscribe to [here](https://docs.pycord.dev/en/stable/api/data_classes.html#discord.Intents). - -```python title="Enabling Intents" -import discord + + You can view a list of intents and the events they subscribe to [here](https://docs.pycord.dev/en/stable/api/data_classes.html#discord.Intents). -bot = discord.Bot(intents=discord.intents.members(bans=True, guilds=True)) -``` + ```python title="Enabling Intents" + import discord + bot = discord.Bot(intents=discord.intents.members(bans=True, guilds=True)) + ``` @@ -56,7 +52,7 @@ Not enabling these intents doesn't mean you won't be able to ban users, but you :::info Related Topics -- [Sharding Bots](sharding) -- [Rules and Common Practices](../Getting-Started/rules-and-common-practices) +* [Sharding Bots](sharding) +* [Rules and Common Practices](../Getting-Started/rules-and-common-practices) ::: diff --git a/docs/popular-topics/sharding.mdx b/docs/popular-topics/sharding.mdx index b9af0fa0..5b5ce18f 100644 --- a/docs/popular-topics/sharding.mdx +++ b/docs/popular-topics/sharding.mdx @@ -16,9 +16,9 @@ Sharding is used only for large bots and takes up additional resources for manag Pycord automatically shards your bot, so the only thing you need to do is use an `AutoShardedClient` or `AutoShardedBot` class instead of a plain `Client` or `Bot` class. Pretty cool, right? -Just because you _can_ shard your bot doesn't mean you _should_. While Pycord makes it easy to shard +Just because you *can* shard your bot doesn't mean you *should*. While Pycord makes it easy to shard your bot, it isn't necessary to shard unless your bot is large. Sharding a small bot isn't -just useless, but _harmful_, as it uses extra resources and may slow down your bot. Discord +just useless, but *harmful*, as it uses extra resources and may slow down your bot. Discord themselves will let you know when your bot needs sharding, so you won't need to worry about this until they contact you. ## How Do I Shard in Pycord? @@ -38,11 +38,11 @@ just add the `shards` parameter, along with the number of shards you want. Sharding is very necessary for big bots. While your bot grows, it gets harder for your bot to control how many guilds it is in and what parts of your code should do what. This is exactly what sharding handles, it makes all of this easier for your bot. Remember, though, only shard your bot once it's -big enough, and that's at _least_ 1,000 guilds. +big enough, and that's at *least* 1,000 guilds. :::info Related Topics -- [Hosting your Bot](../Getting-Started/hosting-your-bot) -- [Rules and Common Practices](../Getting-Started/rules-and-common-practices) +* [Hosting your Bot](../Getting-Started/hosting-your-bot) +* [Rules and Common Practices](../Getting-Started/rules-and-common-practices) ::: diff --git a/docs/popular-topics/subclassing-bots.mdx b/docs/popular-topics/subclassing-bots.mdx index e6e34c39..56b2d643 100644 --- a/docs/popular-topics/subclassing-bots.mdx +++ b/docs/popular-topics/subclassing-bots.mdx @@ -9,8 +9,8 @@ Subclassing is another popular way of creating Discord Bots. Here, you create a Subclassing is an intermediate python concept, so we recommend you learn about it before continuing. Some good resources are: -- [W3Schools's Guide to Python Classes & Objects](https://www.w3schools.com/python/python_classes.asp) -- [W3Schools's Guide to Python Inheritance](https://www.w3schools.com/python/python_inheritance.asp) +* [W3Schools's Guide to Python Classes & Objects](https://www.w3schools.com/python/python_classes.asp) +* [W3Schools's Guide to Python Inheritance](https://www.w3schools.com/python/python_inheritance.asp) ## Why Subclassing? @@ -86,9 +86,11 @@ class MyBot(discord.Bot): # subclass discord.Bot print(self.user.id) print('------') ``` + ```python title="./src/__init__.py" from .bot import MyBot # import the MyBot class from the bot.py file ``` + ```python title="./main.py" from src import MyBot # import MyBot from /src @@ -107,7 +109,7 @@ So, should you subclass? There are no limitations you face if you decide to subc :::info Related Topics -- [Making a Help Command](../Extensions/Commands/help-command) -- [Rules and Common Practices](../Getting-Started/rules-and-common-practices) +* [Making a Help Command](../Extensions/Commands/help-command) +* [Rules and Common Practices](../Getting-Started/rules-and-common-practices) ::: diff --git a/docs/popular-topics/threads.mdx b/docs/popular-topics/threads.mdx index b96f6957..32640aec 100644 --- a/docs/popular-topics/threads.mdx +++ b/docs/popular-topics/threads.mdx @@ -55,17 +55,17 @@ await thread.delete() **Parameters** -- `name` (str) – The new name of the thread +* `name` (str) – The new name of the thread -- `archived` (bool) – Whether to archive the thread or not. +* `archived` (bool) – Whether to archive the thread or not. -- `locked` (bool) – Whether to lock the thread or not. +* `locked` (bool) – Whether to lock the thread or not. -- `invitable` (bool) – Whether non-moderators can add other non-moderators to this thread. Only available for private threads. +* `invitable` (bool) – Whether non-moderators can add other non-moderators to this thread. Only available for private threads. -- `auto_archive_duration` (int) – The new duration in minutes before a thread gets automatically archived for inactivity. Must be one of 60, 1440, 4320, or 10080. +* `auto_archive_duration` (int) – The new duration in minutes before a thread gets automatically archived for inactivity. Must be one of 60, 1440, 4320, or 10080. -- `slowmode_delay` (int) – Specifies the slow-mode rate limit for users in the thread, in seconds. A value of 0 disables slow-mode. The maximum value possible is 21600. +* `slowmode_delay` (int) – Specifies the slow-mode rate limit for users in the thread, in seconds. A value of 0 disables slow-mode. The maximum value possible is 21600. ```python title="Editing a Thread" thread = bot.get_channel(id) @@ -93,13 +93,15 @@ raised an exception: HTTPException: 400 Bad Request (error code: 10008): Unknown There could be multiple reasons, some of them being: -- The message does not exist -- The message already has a thread -- The message is in channel x, you are trying to start a thread in channel y. -- The message was deleted. +* The message does not exist +* The message already has a thread +* The message is in channel x, you are trying to start a thread in channel y. +* The message was deleted. :::info Related Topics -<>{/* I can't think of any related topics for this at the moment. */} +<> + {/* I can't think of any related topics for this at the moment. */} + ::: diff --git a/docs/voice/index.mdx b/docs/voice/index.mdx index f56ca692..4dc7c926 100644 --- a/docs/voice/index.mdx +++ b/docs/voice/index.mdx @@ -1,24 +1,24 @@ ---- -title: Voice ---- - -Welcome to the guide for voice features in Pycord. - +--- +title: Voice +--- + +Welcome to the guide for voice features in Pycord. + :::caution This guide requires previous experience with Pycord and Python. -::: - -## Requirements - +::: + +## Requirements + The only requirement which is required for voice features is [`PyNaCl`](https://pypi.org/project/PyNaCl/). -The following features are optional: - +The following features are optional: + :::tip Opus is also a required library, but this comes with Pycord. Some hosts may not come with it, though, so remember to always check if required dependencies are installed. -::: - -- [`FFmpeg`](https://ffmpeg.org) - used for sending/receiving files other than `.pcm` and `.wav` -- [`Pycord.Wavelink`](https://github.com/Pycord-Development/Pycord.Wavelink), -[`Lavalink.py`](https://github.com/Devoxin/Lavalink.py), -[`Wavelink`](https://github.com/PythonistaGuild/Wavelink) or any other Python LavaLink library for music playback. +::: + +* [`FFmpeg`](https://ffmpeg.org) - used for sending/receiving files other than `.pcm` and `.wav` +* [`Pycord.Wavelink`](https://github.com/Pycord-Development/Pycord.Wavelink), + [`Lavalink.py`](https://github.com/Devoxin/Lavalink.py), + [`Wavelink`](https://github.com/PythonistaGuild/Wavelink) or any other Python LavaLink library for music playback. diff --git a/docs/voice/playing.mdx b/docs/voice/playing.mdx index 55e97bb6..7800b4b2 100644 --- a/docs/voice/playing.mdx +++ b/docs/voice/playing.mdx @@ -26,6 +26,7 @@ For users that want extra examples, you can find some in Pycord's [GitHub repository](https://github.com/Pycord-Development/pycord/blob/master/examples/). ## Starting out + First you need to run a [Lavalink Server](https://github.com/freyacodes/Lavalink) to connect with. There a multiple documentations to do this, so we are not covering that here. @@ -62,8 +63,8 @@ async def connect_nodes(): Now you are finished making your node! Next, you will want to: -1. Making a play command -2. Adding connect events +1. Making a play command +2. Adding connect events ### Making a play command @@ -108,6 +109,7 @@ async def play(ctx, search: str): play
+ Now playing: Never Gonna Give You Up @@ -143,6 +145,6 @@ it easy to make complex bots so that you can get even the most advanced of ideas :::info Related Topics -- [Rules and Common Practices](../getting-started/rules-and-common-practices) +* [Rules and Common Practices](../getting-started/rules-and-common-practices) ::: diff --git a/docs/voice/receiving.mdx b/docs/voice/receiving.mdx index bb0360d0..5c18a7cb 100644 --- a/docs/voice/receiving.mdx +++ b/docs/voice/receiving.mdx @@ -61,6 +61,7 @@ async def record(ctx): # If you're using commands.Bot, this will also work. record + Started recording! @@ -69,8 +70,8 @@ async def record(ctx): # If you're using commands.Bot, this will also work. Now you are finished making your command for voice receiving! Next, you will want to: -1. Make your finished callback -2. Make a stop command +1. Make your finished callback +2. Make a stop command ### Making a Callback @@ -91,7 +92,10 @@ async def once_done(sink: discord.sinks, channel: discord.TextChannel, *args): finished recording audio for:{" "} - {defaultOptions.profiles.bob.author} + + + {defaultOptions.profiles.bob.author} + @@ -125,6 +129,6 @@ it easy to make complex bots so that you can get even the most advanced of ideas :::info Related Topics -- [Rules and Common Practices](../getting-started/rules-and-common-practices) +* [Rules and Common Practices](../getting-started/rules-and-common-practices) ::: diff --git a/docusaurus.config.js b/docusaurus.config.js index 5663b361..64651c9d 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -1,7 +1,9 @@ // @ts-check // Note: type annotations allow type checking and IDEs autocompletion +// @ts-ignore const lightCodeTheme = require("prism-react-renderer").themes.vsLight; +// @ts-ignore const darkCodeTheme = require("prism-react-renderer").themes.vsDark; const DefaultLocale = 'en'; @@ -25,6 +27,7 @@ const config = { "classic", { docs: { + // @ts-ignore editUrl: ({locale, versionDocsDirPath, docPath}) => { // Link to Crowdin for French docs if (locale !== DefaultLocale) { diff --git a/i18n/de/docusaurus-plugin-content-pagesindex.tsx b/i18n/de/docusaurus-plugin-content-pagesindex.tsx index 84df3a9c..6ca77bb2 100644 --- a/i18n/de/docusaurus-plugin-content-pagesindex.tsx +++ b/i18n/de/docusaurus-plugin-content-pagesindex.tsx @@ -1,5 +1,5 @@ import React from "react"; -import DefaultLayout from "../layouts/DefaultLayout"; +import DefaultLayout from "@site/src/layouts/DefaultLayout"; import PYCHero from "@site/src/components/PYCHero"; import PYCButton from "@site/src/components/PYCButton"; diff --git a/i18n/es/docusaurus-plugin-content-pagesindex.tsx b/i18n/es/docusaurus-plugin-content-pagesindex.tsx index 84df3a9c..6ca77bb2 100644 --- a/i18n/es/docusaurus-plugin-content-pagesindex.tsx +++ b/i18n/es/docusaurus-plugin-content-pagesindex.tsx @@ -1,5 +1,5 @@ import React from "react"; -import DefaultLayout from "../layouts/DefaultLayout"; +import DefaultLayout from "@site/src/layouts/DefaultLayout"; import PYCHero from "@site/src/components/PYCHero"; import PYCButton from "@site/src/components/PYCButton"; diff --git a/i18n/fr/docusaurus-plugin-content-pagesindex.tsx b/i18n/fr/docusaurus-plugin-content-pagesindex.tsx index 84df3a9c..6ca77bb2 100644 --- a/i18n/fr/docusaurus-plugin-content-pagesindex.tsx +++ b/i18n/fr/docusaurus-plugin-content-pagesindex.tsx @@ -1,5 +1,5 @@ import React from "react"; -import DefaultLayout from "../layouts/DefaultLayout"; +import DefaultLayout from "@site/src/layouts/DefaultLayout"; import PYCHero from "@site/src/components/PYCHero"; import PYCButton from "@site/src/components/PYCButton"; diff --git a/i18n/hi/docusaurus-plugin-content-pagesindex.tsx b/i18n/hi/docusaurus-plugin-content-pagesindex.tsx index 84df3a9c..6ca77bb2 100644 --- a/i18n/hi/docusaurus-plugin-content-pagesindex.tsx +++ b/i18n/hi/docusaurus-plugin-content-pagesindex.tsx @@ -1,5 +1,5 @@ import React from "react"; -import DefaultLayout from "../layouts/DefaultLayout"; +import DefaultLayout from "@site/src/layouts/DefaultLayout"; import PYCHero from "@site/src/components/PYCHero"; import PYCButton from "@site/src/components/PYCButton"; diff --git a/i18n/it/docusaurus-plugin-content-pagesindex.tsx b/i18n/it/docusaurus-plugin-content-pagesindex.tsx index 84df3a9c..6ca77bb2 100644 --- a/i18n/it/docusaurus-plugin-content-pagesindex.tsx +++ b/i18n/it/docusaurus-plugin-content-pagesindex.tsx @@ -1,5 +1,5 @@ import React from "react"; -import DefaultLayout from "../layouts/DefaultLayout"; +import DefaultLayout from "@site/src/layouts/DefaultLayout"; import PYCHero from "@site/src/components/PYCHero"; import PYCButton from "@site/src/components/PYCButton"; diff --git a/i18n/ja/docusaurus-plugin-content-pagesindex.tsx b/i18n/ja/docusaurus-plugin-content-pagesindex.tsx index 84df3a9c..6ca77bb2 100644 --- a/i18n/ja/docusaurus-plugin-content-pagesindex.tsx +++ b/i18n/ja/docusaurus-plugin-content-pagesindex.tsx @@ -1,5 +1,5 @@ import React from "react"; -import DefaultLayout from "../layouts/DefaultLayout"; +import DefaultLayout from "@site/src/layouts/DefaultLayout"; import PYCHero from "@site/src/components/PYCHero"; import PYCButton from "@site/src/components/PYCButton"; diff --git a/i18n/ko/docusaurus-plugin-content-pagesindex.tsx b/i18n/ko/docusaurus-plugin-content-pagesindex.tsx index 84df3a9c..6ca77bb2 100644 --- a/i18n/ko/docusaurus-plugin-content-pagesindex.tsx +++ b/i18n/ko/docusaurus-plugin-content-pagesindex.tsx @@ -1,5 +1,5 @@ import React from "react"; -import DefaultLayout from "../layouts/DefaultLayout"; +import DefaultLayout from "@site/src/layouts/DefaultLayout"; import PYCHero from "@site/src/components/PYCHero"; import PYCButton from "@site/src/components/PYCButton"; diff --git a/i18n/pt/docusaurus-plugin-content-pagesindex.tsx b/i18n/pt/docusaurus-plugin-content-pagesindex.tsx index 84df3a9c..6ca77bb2 100644 --- a/i18n/pt/docusaurus-plugin-content-pagesindex.tsx +++ b/i18n/pt/docusaurus-plugin-content-pagesindex.tsx @@ -1,5 +1,5 @@ import React from "react"; -import DefaultLayout from "../layouts/DefaultLayout"; +import DefaultLayout from "@site/src/layouts/DefaultLayout"; import PYCHero from "@site/src/components/PYCHero"; import PYCButton from "@site/src/components/PYCButton"; diff --git a/i18n/ru/docusaurus-plugin-content-pagesindex.tsx b/i18n/ru/docusaurus-plugin-content-pagesindex.tsx index 84df3a9c..6ca77bb2 100644 --- a/i18n/ru/docusaurus-plugin-content-pagesindex.tsx +++ b/i18n/ru/docusaurus-plugin-content-pagesindex.tsx @@ -1,5 +1,5 @@ import React from "react"; -import DefaultLayout from "../layouts/DefaultLayout"; +import DefaultLayout from "@site/src/layouts/DefaultLayout"; import PYCHero from "@site/src/components/PYCHero"; import PYCButton from "@site/src/components/PYCButton"; diff --git a/i18n/zh/docusaurus-plugin-content-pagesindex.tsx b/i18n/zh/docusaurus-plugin-content-pagesindex.tsx index 84df3a9c..6ca77bb2 100644 --- a/i18n/zh/docusaurus-plugin-content-pagesindex.tsx +++ b/i18n/zh/docusaurus-plugin-content-pagesindex.tsx @@ -1,5 +1,5 @@ import React from "react"; -import DefaultLayout from "../layouts/DefaultLayout"; +import DefaultLayout from "@site/src/layouts/DefaultLayout"; import PYCHero from "@site/src/components/PYCHero"; import PYCButton from "@site/src/components/PYCButton"; diff --git a/package.json b/package.json index facce394..c384ede0 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,6 @@ "@easyops-cn/docusaurus-search-local": "^0.36.0", "@matteusan/sentro": "1.1.0", "@mdx-js/react": "1.6.22", - "@types/react": "17.0.0", "babel-plugin-module-resolver": "5.0.2", "clsx": "2.1.1", "discord-message-components": "https://gitpkg.now.sh/Pycord-Development/discord-message-components?aa468ada9b2b52986ae0aee4051660713c1e9095&scripts.postinstall=yarn%20install%20--ignore-scripts%20%26%26%20node%20node_modules%2Fesbuild%2Finstall.js%20%26%26yarn%20build%3Amarkdown%20%26%26%20yarn%20build%3Acore%20%26%26%20yarn%20build%3Areact%20%26%26", @@ -57,12 +56,14 @@ "react-twemoji": "^0.6.0", "sass": "1.77.8", "search-insights": ">=1 <3", - "webpack": "^5.93.0", + "webpack": "^5.94.0", "yarn": "^1.22.22" }, "devDependencies": { "@docusaurus/module-type-aliases": "^2.4.3", "@tsconfig/docusaurus": "2.0.3", + "@types/react": "17.0.0", + "@types/react-twemoji": "0.4.3", "micromark-extension-mdx-md": "^2.0.0", "remark-cli": "^12.0.1", "remark-comment": "^1.0.0", diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 5bab1be7..6ca77bb2 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,37 +1,37 @@ -import React from "react"; -import DefaultLayout from "../layouts/DefaultLayout"; -import PYCHero from "@site/src/components/PYCHero"; -import PYCButton from "@site/src/components/PYCButton"; - -export default function Home(): JSX.Element { - return ( - - -
- Imagine a place where you can learn how to create an awesome Discord - bot, equip it with Pycord, and have it running in less than a minute. - Imagine a place where you can learn everything about Pycord. Imagine a - guide. A Pycord Guide! -

- Whether you are a newbie or an experienced developer, you will find - everything you need to know about Pycord here. This guide will teach - you: -
    -
  • How to get a brand new bot running from scratch;
  • -
  • How to create Interactions, Context Menus and Commands;
  • -
  • In-depth concepts such as Embeds, Reactions, Help Commands, Paginators, etc;
  • -
  • Popular Topics such as working with Databases, Sharding, etc;
  • -
  • Ways to handle and manage common errors and best practices for bots;
  • -
  • And Much More!
  • -
-
-
- ); -} +import React from "react"; +import DefaultLayout from "@site/src/layouts/DefaultLayout"; +import PYCHero from "@site/src/components/PYCHero"; +import PYCButton from "@site/src/components/PYCButton"; + +export default function Home(): JSX.Element { + return ( + + +
+ Imagine a place where you can learn how to create an awesome Discord + bot, equip it with Pycord, and have it running in less than a minute. + Imagine a place where you can learn everything about Pycord. Imagine a + guide. A Pycord Guide! +

+ Whether you are a newbie or an experienced developer, you will find + everything you need to know about Pycord here. This guide will teach + you: +
    +
  • How to get a brand new bot running from scratch;
  • +
  • How to create Interactions, Context Menus and Commands;
  • +
  • In-depth concepts such as Embeds, Reactions, Help Commands, Paginators, etc;
  • +
  • Popular Topics such as working with Databases, Sharding, etc;
  • +
  • Ways to handle and manage common errors and best practices for bots;
  • +
  • And Much More!
  • +
+
+
+ ); +} diff --git a/tsconfig.json b/tsconfig.json index 8c152f25..1be35802 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,8 +1,16 @@ { "extends": "@tsconfig/docusaurus/tsconfig.json", "compilerOptions": { + "target": "esnext", + "lib": ["dom", "dom.iterable", "esnext"], + "esModuleInterop": true, + "allowJs": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, "baseUrl": ".", "forceConsistentCasingInFileNames": true, + "noImplicitAny": false, "paths": { "@site/*": ["./*"], "react": ["./node_modules/@types/react"] diff --git a/yarn.lock b/yarn.lock index c868a8b4..633f8c47 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2445,22 +2445,6 @@ dependencies: "@types/ms" "*" -"@types/eslint-scope@^3.7.3": - version "3.7.3" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.3.tgz#125b88504b61e3c8bc6f870882003253005c3224" - integrity sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" - -"@types/eslint@*": - version "8.4.3" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.3.tgz#5c92815a3838b1985c90034cd85f26f59d9d0ece" - integrity sha512-YP1S7YJRMPs+7KZKDb9G63n8YejIwW9BALq7a5j2+H4yl6iOv9CB29edho+cuFRrvmJbbaH2yiVChKLJVysDGw== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" - "@types/estree-jsx@^1.0.0": version "1.0.5" resolved "https://registry.yarnpkg.com/@types/estree-jsx/-/estree-jsx-1.0.5.tgz#858a88ea20f34fe65111f005a689fa1ebf70dc18" @@ -2468,12 +2452,7 @@ dependencies: "@types/estree" "*" -"@types/estree@*", "@types/estree@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" - integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== - -"@types/estree@^1.0.5": +"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== @@ -2552,7 +2531,7 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.11" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== @@ -2678,6 +2657,13 @@ "@types/history" "^4.7.11" "@types/react" "*" +"@types/react-twemoji@0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@types/react-twemoji/-/react-twemoji-0.4.3.tgz#83542b47ffcee8c872b669a05e74a5ef7876e497" + integrity sha512-VzWkjmO8yJ31JSWgQhe0LCLU3FxcurTOklECm9p8v1xI/WfUBOGbSrqPjQPL46LE4oOqfrYIQ+0LM/8I6A8EDQ== + dependencies: + "@types/react" "*" + "@types/react@*", "@types/react@17.0.2": version "17.0.2" resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.2.tgz#3de24c4efef902dd9795a49c75f760cbe4f7a5a8" @@ -2931,12 +2917,7 @@ acorn-walk@^8.0.0: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== -acorn@^8.0.0, acorn@^8.0.4, acorn@^8.5.0, acorn@^8.7.1: - version "8.8.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" - integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== - -acorn@^8.8.2: +acorn@^8.0.0, acorn@^8.0.4, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.2: version "8.12.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== @@ -3233,10 +3214,10 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -body-parser@1.20.2: - version "1.20.2" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" - integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== +body-parser@1.20.3: + version "1.20.3" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" + integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g== dependencies: bytes "3.1.2" content-type "~1.0.5" @@ -3246,7 +3227,7 @@ body-parser@1.20.2: http-errors "2.0.0" iconv-lite "0.4.24" on-finished "2.4.1" - qs "6.11.0" + qs "6.13.0" raw-body "2.5.2" type-is "~1.6.18" unpipe "1.0.0" @@ -3309,25 +3290,14 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" -braces@^3.0.2, braces@~3.0.2: +braces@^3.0.3, braces@~3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== dependencies: fill-range "^7.1.1" -browserslist@^4.0.0, browserslist@^4.18.1: - version "4.20.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.4.tgz#98096c9042af689ee1e0271333dbc564b8ce4477" - integrity sha512-ok1d+1WpnU24XYN7oC3QWgTyMhY/avPJ/r9T00xxvUOIparA/gc+UPUMaod3i+G6s+nI2nUb9xZ5k794uIwShw== - dependencies: - caniuse-lite "^1.0.30001349" - electron-to-chromium "^1.4.147" - escalade "^3.1.1" - node-releases "^2.0.5" - picocolors "^1.0.0" - -browserslist@^4.21.10, browserslist@^4.21.4, browserslist@^4.23.1, browserslist@^4.23.3: +browserslist@^4.0.0, browserslist@^4.18.1, browserslist@^4.21.10, browserslist@^4.21.4, browserslist@^4.23.1, browserslist@^4.23.3: version "4.23.3" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.3.tgz#debb029d3c93ebc97ffbc8d9cbb03403e227c800" integrity sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA== @@ -3378,6 +3348,17 @@ call-bind@^1.0.0: function-bind "^1.1.1" get-intrinsic "^1.0.2" +call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -3411,7 +3392,7 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001349, caniuse-lite@^1.0.30001646: +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001646: version "1.0.30001651" resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz" integrity sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg== @@ -3799,10 +3780,10 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== -cookie@0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" - integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== +cookie@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.1.tgz#2f73c42142d5d5cf71310a74fc4ae61670e5dbc9" + integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w== copy-text-to-clipboard@^3.0.1: version "3.2.0" @@ -4109,6 +4090,15 @@ defer-to-connect@^1.0.1: resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== +define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + define-lazy-prop@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" @@ -4327,11 +4317,6 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -electron-to-chromium@^1.4.147: - version "1.4.152" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.152.tgz#7dedbe8f3dc1c597088982a203f392e60f7ee90a" - integrity sha512-jk4Ju5SGZAQQJ1iI4Rgru7dDlvkQPLpNPWH9gIZmwCD4YteA5Bbk1xPcPDUf5jUYs3e1e80RXdi8XgKQZaigeg== - electron-to-chromium@^1.5.4: version "1.5.8" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.8.tgz#0a3225b305212f347be48f159a3c0a117d5e9801" @@ -4367,6 +4352,11 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== +encodeurl@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" + integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== + encoding-sniffer@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz#799569d66d443babe82af18c9f403498365ef1d5" @@ -4382,7 +4372,7 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" -enhanced-resolve@^5.17.0: +enhanced-resolve@^5.17.1: version "5.17.1" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz#67bfbbcc2f81d511be77d686a90267ef7f898a15" integrity sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg== @@ -4417,16 +4407,23 @@ error-ex@^1.3.1, error-ex@^1.3.2: dependencies: is-arrayish "^0.2.1" +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + es-module-lexer@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.2.1.tgz#ba303831f63e6a394983fde2f97ad77b22324527" integrity sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg== -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - escalade@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" @@ -4549,36 +4546,36 @@ execa@^5.0.0: strip-final-newline "^2.0.0" express@^4.17.3: - version "4.19.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" - integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== + version "4.21.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.21.1.tgz#9dae5dda832f16b4eec941a4e44aa89ec481b281" + integrity sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.20.2" + body-parser "1.20.3" content-disposition "0.5.4" content-type "~1.0.4" - cookie "0.6.0" + cookie "0.7.1" cookie-signature "1.0.6" debug "2.6.9" depd "2.0.0" - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" etag "~1.8.1" - finalhandler "1.2.0" + finalhandler "1.3.1" fresh "0.5.2" http-errors "2.0.0" - merge-descriptors "1.0.1" + merge-descriptors "1.0.3" methods "~1.1.2" on-finished "2.4.1" parseurl "~1.3.3" - path-to-regexp "0.1.7" + path-to-regexp "0.1.10" proxy-addr "~2.0.7" - qs "6.11.0" + qs "6.13.0" range-parser "~1.2.1" safe-buffer "5.2.1" - send "0.18.0" - serve-static "1.15.0" + send "0.19.0" + serve-static "1.16.2" setprototypeof "1.2.0" statuses "2.0.1" type-is "~1.6.18" @@ -4698,13 +4695,13 @@ fill-range@^7.1.1: dependencies: to-regex-range "^5.0.1" -finalhandler@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" - integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== +finalhandler@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.1.tgz#0c575f1d1d324ddd1da35ad7ece3df7d19088019" + integrity sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ== dependencies: debug "2.6.9" - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" on-finished "2.4.1" parseurl "~1.3.3" @@ -4885,6 +4882,17 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: has "^1.0.3" has-symbols "^1.0.3" +get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + get-own-enumerable-property-symbols@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" @@ -5018,6 +5026,13 @@ globby@^13.1.1: merge2 "^1.4.1" slash "^4.0.0" +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + got@^9.6.0: version "9.6.0" resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" @@ -5035,12 +5050,7 @@ got@^9.6.0: to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: - version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== - -graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11: +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -5084,6 +5094,18 @@ has-property-descriptors@^1.0.0: dependencies: get-intrinsic "^1.1.1" +has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + +has-proto@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== + has-symbols@^1.0.1, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" @@ -5099,7 +5121,7 @@ has@^1.0.3: resolved "https://registry.yarnpkg.com/has/-/has-1.0.4.tgz#2eb2860e000011dae4f1406a86fe80e530fb2ec6" integrity sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ== -hasown@^2.0.2: +hasown@^2.0.0, hasown@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== @@ -5316,9 +5338,9 @@ http-parser-js@>=0.5.1: integrity sha512-vDlkRPDJn93swjcjqMSaGSPABbIarsr1TLAui/gLDXzV5VsJNdXNzMYDyNBLQkjWQCJ1uizu8T2oDMhmGt0PRA== http-proxy-middleware@^2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" - integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== + version "2.0.7" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz#915f236d92ae98ef48278a95dedf17e991936ec6" + integrity sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA== dependencies: "@types/http-proxy" "^1.17.8" http-proxy "^1.18.1" @@ -6361,10 +6383,10 @@ memfs@^3.1.2, memfs@^3.4.3: dependencies: fs-monkey "1.0.3" -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== +merge-descriptors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5" + integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ== merge-stream@^2.0.0: version "2.0.0" @@ -6785,11 +6807,11 @@ micromark@^4.0.0: micromark-util-types "^2.0.0" micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== dependencies: - braces "^3.0.2" + braces "^3.0.3" picomatch "^2.3.1" mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": @@ -6992,11 +7014,6 @@ node-releases@^2.0.18: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== -node-releases@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.5.tgz#280ed5bc3eba0d96ce44897d8aee478bfb3d9666" - integrity sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q== - nopt@^7.2.1: version "7.2.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-7.2.1.tgz#1cac0eab9b8e97c9093338446eddd40b2c8ca1e7" @@ -7089,10 +7106,10 @@ object-assign@^4.1.0, object-assign@^4.1.1: resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= -object-inspect@^1.9.0: - version "1.12.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" - integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== +object-inspect@^1.13.1: + version "1.13.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff" + integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g== object-keys@^1.1.1: version "1.1.1" @@ -7381,10 +7398,10 @@ path-scurry@^1.11.1, path-scurry@^1.6.1: lru-cache "^10.2.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== +path-to-regexp@0.1.10: + version "0.1.10" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.10.tgz#67e9108c5c0551b9e5326064387de4763c4d5f8b" + integrity sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w== path-to-regexp@2.2.1: version "2.2.1" @@ -7868,12 +7885,12 @@ pure-color@^1.2.0: resolved "https://registry.yarnpkg.com/pure-color/-/pure-color-1.3.0.tgz#1fe064fb0ac851f0de61320a8bf796836422f33e" integrity sha512-QFADYnsVoBMw1srW7OVKEYjG+MbIa49s54w1MA1EDY6r2r/sTcKKYqRX1f4GYvnXP7eN/Pe9HFcX+hwzmrXRHA== -qs@6.11.0: - version "6.11.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" - integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== +qs@6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" + integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== dependencies: - side-channel "^1.0.4" + side-channel "^1.0.6" queue-microtask@^1.2.2: version "1.2.3" @@ -9005,10 +9022,10 @@ semver@^7.3.2, semver@^7.3.5, semver@^7.3.7: dependencies: lru-cache "^6.0.0" -send@0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" - integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== +send@0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8" + integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== dependencies: debug "2.6.9" depd "2.0.0" @@ -9065,15 +9082,27 @@ serve-index@^1.9.1: mime-types "~2.1.17" parseurl "~1.3.2" -serve-static@1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" - integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== +serve-static@1.16.2: + version "1.16.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.2.tgz#b6a5343da47f6bdd2673848bf45754941e803296" + integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw== dependencies: - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" parseurl "~1.3.3" - send "0.18.0" + send "0.19.0" + +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" setimmediate@^1.0.5: version "1.0.5" @@ -9133,14 +9162,15 @@ shelljs@^0.8.5: interpret "^1.0.0" rechoir "^0.6.2" -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== +side-channel@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" signal-exit@^3.0.2, signal-exit@^3.0.3: version "3.0.7" @@ -10284,12 +10314,11 @@ webpack-sources@^3.2.2, webpack-sources@^3.2.3: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@^5.73.0, webpack@^5.93.0: - version "5.93.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.93.0.tgz#2e89ec7035579bdfba9760d26c63ac5c3462a5e5" - integrity sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA== +webpack@^5.73.0, webpack@^5.94.0: + version "5.94.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.94.0.tgz#77a6089c716e7ab90c1c67574a28da518a20970f" + integrity sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg== dependencies: - "@types/eslint-scope" "^3.7.3" "@types/estree" "^1.0.5" "@webassemblyjs/ast" "^1.12.1" "@webassemblyjs/wasm-edit" "^1.12.1" @@ -10298,7 +10327,7 @@ webpack@^5.73.0, webpack@^5.93.0: acorn-import-attributes "^1.9.5" browserslist "^4.21.10" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.17.0" + enhanced-resolve "^5.17.1" es-module-lexer "^1.2.1" eslint-scope "5.1.1" events "^3.2.0"