This seems to be a common "gotcha" with users new to the library. As such I have been asked to cover it a bit more here.
CommandTree.sync is how we make Discord aware of our command definitions. This means that we use an API request to send them a copy of what our commands look like and act like, so they can display it to your users in the client.
If you do not sync your tree, the commands will not show up, or update them if you make changes locally.
I cover some more items relating to this in the next file below. But for now let's cover the basics and what you can do here.
In my time as Helper, I see people syncing their CommandTree in the on_ready_event
or in the new setup_hook
entrypoint method.
I do not advise this personally, it can lead to footguns if you aren't prepared.
For examples, if you sync your tree before you load your extensions (which have your application commands), then you're effectively syncing an empty tree to Discord, which will wipe your commands.
If you sync your tree and then make changes, you rely on the autosync and forget to sync changes, resulting in errors and failing commands.
This is why it is strongly recommended to sync on demand with a command (ideally with a message command) and know when to do such things. I cover that later too.
I'll add more things when I can think of them.
@glass-ships Can do!
So I am a HUGE advocate for having absolutely ZERO autosync.
This means that all syncing should be done manually, by you, as needed.
I've seen people do their sync in
on_ready
, orsetup_hook
and I hate it, to be honest.You do NOT need to sync like this, since the ratelimit for this endpoint not lax and has a cap for daily usage when creating commands.
Updating them has a different ratelimit of which I am not familiar with.
Instead what I suggest is making a command to do this.
Now I can respect people wanna move to slash commmands fully and drop the message commands, that's okay. I still recommend some sort of manual trigger for syncing their CommandTree, like sommething listening in
on_message
for specific instructions in a locked dev channel, etc.I have an example command here:
Click to expand!
commands.Greedy
discord.Object
typing.Optional
andtyping.Literal
Works like:
!sync
-> global sync!sync ~
-> sync current guild!sync *
-> copies all global app commands to current guild and syncs!sync ^
-> clears all commands from the current guild target and syncs (removes guild commands)!sync id_1 id_2
-> syncs guilds with id 1 and 2So general protocol for syncing is whilst your commands are still being worked on, you want to just sync them to a test guild only, not globally. This avoids the super mean global sync ratelimit.
Once the commmands are ready for deployment globally, you can sync globally.
Discord.py provided utilities such as
ComandTree.copy_global_to
that can copy a globally defined application command to a guild logically, so you can have comands defined globally but during testing just copy it to a guild for syncing.You can retrofit this tool into the example commmand if you need to!