aboutsummaryrefslogtreecommitdiff
path: root/src/mod_client_state.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mod_client_state.erl')
-rw-r--r--src/mod_client_state.erl91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/mod_client_state.erl b/src/mod_client_state.erl
new file mode 100644
index 000000000..83363162d
--- /dev/null
+++ b/src/mod_client_state.erl
@@ -0,0 +1,91 @@
+%%%----------------------------------------------------------------------
+%%% File : mod_client_state.erl
+%%% Author : Holger Weiss
+%%% Purpose : Filter stanzas sent to inactive clients (XEP-0352)
+%%% Created : 11 Sep 2014 by Holger Weiss
+%%%
+%%%
+%%% ejabberd, Copyright (C) 2014 ProcessOne
+%%%
+%%% This program is free software; you can redistribute it and/or
+%%% modify it under the terms of the GNU General Public License as
+%%% published by the Free Software Foundation; either version 2 of the
+%%% License, or (at your option) any later version.
+%%%
+%%% This program is distributed in the hope that it will be useful,
+%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
+%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+%%% General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License along
+%%% with this program; if not, write to the Free Software Foundation, Inc.,
+%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+%%%
+%%%----------------------------------------------------------------------
+
+-module(mod_client_state).
+-author('holger@zedat.fu-berlin.de').
+
+-behavior(gen_mod).
+
+-export([start/2, stop/1, filter_presence/2, filter_chat_states/2]).
+
+-include("ejabberd.hrl").
+-include("logger.hrl").
+-include("jlib.hrl").
+
+start(Host, Opts) ->
+ QueuePresence = gen_mod:get_opt(queue_presence, Opts,
+ fun(true) -> true end, false),
+ DropChatStates = gen_mod:get_opt(drop_chat_states, Opts,
+ fun(true) -> true end, false),
+ if QueuePresence ->
+ ejabberd_hooks:add(csi_filter_stanza, Host, ?MODULE,
+ filter_presence, 50);
+ true -> ok
+ end,
+ if DropChatStates ->
+ ejabberd_hooks:add(csi_filter_stanza, Host, ?MODULE,
+ filter_chat_states, 50);
+ true -> ok
+ end,
+ ok.
+
+stop(Host) ->
+ ejabberd_hooks:delete(csi_filter_stanza, Host, ?MODULE,
+ filter_presence, 50),
+ ejabberd_hooks:delete(csi_filter_stanza, Host, ?MODULE,
+ filter_chat_states, 50),
+ ok.
+
+filter_presence(_Action, #xmlel{name = <<"presence">>, attrs = Attrs}) ->
+ case xml:get_attr(<<"type">>, Attrs) of
+ {value, Type} when Type /= <<"unavailable">> ->
+ ?DEBUG("Got important presence stanza", []),
+ {stop, send};
+ _ ->
+ ?DEBUG("Got availability presence stanza", []),
+ {stop, queue}
+ end;
+filter_presence(Action, _Stanza) -> Action.
+
+filter_chat_states(_Action, #xmlel{name = <<"message">>} = Stanza) ->
+ %% All XEP-0085 chat states except for <gone/>:
+ ChatStates = [<<"active">>, <<"inactive">>, <<"composing">>, <<"paused">>],
+ Stripped =
+ lists:foldl(fun(ChatState, AccStanza) ->
+ xml:remove_subtags(AccStanza, ChatState,
+ {<<"xmlns">>, ?NS_CHATSTATES})
+ end, Stanza, ChatStates),
+ case Stripped of
+ #xmlel{children = [#xmlel{name = <<"thread">>}]} ->
+ ?DEBUG("Got standalone chat state notification", []),
+ {stop, drop};
+ #xmlel{children = []} ->
+ ?DEBUG("Got standalone chat state notification", []),
+ {stop, drop};
+ _ ->
+ ?DEBUG("Got message with chat state notification", []),
+ {stop, send}
+ end;
+filter_chat_states(Action, _Stanza) -> Action.