Discord.py 2.0:消息编辑时按钮提前显示引发交互错误的解决咨询
解决Discord Bot消息编辑视图回调延迟问题
针对云端部署Discord Bot时,message.edit(view=...)后按钮立即显示但回调暂不可用的问题,给你几个可行的解决思路:
1. 先展示禁用状态的按钮,编辑完成后再启用
核心思路是先让按钮处于不可点击状态,等消息编辑操作完全完成后,再把按钮改成可点击状态。这样用户不会过早触发无效交互。
修改你的代码示例:
async def throw_dice(self,ctx): try : superself = self async def action(superself): ... if isinstance(self.current,PlayerDiscord) : class myButton(ui.Button): def __init__(self,label,style,row=None): # 初始化时设置按钮为禁用状态 super().__init__(label=label,style=style,row=row, disabled=True) async def callback(self,interaction): await interaction.response.defer() nonlocal superself if interaction.user.id==superself.current.member.id: self.view.stop() await superself.msg_play.edit(view=None) await action(superself) self.view = FRPGame.myView(ctx,self) # 创建新视图 self.view.add_item(myButton("\U0001F3B2",style=discord.ButtonStyle.primary)) # 第一步:先编辑消息,展示禁用的按钮 await self.msg_play.edit(content=self.content,view=self.view) # 第二步:编辑完成后,启用按钮并更新视图 self.view.children[0].disabled = False await self.msg_play.edit(view=self.view) else : ... except BaseException : traceback.print_exc()
2. 在回调中捕获交互错误并给出提示
如果不想让按钮一开始禁用,可以在回调函数里捕获未知交互错误,给用户明确提示,避免无响应的情况。
修改按钮的回调部分:
async def callback(self,interaction): try: await interaction.response.defer() nonlocal superself if interaction.user.id==superself.current.member.id: self.view.stop() await superself.msg_play.edit(view=None) await action(superself) except discord.errors.InteractionResponded: # 捕获交互未就绪的错误,给用户私发提示 await interaction.followup.send("按钮还没准备好,请稍等再点~", ephemeral=True) except Exception as e: traceback.print_exc() await interaction.followup.send("操作失败了,请重试一下", ephemeral=True)
3. 用状态变量标记视图是否加载完成
在你的Bot类里加一个状态变量,标记消息编辑是否完成,回调时先检查这个状态,未完成就提示用户等待。
示例:
# 先在类里添加状态属性 self.view_ready = False # 然后在throw_dice函数里修改 await self.msg_play.edit(content=self.content,view=self.view) # 编辑完成后标记状态为就绪 self.view_ready = True # 按钮回调里添加状态检查 async def callback(self,interaction): nonlocal superself if not superself.view_ready: await interaction.response.send_message("请稍等,按钮正在初始化...", ephemeral=True) return # 后续原有逻辑 await interaction.response.defer() if interaction.user.id==superself.current.member.id: self.view.stop() await superself.msg_play.edit(view=None) await action(superself)
内容的提问来源于stack exchange,提问作者S3NI
相关产品推荐
相关产品推荐

