discord.py发送Embed后监听消息替代on_message()的实现方案
在discord.py命令内监听下一条消息(无需on_message)
我完全理解你的需求——在执行verificationSetup命令发送提示Embed后,直接捕获用户的下一条消息存入变量,而且不想依赖全局的on_message事件。这其实是discord.py里很常见的场景,官方提供的wait_for方法就是专门解决这个问题的,比手动用on_message要更简洁,还能避免命令间的干扰。
下面是修改后的完整实现代码,我会逐段解释关键点:
import asyncio import discord from discord.ext import commands client = commands.Bot(command_prefix="@", intents=discord.Intents.all()) @client.command() async def verificationSetup(ctx, channel_id: int, *, message): if channel_id is not None: # 发送提示用户输入emoji的Embed embed = discord.Embed(title="Send the emoji you want to set!", description="Please send the emoji (regular or custom) you wish to use for verification below.") await ctx.send(embed=embed) # 定义消息检查规则:只接收命令发起者在当前频道发送的消息 def check(m): return m.author == ctx.author and m.channel == ctx.channel try: # 等待用户的下一条消息,设置60秒超时(可根据需求调整) user_response = await client.wait_for('message', check=check, timeout=60.0) selected_emoji = user_response.content # 这里可以添加你的后续逻辑,比如将emoji存入配置、发送确认消息等 await ctx.send(f"Success! You've selected the emoji: {selected_emoji}") # 额外:如果需要处理自定义emoji,可添加这段转换逻辑 try: emoji_obj = discord.PartialEmoji.from_str(selected_emoji) await ctx.send(f"Custom emoji details: Name: {emoji_obj.name}, ID: {emoji_obj.id}") except ValueError: await ctx.send("This is a standard emoji/text.") except asyncio.TimeoutError: # 处理用户超时未回复的情况 await ctx.send("Oops, you took too long to respond! Please run the command again if you still need to set the emoji.") # 记得替换成你的机器人token client.run("YOUR_BOT_TOKEN")
关键说明:
wait_for方法:这是核心,它会监听指定的事件(这里是message),直到捕获到符合check条件的消息才会继续执行代码,完全不需要全局的on_message事件。- check函数:这个函数用来过滤消息,确保只有发起命令的用户在同一频道发送的消息才会被接收,避免误捕获其他人的消息,保证命令的独立性。
- 超时处理:通过
timeout参数设置等待时长,超时后会抛出asyncio.TimeoutError,我们可以捕获这个异常来给用户发送超时提示,避免机器人一直处于等待状态。 - 自定义emoji处理:如果用户发送的是服务器自定义emoji,
user_response.content会是类似<:emoji_name:123456789>的格式,我们可以用discord.PartialEmoji.from_str()将其转换成对象,方便后续的存储或使用。
这样实现的话,你的命令就能完美完成“发送提示→等待用户输入→存储变量”的流程,而且代码逻辑清晰,不会和其他命令或全局事件冲突。
内容的提问来源于stack exchange,提问作者user13690062
相关产品推荐
相关产品推荐

