Discord.py机器人点击“Continue”按钮后无法更新响应,提示“Interaction failed”问题求助
Discord.py机器人点击“Continue”按钮后无法更新响应,提示“Interaction failed”问题求助
看起来你的问题大概率是几个discord.py交互处理的细节没注意到,我帮你梳理下可能的原因和修复方案:
1. 按钮回调里的变量作用域错误(最可能的直接原因)
你在bouton_tuto_suivant类的__init__里把maison赋值给了self.maison,但在按钮回调里直接用了maison这个变量——这会触发NameError,导致整个回调函数抛出异常,交互自然就失败了。
修复后的回调代码应该是这样的:
@discord.ui.button(label="Continuer", style=discord.ButtonStyle.blurple) async def suivant_callback(self, ctx : discord.Interaction, button) : # 把maison改成self.maison,引用类实例的属性 if self.maison == "Gryffondor" : bienvenue_gryffondor = discord.Embed(...) await ctx.response.edit_message(embed = bienvenue_gryffondor, view = None) # 其他学院的判断逻辑也要同步改成self.maison
2. View超时导致交互失效
discord.py的View默认会在180秒(3分钟)后自动失效,如果你的问卷流程耗时超过这个时间,点击“Continue”按钮时View已经被销毁,就会出现“Interaction failed”的提示。
解决方法是给所有的View类加上timeout=None,让它们一直保持有效,直到消息被编辑或删除:
- 给
bouton_choixpeau_suivant添加构造函数:
class bouton_choixpeau_suivant(discord.ui.View) : def __init__(self): super().__init__(timeout=None) # 设置永久有效 @discord.ui.button(label="C'est partis", style=discord.ButtonStyle.blurple) async def suivant_callback(self, interaction : discord.Interaction, button) : await questionnaire_choixpeau(interaction, Q1, id)
- 给
select_questionnaire添加构造函数:
class select_questionnaire(discord.ui.View): def __init__(self): super().__init__(timeout=None) @discord.ui.select( ... ) async def select_callback(self, ctx : discord.Interaction, select) : # 原有的判断逻辑
- 修改
bouton_tuto_suivant的构造函数:
class bouton_tuto_suivant(discord.ui.View) : def __init__(self, maison): super().__init__(timeout=None) # 改成timeout=None self.maison = maison
3. 交互响应超时的处理
如果创建bienvenue_gryffondor这类Embed的过程比较复杂(比如要加载图片、处理大量数据),可能会超过discord要求的3秒交互响应时间,这时候可以先延迟响应,再编辑消息:
async def suivant_callback(self, ctx : discord.Interaction, button) : await ctx.response.defer() # 先告诉Discord我们稍后会响应,避免超时 if self.maison == "Gryffondor" : bienvenue_gryffondor = discord.Embed(...) # 用edit_original_response来编辑原来的消息 await ctx.edit_original_response(embed = bienvenue_gryffondor, view = None)
额外优化建议
你现在在每个函数里重复定义View类的做法虽然能运行,但不够优雅,也可能引发潜在问题。可以把这些View移到函数外面作为全局类,通过构造函数传递需要的参数(比如问卷编号、用户ID、学院名称),这样代码结构更清晰,也更容易维护。
比如把选择菜单的View改成这样:
class SelectQuestionnaire(discord.ui.View): def __init__(self, current_q, user_id): super().__init__(timeout=None) self.current_q = current_q self.user_id = user_id @discord.ui.select(...) # 你的选择菜单参数 async def select_callback(self, ctx : discord.Interaction, select) : if self.current_q == Q1 : await questionnaire_choixpeau(ctx, Q2, self.user_id) # 其他判断逻辑同理
然后在questionnaire_choixpeau里调用:
await interaction.response.edit_message(embed = embed, attachments = [], view = SelectQuestionnaire(numQ, id))
先试试前面三个修复方案,尤其是第一个变量作用域的问题,应该能解决你的交互失败问题。
备注:内容来源于stack exchange,提问作者bilbibalou
相关产品推荐
相关产品推荐

