This Gist This gist explains why Auto Syncing Sucks and ways you can manually sync instead.
Slash commands are special commands that are registered by Discord instead. Unlike prefixed commands, which are handled internally by the library, libraries need to send the commands to Discord through the Discord API. In discord.py, this is done through a process called syncing.
Interally, discord.py represents commands as a tree, which may be helpful to visualize it as shown below:
{
None: [global, commands],
guild_one: [guild, one, commands],
guild_two: [guild, two, commands]
}
Credits to sgtlaggy
Slash commands are scoped to either global or guild-specific. Global means that the command is accessiable everywhere.
As quoted by Leo on the discord.py server:
Syncing your command tree automatically causes extra unnecessary requests to be made, this is because you only need to sync when commands are updated.
As syncing is a process requiring making requests to the Discord API, you only want to send requests when you need to. Discord heavily ratelimits their API, which if you did auto sync, would result in 429 errors, and if this behavoir is continued, then a Cloudflare 429 ban is applied. Moreover, you only need to sync if there are changes to the command name, description, options, locales, and permissions. Most of the time there are no changes to those, which is just a waste of an API request
This quote from ?tag ass
perfectly summarizes it.
What syncing does is send your commands to discord for one guild or globally. If you haven't changed your command's descriptions, added/removed commands, changed names, parameters, etc. you shouldn't sync, since you'd only be updating discord with the commands they already have without doing any changes, which is pointless and a waste of an API request to a limit with an already tight rate limit.
When people inject auto-syncing code (or library maintainers), they trade convenience and in return, get a lack of control. This lack of control over the syncing process adds a burden to how you deploy your commands, and ultimately you run into issues when you use this process.
The most notable example is the case of duplicate commands. This is caused by having global commands along with guild commands, thus causing "duplicates". (Usually caused by globally syncing guild commands). If you did auto-syncing, then you would be freaking out how to fix this and Googling it up, which lead to solutions that worsen the issue. Now what happens if you manually synced instead? The outcomes would be much different, as if you used Umbras Sync Command (USC), then all you would need to run is the following:
!sync ^
By running this simple prefixed command, you effectively solve the whole situtation. Point is, auto-syncing removes the finite control that manually syncing has.
There is a pretty sneaky loophole, and message intents does not affect
mention prefixes (the mention for the bot is used as the prefix).
This also works in DMs.
You could set the bot prefix to commands.when_mentioned
to acheive this.
The simple answer: no. See the following tag ?tag whensync
for more info.
- Basic
- Added/Removed a command
- Added/Removed autocomplete (decorator, transformer)
- Added/Removed an argument
- Added/Modified/Removed locale strings
- Converted the global/guild command to a guild/global command
- Modify
- Changed a command's...
- name (
name=
kwarg, function name) - description (
description=
kwarg, docstring)
- name (
- Changed an argument's...
- name (rename decorator, param name)
- choices (Literal, choices decorator, enum type)
- description (describe decorator, docstring)
- type (
arg: str
str is the type here)
- Changed a command's...
- Permissions
- Added/Modified permissions:
default_permissions
(decorator, kwarg)nsfw
(kwarg)
- Added/Modified contexts:
guild_only
(decorator, kwarg)
- Added/Modified permissions:
- Changed anything in the command/autcomplete function's body (after the
async def ():
part) - Added/Modified/Removed library side checks:
(@)app_commands.checks...
(@)commands...(.check)
@app_commands.checks.(dynamic_)cooldown(...)
This is the same for hybrid app commands