Why can't I have multiple on_message
events?
import discord
client = discord.Client()
@client.event
async def on_ready():
print('in on_ready')
@client.event
async def on_message(message):
print("in on_message #1")
@client.event
async def on_message(message):
print("in on_message #2")
@client.event
async def on_message(message):
print("in on_message #3")
client.run("TOKEN")
For example, if I typed anything in discord, it's always only the last on_message
that gets triggered. How can I get all three to work?
It's not possible with the native
Client
You can only have one
on_message
, if you have multiple, only the last one will be called for theon_message
event. You'll just need to combine your threeon_message
.Like any Python variable/function (unless the decorator stores your function,
@client.event
does it by keeping only the most recent callback), if multiple names are the same, the most recently will be kept, and all others will get overwritten.This is a simple example I wrote to give you a broad understanding of how events in discord.py work (note: the actual code isn't exactly like this, as it's rewritten and significantly reduced).
As you can see
client.event
only keep one instance ofon_message
.You can with
Bot
instancesAlternatively, if you're using the
ext.commands
extension of discord.py, there is a native way to have multipleon_message
callbacks. You do so by using defining them as alistener
. You can have at most oneon_message
event, and infinite amounts ofon_message
listeners.When a message is received, all
on_message #1-3
will all get printed.In python, functions are just objects.
defines an object called
foo
, You can see this using a Python shell.If you define a new method after, or redefine the variable
foo
, you lose access to the initial function.How the
@client.event
decorator works is it tells your client that new messages should be piped into the messages, and well, if the method gets redefined, it means the old method is lost.