The Python Discord library space continues to be unstable, so in order to keep up with new features added to Discord, we are once again migrating libraries. This time, from Disnake back to Discord.py.
This migration has mostly been done for you by migrating MerelyBot-Framework, but there are a handful of changes you should be aware of;
If information relating to a decorator is sent to Discord (command name, description, parameters, allowed contexts, etc), import app_command and rename the decorator.
- Be sure to import
app_commands
usingfrom discord import app_commands
The way command groups work is very different. In Discord.py, you need to explicitly identify command groups by creating an app_commands.Group
instance.
- Sub commands use the
@groupname.command
decorator instead. - You might also need to manually add the group as a command using
add_command
.
This means no calling commands internally with additional arguments
- For Merely Framework, this means calling
bot.cogs['Help'].help(cmd, ephemeral=True)
is no longer possible.- Our solution;
send_message(bot.cogs['Help].resolve_help(cmd), ephemeral=True)
- Our solution;
A plus-side of this pattern is all choices have a name and value.
Instead, use @app_commands.describe(**kwargs)
.
Instead, create component class variables directly
This means you must always have a full lifecycle for your views planned; if the View is meant to survive restarts, you need to use MerelyBot.config
and @commands.Cog.listener('on_ready')
to rehydrate it.
- Be considerate when using the on_ready event! Consider adding a
asyncio.sleep()
so not all on_ready events fire at the same time. - With discord.py v2.4, Dynamic Items have been added, which can help create views that survive restarts.
Interaction
is before Button
now
Refer to this Rapptz/discord.py#7823 (comment)
In disnake, you could determine the structure and context of an interaction based on the subclass (ApplicationCommandInteraction
, ModalInteraction
, etc). In Discord.py, Interaction
is used in all cases and no subclasses exist.
- Use
Interaction.type
to determine the Interaction type instead.
Data must be retreived manually, or just talk to the existing components as their state changes
inter.data.values
is nowinter.data['values']
inter.data.custom_id
is nowinter.data['custom_id']
inter.data.text_values
is nowinter.data['components'][0]['components']
Note that this is an oversimplification. The documentation doesn't describe these structures so you will need to either rely on Intellisense, or print(inter.data) in a few contexts to learn how it is structured.
Instead of self.command(inter)
, you need to call self.command.callback(self, inter)
Instead we rely upon the low-level on_interaction
event, or use Object callbacks
on_button_click
,on_select
no longer exist
on__slash_command_completion
becomeson_app_command_completion
Embed.set_image()
is now positional onlyMessage.edit()
is now positional only
- Danny has given us a list of types and will not allow us to stray away
autocomplete
functions must be asyncload_extension
must be async, alongside Cog setup functions and bot.add_cog
These handy methods automatically use fetch or get depending on cache, you will need to do this manually now
Provide a discord.Object(id)
instead