Events

Prosody is powered by events. From events to notify about the state of the server (startup, shutdown, etc.) to events about incoming connectections, stanzas, and other data.

An event is a notification that something has happened, or is about to happen. In Prosody each event has a unique name, which is how events are identified.

If you want to do something when a certain event occurs, for example send a message to a user when they log in, then you want to "hook" that event. This involves attaching a handler function which will be called each time the event occurs. There are functions in the module API to help you do this.

This page serves as a list of the different events that Prosody may generate internally that modules may be interested in.

Server status

Prosody goes through several stages during startup and shutdown. An event is fired for each transition. The table below lists each event and its meaning. All of these events are global (see module:hook_global()).

server-starting The server is starting. Plugin modules may not catch this event because they will not have been loaded yet.
server-started All server initialisation is complete and all modules loaded. May not be accepting client connections yet though.
server-stopping The server is preparing to shut down.
server-stopped All shutdown preparation is complete, the server process is about to quit. This is always the last core event.
config-reloaded The server's configuration reloaded

None of these events receive any data, except config-reloaded. This receives an event object with the parameters 'filename', 'format' and 'config' (the parsed config). This event is also used to reopen log files.

User sessions

Among the first things a client must do when connecting is authenticate. Once that is completed, prosody fires:

  authentication-success

Or, if the authentication attempt failed:

  authentication-failure

After authentication a client binds a resource, which is a unique identifier for that connection. This is the best way to know when a user has logged in or out (but they won't have sent presence or anything else yet).

On allocating a resource to a new session, Prosody fires:

  resource-bind

and when a session disconnects (gracefully or not):

  resource-unbind

The session will be destroyed shortly after.

All of these events receive an event object with a 'session' field containing the session in question. Additionally, resource-unbind's event object has an 'error' field (that may be nil), with a human-readable message describing why the user is disconnecting, and authentication-failure has 'condition' containing the error code and 'text' with a human-readable message.

Stanzas

Stanza events are composed of the name and the destination JID type. For example "message/bare". Names may be one of "message", "presence", "iq" - JID type may be "bare", "full", "host", or "self".

All of them receive an event object with two fields, 'origin' and 'stanza'. The origin is the session object that the stanza originated from (either the local user session, an s2s session, or a local host or component). The stanza is a stanza object.

To reply to a stanza you can use module:send(), or event.origin.send(). There are two helpers in util.stanza for building responses, util.stanza.reply() and util.stanza.error_reply().

Pre-routing

To handle messages received from local clients, whether they are destined for a local or remote JID, use the pre-routing family of events. They are of the form:

  pre-NAME/DEST

Where NAME is one of 'message', 'presence' or 'iq'. DEST is the type of the destination JID, and may be 'full' (destination JID has a resource), 'bare' (destination JID has no resource) or 'host' (destination JID is a host, such as "example.com").

Return true from your handler to block the outgoing stanza.

Post-routing

For stanzas that have been routed, these events are fired before delivery to the local entity (client, component or host) they are addressed to. The event is fired on the host in the JID it is addressed to. The event is simply of the form:

 NAME/DEST

Again, NAME may be 'message', 'presence' or 'iq', and DEST one of 'full', 'bare' or 'host'. Return true from your handler to prevent delivery of the stanza.

iq stanzas

If NAME is iq and DEST is one of 'bare' or 'host', there are also some additional events fired if nothing handled the above generic one:

  iq/DEST/XMLNS:TAG

If still not handled then TYPE is set to the 'type' attribute of the stanza. This may be 'get'/'set' or 'result'/'error'. If either 'get' or 'set', this event is fired:

  iq-TYPE/DEST/XMLNS:TAG

If the iq is of TYPE 'result' or 'error' then the ID is fetched from the 'id' attribute, and this event is fired:

  iq-TYPE/DEST/ID

Priorities

To ensure that modules handle stanzas in the correct order, some guidance is provided below on what priorities should be used for post-routing event handlers.

Priority range

Purpose

-1

Delivery to the session only

0

"Read-only" stanza interception, for stanzas that are going to be delivered, e.g. for archiving. Do not modify or drop the stanza in priority 0 handlers.

1 - 999

For general processing modules that may modify or drop stanzas

1000+

Pre-processing filters, typically used to drop stanzas before they are seen by most modules.

Self-addressed

XMPP has certain self-addressed stanzas, either the 'to' JID is the user's own bare JID or there is no 'to' on the stanza at all (they are equivalent). Prosody removes the 'to' attribute from these stanzas for consistency, and then fires a /self event:

 NAME/self

The NAME is one of the stanza types, and /self remains constant. Because these events never fire for stanzas from other users, they may be used to implement private per-user functionality such as account management.

If the stanza is an 'iq' stanza, the iq-specific events described above are also fired (with DEST 'self').

Initial presence

When a client changes its presence, 'presence/bare' (and 'presence/self') are fired. If the session was unavailable (seen as offline) before sending a normal available presence, a special event is fired:

  presence/initial
  

This normally happens when the client is done with the login, resource binding and other startup things.

Other stanzas and stream elements

These are stanzas which either come on unauthenticated connections, or are not actually stanzas (not under the jabber:client namespace), such as stream feature negotiations.

Stanzas for remote hosts

  route/remote

Stanzas addressed to remote servers are passed through this event.

Unauthenticated IQ stanzas

IQ stanzas received from connections that have not yet authenticated fire:

  stanza/iq/XMLNS:TAG

Here XMLNS is the namespace of the iq's child element, and TAG is the name of that element.

Other unauthenticated stanzas

  stanza/KIND

Where KIND may be 'message' or 'presence'.

Non-stanzas

Technically anything other than 'message', 'presence' or 'iq' is not a stanza. However these other elements fire an event prefixed with 'stanza/' for consistency:

  stanza/XMLNS:TAG

Where XMLNS is the namespace and TAG is the name of the element. These elements are typically stream feature negotiations such as TLS, SASL or compression.

Components

These events are fired by mod_component for external components, and can be used for tracking whether a component is online/offline. They are fired on the component's host, so you need to load your module explicitly onto that host to receive these events.

Event name Fields Description
component-authenticated session Fired on a component host when an external component has successfully authenticated (and therefore assumed control of its domain).
component-disconnected session, err A component has disconnected.