Skip to main content
alterself connects to the Discord gateway over a persistent WebSocket and receives a continuous stream of JSON payloads describing everything that happens in Discord, including messages, reactions, guild changes, voice state transitions, and more. For each payload, alterself looks up the event name, builds the appropriate model objects (such as Message, Guild, or User), and calls every registered listener in the order it was added. You register listeners using decorators or the manual registration API, and alterself takes care of the rest.

Registering Listeners

alterself offers three styles of listener registration so you can choose whichever fits your code structure best.

@bot.on_event: register by function name

Decorate a coroutine whose name starts with on_. alterself strips the on_ prefix and matches the remainder (case-insensitively) against gateway event names:

@bot.listen(event_name): explicit name

Use this decorator when you want to give the function a different name, or when you need multiple handlers for the same event in the same scope:

bot.add_listener / bot.remove_listener: manual registration

Register and deregister listeners programmatically, which is useful for testing, conditional feature flags, or dynamic plugin systems:
Multiple listeners can be registered for the same event. alterself calls them all concurrently using asyncio.gather, so a slow listener does not block others.

Event Reference

Connection

Messages

Guilds

Channels

Presence and Typing

Relationships

Voice

Raw Event Access

If you need the unprocessed gateway payload before alterself parses it into model objects, listen for the special RAW event. Your handler receives the full payload dictionary exactly as it arrived from Discord:
Raw payloads contain field names and structures defined by the Discord API, which can change without notice. Prefer the typed model objects whenever possible, and fall back to raw access only when you need a field that alterself does not yet expose.

Complete Examples