Ошибка взаимодействия discord button

Чтобы не намешивать библиотеки, я все же предлагаю использовать py-cord:

import discord
from discord.ext import commands
from discord.ui import Button, View

bot = commands.Bot(command_prefix='!', intents=discord.Intents.all())

Тогда обработку нажатия кнопки можно будет реализовать вот так:

@bot.command()
async def test(ctx):
    await ctx.send('Hello World!', view=View(
        Button(custom_id='button1', label='WOW button!', style=discord.ButtonStyle.green)
        ))

    interaction = await bot.wait_for('interaction', check=lambda i: i.custom_id == 'button1')
    await interaction.response.edit_message(content='Button clicked!', view=None)

Или так, через установку отдельной функции в качестве свойства отклика кнопки:

@bot.command()
async def test(ctx):

    async def button_callback(interaction):
        await interaction.response.edit_message(content='Button clicked!', view=None)

    button = Button(custom_id='button1', label='WOW button!', style=discord.ButtonStyle.green)
    button.callback = button_callback

    await ctx.send('Hello World!', view=View(button))

введите сюда описание изображения

введите сюда описание изображения


Всю информацию я брал из документации. Если вам нужен был пример, то тоже не пойму как вы его не нашли, потому что я нашел идеальное видео сразу по запросу discord buttons: https://www.youtube.com/watch?v=kNUuYEWGOxA

The code does what is supposed to do, but after each button press it says «This interaction failed». Pressing the button edits the embed to change it to another. How would I get rid of that interaction failed message after pressing a button?

the issue: https://i.stack.imgur.com/i4dTd.png

code received from: https://github.com/elixss/YouTube/blob/main/source/buttons.py

Here is the code:

@bot.group(invoke_without_command=True)
async def help(ctx):

    # buttons
    one = Button(style=1, label="Commands", id="em1")
    two = Button(style=1, label="Depression", id="em2")
    three = Button(style=1, label="Moderator", id="em3")
    four = Button(style=1, label="Language", id="em4")

    # embeds
    em1 = Embed(title="Commands Plugin",color=0x5865F2)
    em2 = Embed(title="Depression Plugin", description="placeholder", color=0x5865F2)
    em3 = Embed(title="Moderator Plugin", description="placeholder", color=0x5865F2)
    em4 = Embed(title="Language Plugin", description="placeholder", color=0x5865F2)

    # main help embed
    help_embed = Embed(description="> **Help Module**nPress on any button to view the commands for that selected plugin.",
                      color=discord.Color.random())

    # buttons to embeds
    buttons = {
        "em1": em1,
        "em2": em2,
        "em3": em3,
        "em4": em4
    }

    msg = await ctx.send(embed=help_embed,
                         components=[[one, two, three, four]])
    while True:
        event = await bot.wait_for("button_click", timeout=60.0)

        if event.channel is not ctx.channel:
            return

        if event.channel == ctx.channel:
            response = buttons.get(event.component.id)
            await msg.edit(embed=response)

            if response is None:
                await event.channel.send("error, try again.")

I’m trying to make buttons with discord.py, everything is good and the buttons work well, but even though it gives the error message «This interaction failed»

async def dashboard():
    embed=discord.Embed(title="Tile", description="Desc", color=0x00ff00)
    embed.add_field(name="Fiel1", value="hi", inline=False)
    embed.add_field(name="Field2", value="hi2", inline=False)

    channel = bot.get_channel(dashboard_channel_id)
    await channel.send(
        embed=embed,
        components=[[
            Button(label="عام"),
            Button(label="خاص"),
            Button(label="كتم الصوت"),
            Button(label="فك كتم الصوت"),
        ]]
    )

for the buttons to react I use the on_button_click event

@bot.event
async def on_button_click(interaction):
    print("Button clicked")

I tried using on_error event so I can prevent the «This interaction failed» message but that did not work, I just want it not to show this error even if the code is invalid. instead, i want to raise it

Код делает то, что должен делать, но после каждого нажатия кнопки он говорит: «Это взаимодействие не удалось». Нажатие кнопки редактирует вставку, чтобы заменить ее на другую. Как мне избавиться от сообщения об ошибке взаимодействия после нажатия кнопки?

Проблема: https://i.stack.imgur.com/i4dTd.png

Код, полученный от: https://github.com/elixss/YouTube/ blob / main / source / buttons.py

Вот код:

@bot.group(invoke_without_command=True)
async def help(ctx):

    # buttons
    one = Button(style=1, label="Commands", id="em1")
    two = Button(style=1, label="Depression", id="em2")
    three = Button(style=1, label="Moderator", id="em3")
    four = Button(style=1, label="Language", id="em4")

    # embeds
    em1 = Embed(title="Commands Plugin",color=0x5865F2)
    em2 = Embed(title="Depression Plugin", description="placeholder", color=0x5865F2)
    em3 = Embed(title="Moderator Plugin", description="placeholder", color=0x5865F2)
    em4 = Embed(title="Language Plugin", description="placeholder", color=0x5865F2)

    # main help embed
    help_embed = Embed(description="> **Help Module**nPress on any button to view the commands for that selected plugin.",
                      color=discord.Color.random())

    # buttons to embeds
    buttons = {
        "em1": em1,
        "em2": em2,
        "em3": em3,
        "em4": em4
    }

    msg = await ctx.send(embed=help_embed,
                         components=[[one, two, three, four]])
    while True:
        event = await bot.wait_for("button_click", timeout=60.0)

        if event.channel is not ctx.channel:
            return

        if event.channel == ctx.channel:
            response = buttons.get(event.component.id)
            await msg.edit(embed=response)

            if response is None:
                await event.channel.send("error, try again.")

2 ответа

Лучший ответ

Как сказал Элиас, вы должны реагировать на взаимодействия, иначе будет отображаться сообщение «Это взаимодействие не удалось», но не с обычным ctx.send(), а с (в вашем случае)

await event.respond(type=4, message="Responded!")

Если вы не хотите отправлять сообщение в ответ на нажатие кнопки или выбор в выборе, вы можете просто использовать type=6 без сообщения:

await event.respond(type=6)

Дополнительные типы см. В документация.


1

Chuaat
6 Сен 2021 в 18:48

Лучший способ сделать это — либо удалить все кнопки после нажатия, либо добавить время восстановления, которое автоматически удалит кнопки через определенное время.

В вашей ситуации это будет выглядеть примерно так:

msg = await ctx.send(embed=help_embed, components=[[one, two, three, four]])
try: 
   res = await client.wait_for("button_click", timeout = 60)
except asyncio.TimeoutError:
   await msg.edit(components = []) #removes buttons from message
else:
   if res.author == message.author:
       #when button is clicked
       await msg.edit(components = [])

Это также предотвращает ограничение скорости, поэтому у вас нет кнопок, постоянно ожидающих ответа.


0

Larg Ank
7 Сен 2021 в 00:22

I have created button roles using discord.py/pycord and they work pretty well but after some time the interaction gets failed it works well for some time but later it starts getting failed. How can it work forever and also surpass reboots

Code:

client.command()
async def genderrole(ctx: commands.Context):
    embed= discord.Embed(
        title= "Assign yourself Gender Roles by clicking on below given options", 
        description="<a:Arrow:944179619433676800> All the members are requested to click on below options in order to get gender roles", 
        color= discord.Colour.green()
        )


    button= Button(label= "Male", style= discord.ButtonStyle.green, emoji= "<a:male:945567841615241276>")
    button1= Button(label= "Female", style= discord.ButtonStyle.green, emoji= "<a:female:945567715530272778>")

    async def male(interaction: discord.Interaction):
        role = ctx.guild.get_role(945566721861906465)
        member = ctx.guild.get_member(interaction.user.id)
        if role in interaction.user.roles:
            await interaction.user.remove_roles(role)
            await interaction.response.send_message(f"{role} role has been taken from you", ephemeral=True)
        else:
            await member.add_roles(role)
            await interaction.response.send_message(f"{role} role has been given to you", ephemeral=True)
    button.callback=male

    async def female(interaction: discord.Interaction):
        role = ctx.guild.get_role(945566773548298252)
        member = ctx.guild.get_member(interaction.user.id)
        if role in interaction.user.roles:
            await interaction.user.remove_roles(role)
            await interaction.response.send_message(f"{role} role has been taken from you", ephemeral=True)
        else:
            await member.add_roles(role)
            await interaction.response.send_message(f"{role} role has been given to you", ephemeral=True)
    button1.callback=female

    view = View(button, button1)
    await ctx.send(embed=embed, view=view)

Help would be appreciated

asked Feb 23, 2022 at 7:44

IDK's user avatar

1

you can use the on_interaction event ,this event has oe argument wich is an instance to a Interaction class so, you can use it as a you normaly do with it but there are an exception you should add a custom_id argument to these button so your code will look somthing like this

#the command part
client.command()
async def genderrole(ctx: commands.Context):
    embed= "do what you did before"
    #buttons right here
    button = Button(..., custom_id="any id you want")
    button1 = Button(..., custom_id="any id you want")
    #just a note don't make the ids the same
    view = View(button, button1)
    await ctx.send(embed=embed, view=view)
#the event part
@client.event
async def on_interaction(interaction):
    #put here avery function you did create before 
    ...
    #now the callback
    if interaction.custom_id == "the id you put for 'button'":
        await male(interaction): #just pass interaction as an argument
    elif interaction.custom_id == "the id you put for 'button1'":
        await female(interaction)

so this ‘on_interaction’ will trigger every time you someone click a button in the server that the bot on.
Bonus information:
you should add some functions or a way to dedect the specific server that the button is clicked on in you’re case you do not need this

more information about the Interaction class check the officiel document
https://docs.pycord.dev/en/master/api.html?highlight=interaction#discord.Interaction

if anything goes wrong please let me know

answered May 16, 2022 at 18:58

Youssef Hmidi's user avatar

I have created button roles using discord.py/pycord and they work pretty well but after some time the interaction gets failed it works well for some time but later it starts getting failed. How can it work forever and also surpass reboots

Code:

client.command()
async def genderrole(ctx: commands.Context):
    embed= discord.Embed(
        title= "Assign yourself Gender Roles by clicking on below given options", 
        description="<a:Arrow:944179619433676800> All the members are requested to click on below options in order to get gender roles", 
        color= discord.Colour.green()
        )


    button= Button(label= "Male", style= discord.ButtonStyle.green, emoji= "<a:male:945567841615241276>")
    button1= Button(label= "Female", style= discord.ButtonStyle.green, emoji= "<a:female:945567715530272778>")

    async def male(interaction: discord.Interaction):
        role = ctx.guild.get_role(945566721861906465)
        member = ctx.guild.get_member(interaction.user.id)
        if role in interaction.user.roles:
            await interaction.user.remove_roles(role)
            await interaction.response.send_message(f"{role} role has been taken from you", ephemeral=True)
        else:
            await member.add_roles(role)
            await interaction.response.send_message(f"{role} role has been given to you", ephemeral=True)
    button.callback=male

    async def female(interaction: discord.Interaction):
        role = ctx.guild.get_role(945566773548298252)
        member = ctx.guild.get_member(interaction.user.id)
        if role in interaction.user.roles:
            await interaction.user.remove_roles(role)
            await interaction.response.send_message(f"{role} role has been taken from you", ephemeral=True)
        else:
            await member.add_roles(role)
            await interaction.response.send_message(f"{role} role has been given to you", ephemeral=True)
    button1.callback=female

    view = View(button, button1)
    await ctx.send(embed=embed, view=view)

Help would be appreciated

asked Feb 23, 2022 at 7:44

IDK's user avatar

1

you can use the on_interaction event ,this event has oe argument wich is an instance to a Interaction class so, you can use it as a you normaly do with it but there are an exception you should add a custom_id argument to these button so your code will look somthing like this

#the command part
client.command()
async def genderrole(ctx: commands.Context):
    embed= "do what you did before"
    #buttons right here
    button = Button(..., custom_id="any id you want")
    button1 = Button(..., custom_id="any id you want")
    #just a note don't make the ids the same
    view = View(button, button1)
    await ctx.send(embed=embed, view=view)
#the event part
@client.event
async def on_interaction(interaction):
    #put here avery function you did create before 
    ...
    #now the callback
    if interaction.custom_id == "the id you put for 'button'":
        await male(interaction): #just pass interaction as an argument
    elif interaction.custom_id == "the id you put for 'button1'":
        await female(interaction)

so this ‘on_interaction’ will trigger every time you someone click a button in the server that the bot on.
Bonus information:
you should add some functions or a way to dedect the specific server that the button is clicked on in you’re case you do not need this

more information about the Interaction class check the officiel document
https://docs.pycord.dev/en/master/api.html?highlight=interaction#discord.Interaction

if anything goes wrong please let me know

answered May 16, 2022 at 18:58

Youssef Hmidi's user avatar

Create an account to follow your favorite communities and start taking part in conversations.

r/Discord_Bots

I get it with every single interactable button on my bot (they all work). Defer works but it’s not ideal with the annoying extra message sent.

level 1

if you are getting an error message, something is not working properly.

you should try to understand the error message (that you haven’t posted), and figure out what’s wrong

level 2

It’s the message you get when interacting with a discord component button. «This interaction failed» happens every single time on multiple buttons despite everything working as expected.

Which probably means it’s expecting a special response i haven’t given it to signal the interaction has worked, I’m not sure what that is. Deferring works to stop the message though.

level 1

Does your code receive it? The error appears if you do not respond to the interaction within 3 seconds. Defer does this job, for example. Others include stuff like interaction.response.pong or interaction.response.edit_message do these too.

Also note that discord-py is no longer maintained

level 2

Response isn’t a valid attribute. Respond is, but respond doesn’t have the attribute pong or edit_message.

Defer does work, but i don’t want to use it because of the message it sends.

level 1

Having the same issue. My buttons edit an embed and it does what I want it to do (edit the embed page) but every time I click one of the buttons, I get the «this interaction failed»

About Community

Subreddit Icon

Non-official subreddit for Discord bot developement



Before asking a question, look at these :)

Before, check you are using the correct library (discord-components not discord-buttons) and if your library is in

the newest version

.

How to make buttons inline?

Your code must be something like

await <discord.abc.Messageable>.send(

You should use a two-dimensional array like below to make buttons inline.

await <discord.abc.Messageable>.send(

How do I remove components?

Simple. Edit the message with parameter components set to [].

msg = await <discord.abc.Messageable>.send(

interaction = await <discord.ext.commands.Bot or discord.Client>.wait_for(«event»)

await msg.edit(components = [])

await interaction.edit_origin(

How do I ignore the interaction?

Just respond with the type 6 with no other parameters or defer with edit_origin enabled.

There is an event on_button_click and on_select_option. You can use this as normal events.

@<discord.ext.commands.Bot or discord.Client>.event

async def on_button_click(interaction):

if interaction.responded:

await interaction.send(content = «Yay!»)

@<discord.ext.commands.Bot or discord.Client>.event

async def on_select_option(interaction):

if interaction.responded:

await interaction.send(content = «Yay!»)

TypeError: send() got an unexpected keyword argument ‘components’

Have you put DiscordComponents(<discord.Client or discord.ext.commands.Bot>) inside the on_ready event or initialized the bot with ComponentsBot?

Handle multiple interacts

You should put a while on discord.Client.wait_for to handle multiple clicks

interaction = await <discord.ext.commands.Bot or discord.Client>.wait_for(«event»)

await interaction.send(content = «Wow»)

Disabling the components for specific users

This is impossible but you can ignore the interaction by putting a check.

interaction = await <discord.ext.commands.Bot or discord.Client>.wait_for(

check = lambda i: i.user.id == «something»

I get »404 Not Found (error code: 10062): Unknown interaction»

Check if you already responded to the interaction.

You send a discord.Emoji object to the parameter. You can get the custom emoji by doing

<discord.ext.commands.Bot or discord.Client>.get_emoji(849325102746042439)

Can I set my own colors for buttons?

class minigames(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @disnake.ui.button(label="b1", style=disnake.ButtonStyle.green, custom_id="test1")
    async def button_callback(self, interaction:disnake.Interaction, button: disnake.ui.Button):
        await interaction.response.defer()
        await interaction.send("clicked!")


    @commands.command(name="test")
    async def test(self, inter: disnake.MessageInteraction):
        view = disnake.ui.View()
        view.add_item(disnake.ui.Button(label="Button 1", custom_id="test1"))
        msg = await inter.send(content="1", view=view)

в данном фрагменте кода необходимо создать кнопку и привязать ей действия внутри класса. Команда !test эту кнопку должно отобразить, а нажатие на неё должно быть обработано, и выведено clicked! (debug purposes)

Как можно заметить, работа идет внутри кога, так что использовать @commands, вместо @bot?
Ошибок программа не выдаёт

Get the Reddit app

Scan this QR code to download the app now

Or check it out in the app stores

  • Ошибка видеокарты код 43 gtx 770
  • Ошибка взаимной проверки подлинности пароль сервера на контроллере домена устарел
  • Ошибка видеокарты биос как исправить
  • Ошибка вещественное деление на 0 паскаль
  • Ошибка видеокарты mono cga что это