使用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
相关产品推荐
相关产品推荐

