Discord.py bot: Button interaction not working as expected

Hey everyone! I’m having trouble with my Discord bot. I made it using discord.py. The bot is supposed to do something when a new member joins the server. It gives them a role and posts a message in an admin channel. The message has two buttons: one to approve and one to deny the new member.

Here’s what’s weird: when I click either button, I see ‘This Interaction failed’ in Discord. But my console doesn’t show any errors. I’m confused!

Here’s a simplified version of my code:

class ButtonView(discord.ui.View):
    @discord.ui.button(label='Yes', style=discord.ButtonStyle.green)
    async def confirm(self, interaction, button):
        await interaction.response.send_message('User approved!', ephemeral=True)

    @discord.ui.button(label='No', style=discord.ButtonStyle.red)
    async def cancel(self, interaction, button):
        await interaction.response.send_message('User denied!', ephemeral=True)

@bot.event
async def on_member_join(member):
    view = ButtonView()
    role = discord.utils.get(member.guild.roles, name='NewMember')
    admin_channel = member.guild.get_channel(123456789)  # Replace with actual channel ID
    
    if admin_channel:
        await member.add_roles(role)
        await admin_channel.send(f'{member} joined! Approve?', view=view)
    else:
        print('Admin channel not found!')

Any ideas why the buttons aren’t working? Thanks for your help!

Hey mate, had this issue too. check ur bot’s application commands. sometimes they don’t sync right and mess up interactions. try runnin bot.tree.sync() after defining commands. also, make sure ur using discord.py 2.0+. older versions don’t support buttons well. good luck!

I’ve run into this issue before, and it’s often due to a mismatch between the bot’s permissions and the interaction requirements. Make sure your bot has the ‘Use External Emojis’ and ‘Use Slash Commands’ permissions in the server settings. Also, check if you’ve enabled the correct intents when initializing your bot.

Another potential cause could be that the view is timing out before the interaction occurs. Try setting a longer timeout or using timeout=None in your ButtonView class initialization.

Lastly, ensure your bot’s token is correct and that you’re running the latest version of discord.py. Outdated libraries can sometimes cause unexpected behavior with newer Discord features.

I encountered a similar issue with button interactions in my Discord bot. The problem might be related to how you’re handling the view’s lifetime. In your current setup, the view object is created locally in the on_member_join event, which means it could be garbage collected before the interaction occurs.

To fix this, try storing your views in a persistent collection, like a dictionary. Here’s a rough idea of how you could modify your code:

class ButtonView(discord.ui.View):
    def __init__(self, bot, member):
        super().__init__(timeout=None)  # Make the view persistent
        self.bot = bot
        self.member = member

    @discord.ui.button(label='Yes', style=discord.ButtonStyle.green)
    async def confirm(self, interaction, button):
        # Your approval logic here
        await interaction.response.send_message(f'{self.member} approved!', ephemeral=True)
        del self.bot.pending_approvals[self.member.id]

    @discord.ui.button(label='No', style=discord.ButtonStyle.red)
    async def cancel(self, interaction, button):
        # Your denial logic here
        await interaction.response.send_message(f'{self.member} denied!', ephemeral=True)
        del self.bot.pending_approvals[self.member.id]

# In your bot setup
bot.pending_approvals = {}

@bot.event
async def on_member_join(member):
    view = ButtonView(bot, member)
    bot.pending_approvals[member.id] = view
    # Rest of your code...

This approach keeps the view objects alive as long as needed. Don’t forget to clean up the dictionary when interactions are handled or time out. Also, ensure your bot has the necessary intents enabled. Hope this helps!