New hook: muc_filter_presence

Add a hook that allows for modifying or dropping presence stanzas sent
to MUC rooms.
This commit is contained in:
Holger Weiss 2015-08-04 20:13:00 +02:00
parent e3b7d43b76
commit 3d4e8ffac6
1 changed files with 118 additions and 110 deletions

View File

@ -1035,14 +1035,25 @@ get_participant_data(From, StateData) ->
end.
process_presence(From, Nick,
#xmlel{name = <<"presence">>, attrs = Attrs} = Packet,
#xmlel{name = <<"presence">>, attrs = Attrs0} = Packet0,
StateData) ->
Type = xml:get_attr_s(<<"type">>, Attrs),
Type0 = xml:get_attr_s(<<"type">>, Attrs0),
IsOnline = is_user_online(From, StateData),
if Type0 == <<"">>;
IsOnline and ((Type0 == <<"unavailable">>) or (Type0 == <<"error">>)) ->
case ejabberd_hooks:run_fold(muc_filter_presence,
StateData#state.server_host,
Packet0,
[StateData,
StateData#state.jid,
From, Nick]) of
drop ->
{next_state, normal_state, StateData};
#xmlel{attrs = Attrs} = Packet ->
Type = xml:get_attr_s(<<"xml:lang">>, Attrs),
Lang = xml:get_attr_s(<<"xml:lang">>, Attrs),
StateData1 = case Type of
<<"unavailable">> ->
case is_user_online(From, StateData) of
true ->
NewPacket = case
{(StateData#state.config)#config.allow_visitor_status,
is_visitor(From, StateData)}
@ -1065,21 +1076,16 @@ process_presence(From, Nick,
xml:get_tag_cdata(Status_el)
end,
remove_online_user(From, NewState, Reason);
_ -> StateData
end;
<<"error">> ->
case is_user_online(From, StateData) of
true ->
ErrorText =
<<"This participant is kicked from the "
"room because he sent an error presence">>,
expulse_participant(Packet, From, StateData,
translate:translate(Lang,
ErrorText));
_ -> StateData
end;
<<"">> ->
case is_user_online(From, StateData) of
if not IsOnline ->
add_new_user(From, Nick, Packet, StateData);
true ->
case is_nick_change(From, Nick, StateData) of
true ->
@ -1140,12 +1146,14 @@ process_presence(From, Nick,
StateData),
send_new_presence(From, NewState),
NewState
end;
_ -> add_new_user(From, Nick, Packet, StateData)
end;
_ -> StateData
end
end
end,
close_room_if_temporary_and_empty(StateData1).
close_room_if_temporary_and_empty(StateData1)
end;
true ->
{next_state, normal_state, StateData}
end.
close_room_if_temporary_and_empty(StateData1) ->
case not (StateData1#state.config)#config.persistent