We need:
-
A new
sm_presence_in
hook to track the presence of contacts fromejabberd_sm
. The existingcaps_add
andcaps_update
hooks could be removed. -
A global table (distributed across the cluster) that maps the
FullJID
of an online contact to (1) that contact'sCAPS
and (2) the set of localBareJIDs
that received available presence for the contact's current online session. E.g.:#contact_session{ caps :: caps(), peers :: gb_sets:set({binary(), binary()}) % {LUser, LServer} }
This could be done using
ets_cache
.
-
Check whether the presence stanza includes CAPS. If not, we're DONE.
-
Check whether
FromJID
is presence-subscribed toToJID
. If not, we're DONE. -
Check whether
FromJID
exists in thecontact_session
table.-
If it DOESN'T, store this record:
#jid{luser = U, lserver = S} = ToJID, NewSet = gb_sets:from_list([{U, S}]), #contact_session{ caps = CAPS, peers = NewSet }
-
If it DOES, check whether
ToJID
is in the#caps.peers
set. If it is, we're DONE (as this wasn't the initial available presence). Otherwise:
-
-
Check for the
CAPS
incaps_features
.-
If we don't have the features, query them and call
mod_pubsub:send_last(ToJID, FromJID, CAPS)
from theFun
handed over toejabberd_local:route_iq(IQ, Fun)
. -
If we have the features, call
mod_pubsub:send_last(ToJID, FromJID, CAPS)
directly.
-
- Remove FromJID from the
contact_session
table.