Skip to content

Commit 31039ce

Browse files
Component callback docs, small fix (#217)
* Fixed PartialEmoji usage in create_button * Include component callbacks in docs, patch some things in component docs. * Apply suggestions from code review Co-authored-by: LordOfPolls <[email protected]> * Add subsections * Applied suggestions from reviews Co-authored-by: LordOfPolls <[email protected]>
1 parent 71758e6 commit 31039ce

File tree

2 files changed

+30
-5
lines changed

2 files changed

+30
-5
lines changed

discord_slash/utils/manage_components.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ def emoji_to_dict(emoji: typing.Union[discord.Emoji, discord.PartialEmoji, str])
8282
"""
8383
if isinstance(emoji, discord.Emoji):
8484
emoji = {"name": emoji.name, "id": emoji.id, "animated": emoji.animated}
85+
elif isinstance(emoji, discord.PartialEmoji):
86+
emoji = emoji.to_dict()
8587
elif isinstance(emoji, str):
8688
emoji = {"name": emoji, "id": None}
8789
return emoji if emoji else {}

docs/components.rst

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,28 +45,51 @@ Well, in Discord, clicking buttons and using slash commands are called ``interac
4545
Responding to interactions
4646
__________________________
4747

48-
When responding, you have 2 choices in how you handle interactions. You can either wait for them in the command itself, or listen for them in a global event handler (similar to :meth:`on_slash_command_error`)
48+
When responding, you have 3 choices in how you handle interactions. You can either wait for them in the command itself, or listen for them in a global event handler (similar to :func:`on_slash_command_error`), or register async function as component callback.
4949

50-
Lets go through the most common method first, responding in the event itself. We simply need to :meth:`wait_for` the event, just like you do for reactions. For this we're going to use :func:`wait_for_component() <discord_slash.utils.manage_components>`, and we're going to only wait for events from the action row we just .
51-
This method will return a :class:`ComponentContext <discord_slash.context.ComponentContext>` object that we can use to respond. For this example, we'll just edit the original message (:meth:`edit_origin() <discord_slash.context.ComponentContext.edit_origin>`)
50+
Wait_for
51+
********
52+
53+
Lets go through the most common method first, responding in the command itself. We simply need to :func:`wait_for` the event, just like you do for reactions. For this we're going to use :func:`wait_for_component() <discord_slash.utils.manage_components>`, and we're going to only wait for events from the action row we just sent.
54+
This method will return a :class:`ComponentContext <discord_slash.context.ComponentContext>` object that we can use to respond. For this example, we'll just edit the original message (:meth:`edit_origin() <discord_slash.context.ComponentContext.edit_origin>`, uses same logic as :func:`edit()`)
5255

5356
.. code-block:: python
5457
5558
await ctx.send("My Message", components=[action_row])
5659
# note: this will only catch one button press, if you want more, put this in a loop
57-
button_ctx: ComponentContext = await manage_components.wait_for_component(bot, action_row)
60+
button_ctx: ComponentContext = await manage_components.wait_for_component(bot, components=action_row)
5861
await button_ctx.edit_origin(content="You pressed a button!")
5962
6063
.. note:: It's worth being aware that if you handle the event in the command itself, it will not persist reboots. As such when you restart the bot, the interaction will fail
6164

62-
Next we'll go over the alternative, a global event handler. This works just the same as :meth:`on_slash_command_error` or `on_ready`.
65+
Global event handler
66+
********************
67+
68+
Next we'll go over the alternative, a global event handler. This works just the same as :func:`on_slash_command_error` or `on_ready`. But note that this code will be triggered on any components interaction.
6369

6470
.. code-block:: python
6571
6672
@bot.event
6773
async def on_component(ctx: ComponentContext):
74+
# you may want to filter or change behaviour based on custom_id or message
6875
await ctx.edit_origin(content="You pressed a button!")
6976
77+
Component callbacks
78+
********************
79+
80+
There is one more method - making a function that'll be component callback - triggered when components in specified messages or with specified custom_ids would be activated
81+
Let's register our callback function via decorator :meth:`component_callback() <discord_slash.client.SlashCommand.component_callback>`, in similar ways to slash commands.
82+
83+
.. code-block:: python
84+
85+
@slash.component_callback()
86+
async def hello(button_context: ComponentContext):
87+
await ctx.edit_origin(content="You pressed a button!")
88+
89+
In this example, :func:`hello` will be triggered when you receive interaction event from a component with a `custom_id` set to `"hello"`. Just like slash commands, The callback's `custom_id` defaults to the function name.
90+
You can also register such callbacks in cogs using :func:`cog_component() <discord_slash.cog_ext>`
91+
Additionally, component callbacks can be dynamically added, removed or edited - see :class:`SlashCommand <discord_slash.client.SlashCommand>`
92+
7093
But [writer], I dont want to edit the message
7194
*********************************************
7295

0 commit comments

Comments
 (0)