Skip to content

Instantly share code, notes, and snippets.

@weiss
Created August 15, 2017 11:55
Show Gist options
  • Save weiss/e6a42fa13b7d348560e95df16d66d86f to your computer and use it in GitHub Desktop.
Save weiss/e6a42fa13b7d348560e95df16d66d86f to your computer and use it in GitHub Desktop.
PEP notifications in ejabberd

XEP-compliant PEP notifications in ejabberd

We need:

  • A new sm_presence_in hook to track the presence of contacts from ejabberd_sm. The existing caps_add and caps_update hooks could be removed.

  • A global table (distributed across the cluster) that maps the FullJID of an online contact to (1) that contact's CAPS and (2) the set of local BareJIDs 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.

On available presence

  • Check whether the presence stanza includes CAPS. If not, we're DONE.

  • Check whether FromJID is presence-subscribed to ToJID. If not, we're DONE.

  • Check whether FromJID exists in the contact_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 in caps_features.

    • If we don't have the features, query them and call mod_pubsub:send_last(ToJID, FromJID, CAPS) from the Fun handed over to ejabberd_local:route_iq(IQ, Fun).

    • If we have the features, call mod_pubsub:send_last(ToJID, FromJID, CAPS) directly.

On unavailable presence

  • Remove FromJID from the contact_session table.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment