Can't add buttons to slash commands for my discord bot

Question:

So I was trying to add buttons to slash commands using discord.py interactions and app_commands elements but when I try to run this code I get this error: error. I can’t find normal examples for discord.py implementations maybe somebody can help.

Code:

intents = discord.Intents.all()
client = discord.Client(intents=intents)
tree = app_commands.CommandTree(client)

@tree.command(name="hello", description="Sends a hello message with buttons", guild=croc)
async def hello(ctx):
    button1 = discord.Button(label="Hello", custom_id="hello")
    button2 = discord.Button(label="World", custom_id="world")
    action_row = discord.ActionRow(button1, button2)

    await ctx.response.send_message("Click a button!", components=[action_row])

@client.event
async def on_interaction(interaction):
    if interaction.type == discord.InteractionType.component:
        custom_id = interaction.data["custom_id"]

        if custom_id == "hello":
            await interaction.response.send_message("You clicked the Hello button!", ephemeral=True)
        elif custom_id == "world":
            await interaction.response.send_message("You clicked the World button!", ephemeral=True)

@client.event
async def on_ready():
    await tree.sync(guild=croc)
    print("Loged as ", client.user)

Maybe there is problem with library version but i don’t know.

Asked By: ICHi

||

Answers:

From the docs,

The user constructible and usable type to create a button is discord.ui.Button not this one.

This is not how you make a button. Making a view class:

class ButtonView(discord.ui.View):
    def __init__(self):
        super().__init__()

Now, after this, there are two ways to add your buttons.

class ButtonView(discord.ui.View):
    def __init__(self):
        super().__init__()
    
    @discord.ui.button(label="Hello")
    async def buttoncallback(self, interaction: discord.Interaction, button: button: discord.ui.Button):
        pass

Or you can dynamically add them

class ButtonView(discord.ui.View):
    def __init__(self):
        super().__init__()
        self.add_buttons() # Remember to add this line to call the add_buttons() function
    def add_buttons(self):
        mybutton = discord.ui.Button(label="Hello")
        self.add_item(mybutton)

        async def buttoncallback(interaction: discord.Interaction):
            pass

        mybutton.callback = buttoncallback

To call your button, add your ButtonView to the view parameter when sending your message.

@tree.command(name="hello", description="Sends a hello message with buttons", guild=croc)
async def hello(interaction: discord.Interaction):
    view = ButtonView()
    await interaction.response.send_message("Click a button!", view=view)

Note: As to not confuse yourself, change ctx to interaction. discord.ext.commands.Context is completely different from discord.Interaction. The only reason ctx works is because your code thinks that it is interaction and you did use it as if it was interaction

References: discord.InteractionResponse.send_message, discord.ui.Button, discord.ui.View

Answered By: Raymus
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.