Handling Messages#
This guide shows how to handle incoming messages with the high-level App API.
Basic handler flow#
App routes incoming message nodes into your registered handlers.
from waton import App
from waton.app import filters
app = App(storage_path="my_session.db")
@app.message(filters.text & filters.private)
async def on_private_text(ctx):
if ctx.text:
await ctx.reply(f"You said: {ctx.text}")
@app.command("/help")
async def on_help(ctx):
await ctx.reply("Available commands: /help, ping")
Filters#
Available built-in filters:
filters.textfilters.privatefilters.groupfilters.regex(pattern)filters.command(prefix)
Filters can be combined:
filters.text & filters.privatefilters.group | filters.private
Context helpers#
Inside a handler, ctx provides:
ctx.textctx.from_jidctx.senderawait ctx.reply(text)await ctx.react(emoji)
Advanced helpers also exist:
await ctx.forward(to_jid)await ctx.delete()
For production-critical revoke/edits, prefer explicit MessagesAPI methods
such as send_delete(...) and send_edit(...).
Middleware#
You can add middleware to run logic before/after handlers:
async def log_middleware(ctx, next_step):
print(f"incoming from={ctx.from_jid} text={ctx.text!r}")
await next_step()
app.use(log_middleware)
Message content model#
ctx.message contains parsed metadata beyond plain text, including:
content_typeandcontentprotocol fields (edit/revoke/history/app-state)
encrypted add-on fields (poll update, event response, encrypted reaction)
If you need these details, inspect ctx.message directly.
Important scope note#
App handlers process only message nodes. If you need normalized non-message
events (receipts, notifications, calls, acks), attach handlers to low-level
WAClient.on_event.
Next steps#
Outgoing message APIs: Sending Messages
Event categories and payloads: Event Model