Creating my first Discord bot and I'm running into an issue with the buttons and interactions. No matter what I do I only get an error which says 'This Interaction Failed'
The bot has tested perms to add roles, assign roles, delete roles, create/delete channels and send + read user messages. I saw a reddit post about doing something like this to fix the error
async def on_button_click(interaction):
your code
try:
interaction.respond()
except:
pass
but I can't figure out how to implement this or if I'm already doing this. I know it has to do with callbacks lol.
Here is the code. If more information is needed please let me know. I'm not sure how to log as well because my google cloud vm throws no errors.
buttons and view come from here
from discord.ui import Button, View
@bot.command()
async def invite(ctx, user: discord.User):
if ctx.author.id not in clan_data:
await ctx.send("You are not in any clan. Create a clan first.")
return
# Check if the author of the message is the clan creator
clan_creator_id = ctx.author.id
if clan_creator_id not in clan_data:
await ctx.send("Only the clan creator can invite users.")
return
clan_name, channel_id, role_id, member_list= clan_data[clan_creator_id]
embed = discord.Embed(
title=f"Invitation to {clan_name}",
description=f"You have been invited to {clan_name} by {ctx.author.name}",
color=discord.Color.blurple()
)
embed.set_thumbnail(url=ctx.guild.icon.url)
accept_button = Button(style=discord.ButtonStyle.green, label="Accept", custom_id="join")
reject_button = Button(style=discord.ButtonStyle.red, label="Reject", custom_id="reject")
action_row = View()
action_row.add_item(accept_button)
action_row.add_item(reject_button)
await user.send(embed=embed, view=action_row)
@bot.event
async def on_component(interaction):
if interaction.custom_id == "join":
await interaction.response.send_message("Accepted.", ephemeral=True)
await handle_accept(interaction)
elif interaction.custom_id == "reject":
await interaction.response.send_message("Invite rejected.", ephemeral=True)
async def handle_accept(interaction):
user = interaction.user
guild = bot.get_guild(1159153096191123517) #REPLACE WITH YOUR SERVER ID
clan_creator_id = None
for key, value in clan_data.items():
if value[2] == interaction.message.embeds[0].title:
clan_creator_id = key
break
if clan_creator_id is not None:
role_id = clan_data[clan_creator_id][2]
role = guild.get_role(role_id)
if role is not None:
clan_data[clan_creator_id][3].append(user.id)
await user.add_roles(role)
await interaction.response.send_message("You have accepted the invitation.", ephemeral=True)
else:
await interaction.response.send_message("Role not found!", ephemeral=True)
else:
await interaction.response.send_message("Invalid Invitation!", ephemeral=True)
Main thing I have tried is this:
async def on_button_click(interaction):
your code
try:
interaction.respond()
except:
pass
Here is a code for a simple button interaction:
class MyView(discord.ui.View):
def __init__(self):
super().__init__(timeout=None)
@discord.ui.button(label="Test",style=discord.ButtonStyle.green, custom_id="my_custom_button")
async def testbutton(self,interaction:discord.Interaction,button:discord.ui.Button):
await interaction.response.send_message("Testing...")
@bot.tree.command(name='testbutton')
async def testbutton(interaction:discord.Interaction):
await interaction.response.send_message(view=MyView())
Explanation: (You can put the code in the main file it is not a cog.)
You create a class for the button. Inside that class you directly respond to the button click by mentioning the button itself. With the command you only send the button.
For this button to work after the bot restarts in your on_ready event add this line: bot.add_view(MyView())
Of course if you rename the class rename the MyView part inside the line.