如何实现Discord机器人同时兼容on_message事件与command命令?
嘿,这个问题我之前做Discord机器人时也踩过坑!核心原因是当你自定义了on_message事件处理函数后,会覆盖discord.py默认的命令分发逻辑——也就是说,机器人只会执行你在on_message里写的逻辑,完全不会去检查那些用@bot.command装饰的命令了。
要解决这个问题很简单,只需要在你的on_message函数末尾加上一行关键代码,让机器人手动去处理命令即可。另外我也帮你修正了代码里的几个小问题,比如过时的发送消息方法和不完整的字符串分割语法:
修正后的完整代码
import discord from discord.ext import commands bot = commands.Bot(command_prefix='~') @bot.event async def on_ready(): print(f"Logged in as {bot.user.name}") @bot.event async def on_message(message): # 建议先过滤机器人自身消息,避免循环触发 if message.author.bot: return # 处理你自定义的消息触发逻辑 if message.content.upper().startswith('!PING'): user_id = message.author.id # 新版本discord.py用message.channel.send替代bot.send_message await message.channel.send(f"<@{user_id}> Pong!") if message.content.upper().startswith('!SAY'): # 修正split语法,用" "分割1次,把命令和内容分开 args = message.content.split(" ", 1) if len(args) > 1: await message.channel.send(args[1]) # 关键:必须调用这一行,让机器人处理@bot.command定义的命令 await bot.process_commands(message) # 测试用的命令,验证共存效果 @bot.command(pass_context=True) async def greet(ctx): await ctx.send(f"Hi there, {ctx.author.display_name}!") # 替换成你的机器人Token bot.run("YOUR_BOT_TOKEN")
重要说明
await bot.process_commands(message)这行是核心修复,它会告诉机器人:“我自己的逻辑处理完了,现在去看看这条消息是不是命令,是的话就执行对应的指令”。你可以根据需求调整它的位置——如果想让命令优先于自定义逻辑执行,就把它放在自定义逻辑前面。- 如果你用的是discord.py v1.x及以上版本,
pass_context=True其实已经默认开启了,不过保留也不会有问题。
内容的提问来源于stack exchange,提问作者KowaiiNeko
相关产品推荐
相关产品推荐

