Trigger PEP notifications on CAPS updates

Let mod_pubsub send last items whenever a contact updates the entity
capabilities.  This was already done for remote contacts and is now also
done for local contacts.
This commit is contained in:
Holger Weiss 2015-07-07 00:24:06 +02:00
parent edb18deb8f
commit 0f96414279
2 changed files with 33 additions and 29 deletions

View File

@ -243,27 +243,24 @@ c2s_presence_in(C2SState,
error -> gb_trees:empty()
end,
Caps = read_caps(Els),
{CapsUpdated, NewRs} = case Caps of
nothing when Insert == true -> {false, Rs};
_ when Insert == true ->
case gb_trees:lookup(LFrom, Rs) of
{value, Caps} -> {false, Rs};
none ->
{true,
gb_trees:insert(LFrom, Caps,
Rs)};
_ ->
{true,
gb_trees:update(LFrom, Caps, Rs)}
end;
_ -> {false, gb_trees:delete_any(LFrom, Rs)}
end,
if CapsUpdated ->
ejabberd_hooks:run(caps_update, To#jid.lserver,
[From, To,
get_features(To#jid.lserver, Caps)]);
true -> ok
end,
NewRs = case Caps of
nothing when Insert == true -> Rs;
_ when Insert == true ->
case gb_trees:lookup(LFrom, Rs) of
{value, Caps} -> Rs;
none ->
ejabberd_hooks:run(caps_add, To#jid.lserver,
[From, To,
get_features(To#jid.lserver, Caps)]),
gb_trees:insert(LFrom, Caps, Rs);
_ ->
ejabberd_hooks:run(caps_update, To#jid.lserver,
[From, To,
get_features(To#jid.lserver, Caps)]),
gb_trees:update(LFrom, Caps, Rs)
end;
_ -> gb_trees:delete_any(LFrom, Rs)
end,
ejabberd_c2s:set_aux_field(caps_resources, NewRs,
C2SState);
true -> C2SState

View File

@ -62,7 +62,7 @@
-define(PEPNODE, <<"pep">>).
%% exports for hooks
-export([presence_probe/3, caps_update/3,
-export([presence_probe/3, caps_add/3, caps_update/3,
in_subscription/6, out_subscription/4,
on_user_offline/3, remove_user/2,
disco_local_identity/5, disco_local_features/5,
@ -293,6 +293,8 @@ init([ServerHost, Opts]) ->
?MODULE, remove_user, 50),
case lists:member(?PEPNODE, Plugins) of
true ->
ejabberd_hooks:add(caps_add, ServerHost,
?MODULE, caps_add, 80),
ejabberd_hooks:add(caps_update, ServerHost,
?MODULE, caps_update, 80),
ejabberd_hooks:add(disco_sm_identity, ServerHost,
@ -683,21 +685,24 @@ disco_items(Host, Node, From) ->
%% presence hooks handling functions
%%
caps_update(#jid{luser = U, lserver = S, lresource = R}, #jid{lserver = Host} = JID, _Features)
caps_add(#jid{luser = U, lserver = S, lresource = R}, #jid{lserver = Host} = JID, _Features)
when Host =/= S ->
%% When a remote contact goes online while the local user is offline, the
%% remote contact won't receive last items from the local user even if
%% ignore_pep_from_offline is set to false. To work around this issue a bit,
%% we'll also send the last items to remote contacts when the local user
%% connects. That's the reason to use the caps_update hook instead of the
%% connects. That's the reason to use the caps_add hook instead of the
%% presence_probe_hook for remote contacts: The latter is only called when a
%% contact becomes available; the former also is also executed when the
%% local user goes online (because that triggers the contact to send a
%% presence packet with CAPS).
%% contact becomes available; the former is also executed when the local
%% user goes online (because that triggers the contact to send a presence
%% packet with CAPS).
presence(Host, {presence, U, S, [R], JID});
caps_update(_From, _To, _Feature) ->
caps_add(_From, _To, _Feature) ->
ok.
caps_update(#jid{luser = U, lserver = S, lresource = R}, #jid{lserver = Host} = JID, _Features) ->
presence(Host, {presence, U, S, [R], JID}).
presence_probe(#jid{luser = U, lserver = S, lresource = R} = JID, JID, Pid) ->
presence(S, {presence, JID, Pid}),
presence(S, {presence, U, S, [R], JID});
@ -709,7 +714,7 @@ presence_probe(#jid{luser = U, lserver = S, lresource = R}, #jid{lserver = S} =
presence(S, {presence, U, S, [R], JID});
presence_probe(_Host, _JID, _Pid) ->
%% ignore presence_probe from remote contacts,
%% those are handled via caps_update
%% those are handled via caps_add
ok.
presence(ServerHost, Presence) ->
@ -881,6 +886,8 @@ terminate(_Reason,
ejabberd_router:unregister_route(Host),
case lists:member(?PEPNODE, Plugins) of
true ->
ejabberd_hooks:delete(caps_add, ServerHost,
?MODULE, caps_add, 80),
ejabberd_hooks:delete(caps_update, ServerHost,
?MODULE, caps_update, 80),
ejabberd_hooks:delete(disco_sm_identity, ServerHost,