discord.py按钮功能正常却报‘interaction failed’问题求助
问题解决:Discord按钮功能正常但显示“交互失败”
核心原因分析
你的按钮逻辑能正常执行,但客户端提示交互失败,大概率是没有正确完成Discord的交互响应流程:
- Discord要求所有交互(按钮、斜杠命令等)必须在3秒内得到响应(无论是直接回复还是延迟响应)
- 你当前使用
channel.send()发送提示,这属于独立的频道消息,不会标记交互为“已完成”,客户端会一直等待交互响应直到超时
具体修复方案
1. 确保在3秒内调用延迟响应
即使你已经加了defer,也要确保它是第一个被执行的交互相关操作,不能放在耗时代码之后:
@discord.ui.button(label='Hit', style=discord.ButtonStyle.primary, custom_id='hit') async def hit(self, button: discord.ui.Button, interaction: discord.Interaction): # 第一步就调用defer,确保在3秒内响应 await interaction.response.defer() user_id = self.user_id await self.cog.hit(interaction, user_id, self.channel)
2. 用交互的后续回复替代channel.send()
在cog的hit方法里,不要直接用channel.send(),而是使用interaction.followup.send()来发送提示,这样会标记交互为完成:
async def hit(self, interaction, user_id, channel): if user_id not in self.players: # 替换channel.send为followup.send await interaction.followup.send("You haven't started the game yet. Use `!start`.") return # 其他代码...
3. 检查是否有阻塞异步的代码
如果你的_some extra code里有同步的耗时操作(比如大量计算、IO操作),会导致整个响应流程超时。这种情况需要把同步代码放到线程池里执行,比如:
import asyncio async def hit(self, interaction, user_id, channel): if user_id not in self.players: await interaction.followup.send("You haven't started the game yet. Use `!start`.") return # 把耗时同步代码放到线程池 result = await asyncio.to_thread(self.sync_heavy_task) # 后续逻辑...
4. 确保View的超时设置正确
如果你的View存在超时,可能导致按钮失效。可以在初始化View时设置合理的超时时间,或者禁用超时:
class StartButtons(discord.ui.View): def __init__(self, user_id, cog, channel): # 设置超时为10分钟,或者timeout=None禁用超时 super().__init__(timeout=600) self.user_id = user_id self.cog = cog self.channel = channel
内容的提问来源于stack exchange,提问作者worker
相关产品推荐
相关产品推荐

