Article - Talk ejabberd events and hooks
Return to ejabberd module development
Introduction
ejabberd provides an event mechanism. Each module can subscribe to events and a hook in the module code is called when the event occurs.
Example
The module mod_offline.erl is an example of how the events/hooks mechanism can be used.
API
ejabberd_hooks:add(Hook, Host, Module, Function, Priority)
ejabberd_hooks:remove(Hook, Host, Module, Function, Priority)
* Hook = atom()
* Host = string()
* Module = atom()
* Function = atom()
* Priority = integer()
- The Hook parameter is the name of the event (see below).
- The Host parameter is the name of the virtual host related to the event.
- The Module and Function parameters describe the hook to be called when the event occurs.
- The Priority parameter is the hook rank, to determine in which order the hooks are run (when several hooks are defined for the same event), use it if you have dependencies between hooks.
To stop ejabberd from calling other functions in that hook, your function must return the atom() stop. An another way to stop the call chain is to return tuple {stop, Val} to override the return value.
List of events
The list of available events, and the type of corresponding hooks, is described below.
Events
adhoc_local_items(Acc, From, To, Lang) -> Adhoc
adhoc_sm_items(Acc, From, To, Lang) -> Adhoc
c2s_stream_features(Acc)
c2s_unauthenticated_iq(Acc, Server, IQ) -> Adhoc
disco_local_features(Acc, From, To, Node, Lang) -> Adhoc
disco_local_identity(Acc, From, To, Node, Lang) -> Adhoc
disco_local_items(Acc, From, To, Node, Lang) -> Adhoc
disco_sm_features(Acc, From, To, Node, Lang) -> Adhoc
disco_sm_identity(Acc, From, To, Node, Lang) -> Adhoc
disco_sm_items(Acc, From, To, Node, Lang) -> Adhoc
ejabberd_ctl_process(Args) -> CtlStatus
filter_packet({From, To, Packet}) -> {From, To, Packet}
local_send_to_resource_hook(From, To, Packet) -> ok
offline_message_hook(From, To, Packet) -> ok
privacy_check_packet(Acc, User, Server, PrivacyList, {From, To, Packet}, Dir) -> Auth
privacy_get_user_list(Acc, User, Server) -> PrivacyList
privacy_iq_get(Acc, From, To, IQ) -> {result, Packet} | {error, Error}
privacy_iq_set(Acc, From, To, IQ) -> {result, Packet} | {error, Error}
privacy_updated_list(Acc, OldPrivacyList, NewPrivacyList) -> PrivacyList
pubsub_publish_item(From, To, Node, ItemID, Payload) -> ok
remove_user(User, Server) -> ok
resend_offline_messages_hook(Acc, User, Server) -> [Route]
resend_subscription_requests_hook(Acc, User, Server) -> [Packet]
roster_get(Acc, {User, Server}) -> [RosterItem]
roster_get_jid_info(Acc, User, Server, JID) -> {Subscription, Groups}
roster_get_subscription_lists(Acc, User, Server) -> {[FromSubscription], [ToSubscription]}
roster_in_subscription(User, Server, JID, SubscriptionType, Reason) -> bool()
roster_out_subscription(User, Server, JID, SubscriptionType) -> bool()
roster_process_item(RosterItem, Server) -> RosterItem
set_presence_hook(User, Server, Resource, Packet) -> none
sm_register_connection_hook(SID, JID) -> ok
sm_remove_connection_hook(SID, JID, SessionInfo) -> ok
unset_presence_hook(User, Server, Resource, Status) -> void()
user_available_hook(JID) -> ok
user_receive_packet(JID, From, To, Packet) -> ok
user_send_packet(From, To, Packet) -> ok
Types
To = From = JID = ServerJID = #jid (see jlib)
Packet = Payload = {xmlelement, Name, Attrs, SubEl}
IQ = #iq (see jlib)
Error = ?STANZA_ERROR/3 (see jlib.h)
Lang = string()
Dir = in | out
Auth = allow | deny
PrivacyList = OldPrivacyList = NewPrivacyList = none | #userlist
CtlStatus = false | ?STATUS_SUCCESS | ?STATUS_ERROR | ?STATUS_USAGE | ?STATUS_BADRPC (see ejabberd_ctl.hrl")
Adhoc = {result, I} | {error, Error} | empty
Arg = [string()]
Node = [string()]
ItemID = string()
Route = {route, From, To, Packet
RosterItem = #roster (see mod_roster.hrl)
Subscription = none | from | to | both | remove
SubscriptionType = subscribe | subscribed | unsubscribe | unsubscribed
Reason = string()
Groups = [string()]
SimpleJID = FromSubscription = ToSubscription = {User, Server, Resource}
User = string()
Server = string()
Resource = string()
Status = string()
SID = {Time, pid()}
Time = {MegaSecs, Secs, MicroSecs} (see erlang:now/0)
MegaSecs = Secs = MicroSecs = int()
Acc = same type as the return type of the function. Each module adds to the accumulator Acc their contribution
Event Details
adhoc_local_items(Acc, From, To, Lang) -> Adhoc
adhoc_sm_items(Acc, From, To, Lang) -> Adhoc
c2s_stream_features(Acc)
c2s_unauthenticated_iq(Acc, Server, IQ) -> Adhoc
disco_local_features(Acc, From, To, Node, Lang) -> Adhoc
disco_local_identity(Acc, From, To, Node, Lang) -> Adhoc
This hook is related to XEP-0030
disco_local_items(Acc, From, To, Node, Lang)
This hook is related to XEP-0030
disco_sm_features(Acc, From, To, Node, Lang) -> Adhoc
disco_sm_identity(Acc, From, To, Node, Lang) -> Adhoc
disco_sm_items(Acc, From, To, Node, Lang) -> Adhoc
ejabberd_ctl_process(Args) -> CtlStatus
filter_packet({From, To, Packet}) -> {From, To, Packet}
local_send_to_resource_hook(From, To, Packet)
offline_message_hook(From, To, Packet)
Triggered when a message is sent to an offline user. The ejabberd session manager adds a default function to the offline_message_hook chain that bounces the incoming message with a service unavailable error. This hook is added at the lowest priority so that it executes after anything else in the chain.
privacy_check_packet(Acc, User, Server, PrivacyList, {From, To, Packet}, Dir) -> Auth
privacy_get_user_list(Acc, User, Server) -> PrivacyList
privacy_iq_get(Acc, From, To, IQ) -> {result, Packet} | {error, Error}
privacy_iq_set(Acc, From, To, IQ) -> {result, Packet} | {error, Error}
privacy_updated_list(Acc, OldPrivacyList, NewPrivacyList) -> PrivacyList
pubsub_publish_item(From, To, Node, ItemID, Payload) -> ok
remove_user(User, Server) -> ok
resend_offline_messages_hook(Acc, User, Server) -> [Route]
resend_subscription_requests_hook(Acc, User, Server) -> [Packet]
roster_get(Acc, {User, Server}) -> [RosterItem]
roster_get_jid_info(Acc, User, Server, JID) -> {Subscription, Groups}
roster_get_subscription_lists(Acc, User, Server) -> {[FromSubscription], [ToSubscription]}
roster_in_subscription(User, Server, JID, SubscriptionType, Reason) -> bool()
roster_out_subscription(User, Server, JID, SubscriptionType) -> bool()
roster_process_item(RosterItem, Server) -> RosterItem
set_presence_hook(User, Server, Resource, Priority)
This hook is processed whenever a connected user sends a presence stanza to the server.
