You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用discord_components实现带按钮分页Embed时报交互失败错误如何解决?

问题描述

我刚接触Discord按钮功能,正在为帮助菜单实现带按钮分页的Embed效果,现有代码功能符合预期,但每次点击按钮完成交互后,按钮下方都会弹出“This interaction failed”错误提示,请问是什么原因、如何修复?
报错截图
相关代码如下:

if message.content.lower().startswith('.help'):
    embed = discord.Embed(title="test", description="test", color=0x33f6dc)
    embed.set_author(name="test")
    embed.add_field(name="test", value="!test", inline=True)

    embed2 = discord.Embed(title="test2", description="test2", color=0x33f6dc)
    embed2.set_author(name="test2")
    embed2.add_field(name="test2", value="!test2", inline=True)

    pages = 2
    currentpage = 1
    
    page1 = await message.channel.send(embed=embed, components=
        [
            Button(style=ButtonStyle.blue, label="▶️", custom_id="next"),
        ]
    )
    while True:
        try:
            interaction = await client.wait_for("button_click", check=lambda inter: inter.custom_id == "next", timeout=300)

            if interaction and currentpage != pages:
                await page1.edit(embed=embed2, components=
                [
                    Button(style=ButtonStyle.blue, label="◀️", custom_id="back"),
                ])
                currentpage += 1

                interaction2 = await client.wait_for("button_click", check=lambda inter: inter.custom_id == "back")

                if interaction2 and currentpage > 1:
                    await page1.edit(embed=embed, components=
                    [
                        Button(style=ButtonStyle.blue, label="▶️", custom_id="next"),
                    ])
                    currentpage -= 1
        except asyncio.TimeoutError:
            await page1.delete()
            break
原因分析

Discord对所有交互事件都有3秒的响应超时限制,你在捕获到button_click事件后,只执行了编辑原消息的操作,没有对触发操作的交互本身返回任何响应,Discord会判定该交互未被处理,因此弹出"This interaction failed"提示。

修复方案

每次捕获到按钮点击事件后,先调用response.defer()告知Discord你已经收到交互请求,后续会更新内容,或者直接使用交互自带的编辑消息方法来修改内容即可。修改后的完整代码如下:

if message.content.lower().startswith('.help'):
    embed = discord.Embed(title="test", description="test", color=0x33f6dc)
    embed.set_author(name="test")
    embed.add_field(name="test", value="!test", inline=True)

    embed2 = discord.Embed(title="test2", description="test2", color=0x33f6dc)
    embed2.set_author(name="test2")
    embed2.add_field(name="test2", value="!test2", inline=True)

    pages = 2
    currentpage = 1
    
    page1 = await message.channel.send(embed=embed, components=
        [
            Button(style=ButtonStyle.blue, label="▶️", custom_id="next"),
        ]
    )
    while True:
        try:
            interaction = await client.wait_for("button_click", check=lambda inter: inter.custom_id == "next", timeout=300)
            # 新增:响应交互
            await interaction.response.defer()
            if interaction and currentpage != pages:
                await page1.edit(embed=embed2, components=
                [
                    Button(style=ButtonStyle.blue, label="◀️", custom_id="back"),
                ])
                currentpage += 1

                interaction2 = await client.wait_for("button_click", check=lambda inter: inter.custom_id == "back")
                # 新增:响应第二个交互
                await interaction2.response.defer()
                if interaction2 and currentpage > 1:
                    await page1.edit(embed=embed, components=
                    [
                        Button(style=ButtonStyle.blue, label="▶️", custom_id="next"),
                    ])
                    currentpage -= 1
        except asyncio.TimeoutError:
            await page1.delete()
            break
可选优化

你现在嵌套等待按钮事件的写法会导致逻辑层级过深,后续如果分页数量增加会很难维护,建议把分页逻辑放到同一个等待逻辑里判断custom_id处理即可,不需要嵌套两次wait_for。

内容的提问来源于stack exchange,提问作者user10241025

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 17:45:01