Only last event handler working in Discord.py bot

I’m having trouble with my Discord bot using discord.py library. I created multiple event handlers for the on_message event, but only one of them seems to work properly. When I test the bot, only the last defined handler responds to messages while the others get ignored completely.

Here’s my current code setup:

import discord
from discord.ext import commands

bot_description = 'My Test Bot'
command_prefix = '$'

bot = commands.Bot(description=bot_description, command_prefix=command_prefix)

greetings = ['hey', 'hello', 'hi']

@bot.event
async def on_ready():
    print('Bot is online')

@bot.event
async def on_message(msg):
    if msg.content.startswith('$info'):
        await bot.send_message(msg.channel, 'Information here!')

@bot.event
async def on_message(msg):
    if msg.content.lower() in greetings:
        await bot.send_message(msg.channel, 'Hello friend!')

bot.run('TOKEN_HERE')

The greeting handler works fine when someone types ‘hey’ or ‘hello’, but the ‘$info’ command doesn’t trigger at all. If I switch the order of these handlers, then only the ‘$info’ works and greetings stop working. What am I doing wrong here? Is there a better way to handle multiple message events?

The issue you’re encountering is a common Python behavior where decorator functions get overwritten when defined multiple times. When you declare two @bot.event decorators for on_message, the second one completely replaces the first one in memory. This isn’t specific to discord.py but happens with any Python decorator.

Since you’re using commands.Bot, I’d recommend converting your $info functionality into a proper command using @bot.command() decorator. Keep the greeting logic in your single on_message handler. Also, make sure to add await bot.process_commands(msg) at the end of your on_message function, otherwise your bot commands won’t work at all. Without this line, the on_message event prevents command processing entirely.

I’ve faced a similar issue with discord.py before. The core problem is that Python replaces the previous @bot.event decorator, which is why only the last one is working. To resolve this, I recommend combining all your logic into a single on_message event. Alternatively, since you’re utilizing commands.Bot, you could turn your $info functionality into a command using @bot.command(). Keep your greeting logic simple in the on_message handler, but make sure to add await bot.process_commands(msg) at the end. This allow your bot to process any commands successfully.

exactly! you can only use one @bot.event for on_message. it replaces the previous one. try merging your logic into a single handler or turn the $info into a command since you’re already using commands.Bot.