discord.py中如何在wait_for的check函数内使用TextChannelConverter
解决方法
核心报错原因
discord.py 的 wait_for 方法的 check 参数仅支持传入同步函数,框架不会主动对异步协程类型的返回值做 await 处理,所以直接传入异步校验函数会触发协程未等待的警告,同时校验逻辑也不会正常生效。
推荐解决方案
不需要强行在 check 函数内完成所有校验逻辑,把校验拆分到两步即可兼顾简洁性和功能需求:
- 先简化 check 函数,仅做最基础的消息来源校验,确保拿到的是触发命令的用户在当前频道发送的消息
def checkChannel(msg): return ctx.message.author == msg.author and ctx.channel == msg.channel
- 拿到符合来源要求的消息后,再单独处理取消判断和频道转换逻辑,利用
TextChannelConverter自动支持频道ID、频道提及、频道名称三种输入格式的特性,代码会非常简洁:
import asyncio from discord.ext import commands try: # 监听符合来源要求的用户消息 msg = await self.bot.wait_for('message', check=checkChannel, timeout=60) except asyncio.TimeoutError: await ctx.send("操作超时已取消") return # 先判断是否是取消指令 if msg.content.strip() == "Cancel": await ctx.send("操作已取消") return # 调用转换器做频道校验,自动兼容所有合法频道输入格式 try: embedChannel = await commands.TextChannelConverter().convert(ctx, msg.content) except commands.BadArgument: await ctx.send("输入内容不是当前服务器的有效频道,请重新运行命令重试") return # 后续可正常使用 embedChannel 变量完成后续逻辑
不推荐的替代方案
如果一定要在校验阶段完成所有判断,可以在同步check函数内用asyncio.run()手动执行异步转换逻辑,但该方法会阻塞事件循环,高并发场景下会影响机器人性能,不建议使用。
内容的提问来源于stack exchange,提问作者Andrei
相关产品推荐
相关产品推荐

