Discord.py:使用wait_for获取消息成员时遇asyncio.TimeoutError问题
问题修复方案
错误原因分析
- Check函数逻辑错误:原代码里
m == discord.Member是把消息对象和Member类本身做对比,永远返回False,导致wait_for匹配不到有效消息,直接触发超时。同时check函数的参数类型注解错误,wait_for('message')返回的是discord.Message对象,而非discord.Member。 - 未正确提取目标用户:原代码直接把消息对象加入列表,而非从消息里提取被@的用户。
- 未处理按钮交互回应:Discord要求按钮交互必须在3秒内给出回应,否则会触发交互失败提示。
修正后的代码
import asyncio import discord class LevelButtons(discord.ui.View): def __init__(self, bot, message): super().__init__() self.bot = bot self.message = message self.first_level = [] @discord.ui.button(label="Setting up first category", style=discord.ButtonStyle.green) async def conf_level(self, interaction: discord.Interaction, button: discord.ui.Button): # 先回应按钮交互,避免Discord报错 await interaction.response.send_message("Send a @user who will be in the first category", ephemeral=False) def check(m: discord.Message): # 确保消息来自触发按钮的用户、在同一频道、且包含用户提及 return m.author == interaction.user and m.channel == self.message.channel and len(m.mentions) > 0 try: # 等待用户发送带@的消息 msg = await self.bot.wait_for('message', timeout=10, check=check) except asyncio.TimeoutError: await self.message.channel.send('Received no input so operation was aborted') else: # 提取第一个被提及的成员 member = msg.mentions[0] self.first_level.append(member) await self.message.channel.send(f"{member.mention} added in the first category")
关键修正点
- 修正Check函数:
- 参数类型注解改为
discord.Message - 判断条件调整为验证消息发送者是触发按钮的用户、消息在同一频道、且包含至少一个用户提及
- 参数类型注解改为
- 提取目标用户:通过
msg.mentions获取消息中被@的用户列表,取第一个成员加入分类 - 补充交互回应:调用
interaction.response.send_message及时回应按钮交互,符合Discord的交互规范
内容的提问来源于stack exchange,提问作者ненавижу думать
相关产品推荐
相关产品推荐

