You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:27:05