Disnake中使用wait_for()导致交互失败的问题求助
解决Disnake中使用bot.wait_for导致交互失败的问题
问题根源
- 交互超时限制:Disnake要求交互(如下拉菜单回调)必须在3秒内返回响应,直接调用
bot.wait_for('message')会阻塞回调函数,导致超过时间限制触发交互失败。 - 对象赋值错误:代码中
self.Embeddescription=msg直接将Message对象赋值给描述字段,应该取消息内容msg.content。 - 未及时响应交互:回调函数中未先处理交互状态就等待用户输入,导致交互一直处于挂起状态。
修复方案
- 先通过
inter.response.defer()临时响应交互,避免超时。 - 正确提取用户输入的消息内容。
- 添加超时异常处理,提升鲁棒性。
- 完成输入后编辑原消息更新Embed。
修改后的代码
import disnake from disnake import Intents from disnake.ext.commands import Context, Bot from disnake.errors import TimeoutError bot = Bot(command_prefix='+', test_guilds=[1032280589031706706], help_command=None, intents=Intents.all()) @bot.event async def on_ready(): print('ready') @bot.command() async def test(ctx: Context): view = DropdownView() await ctx.send(embed=disnake.Embed(description='>\n '), view=view) class Dropdown(disnake.ui.Select): def __init__(self): self.Embedtitle = None self.Embeddescription = '>\n' options = [ disnake.SelectOption( label="Red", description="修改描述为红色主题", emoji="🟥" ), disnake.SelectOption( label="Green", description="修改描述为绿色主题", emoji="🟩" ), disnake.SelectOption( label="Blue", description="修改描述为蓝色主题", emoji="🟦" ), ] super().__init__( placeholder="选择要修改的Embed内容...", min_values=1, max_values=1, options=options, ) async def callback(self, inter: disnake.MessageInteraction): # 先临时响应交互,避免超时 await inter.response.defer() # 发送提示消息,告诉用户需要输入内容 prompt_msg = await inter.followup.send(f"请输入{self.values[0]}主题的描述内容:", ephemeral=True) def check(m: disnake.Message): return inter.author.id == m.author.id and m.channel == inter.channel and m.content != '' try: # 等待用户输入消息 msg = await bot.wait_for('message', check=check, timeout=120.0) # 提取消息内容作为新描述 self.Embeddescription = msg.content # 更新原消息的Embed await inter.message.edit(embed=disnake.Embed( colour=None, title=self.Embedtitle, description=self.Embeddescription, )) # 删除提示消息和用户输入的消息 await prompt_msg.delete() await msg.delete() except TimeoutError: # 处理超时情况 await inter.followup.send("输入超时,请重新操作", ephemeral=True) await prompt_msg.delete() class DropdownView(disnake.ui.View): def __init__(self): super().__init__(timeout=None) # 设置View永不超时,保持下拉菜单可用 self.add_item(Dropdown()) bot.run("token")
关键改动说明
- 用
inter.response.defer()先确认交互,避免3秒超时。 - 添加
ephemeral=True的提示消息,仅用户可见,避免频道消息混乱。 - 处理
TimeoutError,给用户明确的超时提示。 - 将View的
timeout设为None,保持下拉菜单长期可用。
内容的提问来源于stack exchange,提问作者majvax
相关产品推荐
相关产品推荐

