|
| 1 | +How to use components |
| 2 | +===================== |
| 3 | + |
| 4 | + |
| 5 | +So you've seen the new fancy buttons and want to give them a try, but dont know where to start. No problem! |
| 6 | + |
| 7 | +First lets cover the basics. Discord messages can have *components*, such as buttons, dropdowns etc. These components sit in whats called an "action row". An action row can hold 5 components at a time. Your message can have 5 action rows, so thats a total of 25 components! |
| 8 | + |
| 9 | +Sending some components |
| 10 | +_______________________ |
| 11 | + |
| 12 | +First we need to create some buttons, lets put them in a list for now. We'll use :meth:`create_button() <discord_slash.utils.manage_components>` to create a green button |
| 13 | + |
| 14 | +.. code-block:: python |
| 15 | +
|
| 16 | + from discord_slash.utils import manage_components |
| 17 | + from discord_slash.model import ButtonStyle |
| 18 | +
|
| 19 | + buttons = [ |
| 20 | + manage_components.create_button( |
| 21 | + style=ButtonStyle.green, |
| 22 | + label="A Green Button" |
| 23 | + ), |
| 24 | + ] |
| 25 | +
|
| 26 | +So we have a button, but where do we use it. Let's create an action row with :func:`create_actionrow() <discord_slash.utils.manage_components>` and put our buttons in it |
| 27 | + |
| 28 | +.. code-block:: python |
| 29 | +
|
| 30 | + [...] |
| 31 | + action_row = manage_components.create_actionrow(*buttons) |
| 32 | +
|
| 33 | +
|
| 34 | +Fantastic, we now have an action row with a green button in it, now lets get it sent in discord |
| 35 | + |
| 36 | +.. code-block:: python |
| 37 | +
|
| 38 | + await ctx.send("My Message", components=[action_row]) |
| 39 | +
|
| 40 | +.. note:: This will work in both slash commands, and discord.py commands |
| 41 | + |
| 42 | +Now if you've followed along, you have a green button in discord! But theres a problem, whenever you click it you see that the ``interaction failed``. Why is that? |
| 43 | +Well, in Discord, clicking buttons and using slash commands are called ``interactions``, and Discord doesn't know if we've received them or not unless we tell Discord. So how do we do that? |
| 44 | + |
| 45 | +Responding to interactions |
| 46 | +__________________________ |
| 47 | + |
| 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`) |
| 49 | + |
| 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>`) |
| 52 | + |
| 53 | +.. code-block:: python |
| 54 | +
|
| 55 | + await ctx.send("My Message", components=[action_row]) |
| 56 | + # 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) |
| 58 | + await button_ctx.edit_origin(content="You pressed a button!") |
| 59 | +
|
| 60 | +.. 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 |
| 61 | + |
| 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`. |
| 63 | + |
| 64 | +.. code-block:: python |
| 65 | +
|
| 66 | + @bot.event |
| 67 | + async def on_component(ctx: ComponentContext): |
| 68 | + await button_ctx.edit_origin(content="You pressed a button!") |
| 69 | +
|
| 70 | +But [writer], I dont want to edit the message |
| 71 | +********************************************* |
| 72 | + |
| 73 | +Well lucky for you, you don't have to. You can either respond silently, with a thinking animation, or send a whole new message. Take a look here: :class:`ComponentContext <discord_slash.context.ComponentContext>` |
| 74 | + |
| 75 | +How do i know which button was pressed? |
| 76 | +_______________________________________ |
| 77 | + |
| 78 | +Each button gets a ``custom_id``, this is a unique identifier of which button is being pressed. You can specify what the ID is when you define your button, if you don't; a random one will be generated. When handling the event, simply check the custom_id, and handle accordingly. |
0 commit comments