1 |
|
%%============================================================================== |
2 |
|
%% Copyright 2016 Erlang Solutions Ltd. |
3 |
|
%% |
4 |
|
%% Licensed under the Apache License, Version 2.0 (the "License"); |
5 |
|
%% you may not use this file except in compliance with the License. |
6 |
|
%% You may obtain a copy of the License at |
7 |
|
%% |
8 |
|
%% http://www.apache.org/licenses/LICENSE-2.0 |
9 |
|
%% |
10 |
|
%% Unless required by applicable law or agreed to in writing, software |
11 |
|
%% distributed under the License is distributed on an "AS IS" BASIS, |
12 |
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 |
|
%% See the License for the specific language governing permissions and |
14 |
|
%% limitations under the License. |
15 |
|
%%============================================================================== |
16 |
|
|
17 |
|
-module(mod_event_pusher_hook_translator). |
18 |
|
-author('konrad.zemek@erlang-solutions.com'). |
19 |
|
|
20 |
|
-behaviour(gen_mod). |
21 |
|
-behaviour(mongoose_module_metrics). |
22 |
|
|
23 |
|
-include("jlib.hrl"). |
24 |
|
-include("mod_event_pusher_events.hrl"). |
25 |
|
|
26 |
|
-export([start/2, stop/1]). |
27 |
|
-export([user_send_packet/4, |
28 |
|
filter_local_packet/1, |
29 |
|
user_present/2, |
30 |
|
user_not_present/5, |
31 |
|
unacknowledged_message/2]). |
32 |
|
|
33 |
|
-ignore_xref([filter_local_packet/1, unacknowledged_message/2, user_not_present/5, |
34 |
|
user_present/2, user_send_packet/4]). |
35 |
|
|
36 |
|
%%-------------------------------------------------------------------- |
37 |
|
%% gen_mod API |
38 |
|
%%-------------------------------------------------------------------- |
39 |
|
|
40 |
|
-spec start(Host :: jid:server(), Opts :: proplists:proplist()) -> any(). |
41 |
|
start(Host, _Opts) -> |
42 |
26 |
ejabberd_hooks:add(hooks(Host)). |
43 |
|
|
44 |
|
-spec stop(Host :: jid:server()) -> ok. |
45 |
|
stop(Host) -> |
46 |
26 |
ejabberd_hooks:delete(hooks(Host)). |
47 |
|
|
48 |
|
%%-------------------------------------------------------------------- |
49 |
|
%% Hook callbacks |
50 |
|
%%-------------------------------------------------------------------- |
51 |
|
-type routing_data() :: {jid:jid(), jid:jid(), mongoose_acc:t(), exml:element()}. |
52 |
|
-spec filter_local_packet(drop) -> drop; |
53 |
|
(routing_data()) -> routing_data(). |
54 |
|
filter_local_packet(drop) -> |
55 |
:-( |
drop; |
56 |
|
filter_local_packet({From, To = #jid{lserver = Host}, Acc0, Packet}) -> |
57 |
1520 |
Acc = case chat_type(Acc0) of |
58 |
974 |
false -> Acc0; |
59 |
|
Type -> |
60 |
546 |
Event = #chat_event{type = Type, direction = out, |
61 |
|
from = From, to = To, packet = Packet}, |
62 |
546 |
NewAcc = mod_event_pusher:push_event(Acc0, Host, Event), |
63 |
501 |
merge_acc(Acc0, NewAcc) |
64 |
|
end, |
65 |
1475 |
{From, To, Acc, Packet}. |
66 |
|
|
67 |
|
-spec user_send_packet(mongoose_acc:t(), From :: jid:jid(), To :: jid:jid(), |
68 |
|
Packet :: exml:element()) -> mongoose_acc:t(). |
69 |
|
user_send_packet(Acc, From, To, Packet = #xmlel{name = <<"message">>}) -> |
70 |
108 |
case chat_type(Acc) of |
71 |
:-( |
false -> Acc; |
72 |
|
Type -> |
73 |
108 |
Event = #chat_event{type = Type, direction = in, |
74 |
|
from = From, to = To, packet = Packet}, |
75 |
108 |
NewAcc = mod_event_pusher:push_event(Acc, From#jid.lserver, Event), |
76 |
108 |
merge_acc(Acc, NewAcc) |
77 |
|
end; |
78 |
|
user_send_packet(Acc, _From, _To, _Packet) -> |
79 |
513 |
Acc. |
80 |
|
|
81 |
|
-spec user_present(mongoose_acc:t(), UserJID :: jid:jid()) -> mongoose_acc:t(). |
82 |
|
user_present(Acc, #jid{} = UserJID) -> |
83 |
232 |
Event = #user_status_event{jid = UserJID, status = online}, |
84 |
232 |
NewAcc = mod_event_pusher:push_event(Acc, UserJID#jid.lserver, Event), |
85 |
232 |
merge_acc(Acc, NewAcc). |
86 |
|
|
87 |
|
-spec user_not_present(mongoose_acc:t(), User :: jid:luser(), Server :: jid:lserver(), |
88 |
|
Resource :: jid:lresource(), Status :: any()) -> mongoose_acc:t(). |
89 |
|
user_not_present(Acc, LUser, LHost, LResource, _Status) -> |
90 |
232 |
UserJID = jid:make_noprep(LUser, LHost, LResource), |
91 |
232 |
Event = #user_status_event{jid = UserJID, status = offline}, |
92 |
232 |
NewAcc = mod_event_pusher:push_event(Acc, LHost, Event), |
93 |
232 |
merge_acc(Acc, NewAcc). |
94 |
|
|
95 |
|
unacknowledged_message(Acc, #jid{lserver = Server} = Jid) -> |
96 |
10 |
Event = #unack_msg_event{to = Jid}, |
97 |
10 |
NewAcc = mod_event_pusher:push_event(Acc, Server, Event), |
98 |
10 |
merge_acc(Acc, NewAcc). |
99 |
|
|
100 |
|
%%-------------------------------------------------------------------- |
101 |
|
%% Helpers |
102 |
|
%%-------------------------------------------------------------------- |
103 |
|
|
104 |
|
-spec chat_type(mongoose_acc:t()) -> chat | groupchat | headline | normal | false. |
105 |
|
chat_type(Acc) -> |
106 |
1628 |
case mongoose_acc:stanza_type(Acc) of |
107 |
158 |
<<"chat">> -> chat; |
108 |
224 |
<<"groupchat">> -> groupchat; |
109 |
:-( |
<<"headline">> -> headline; |
110 |
:-( |
<<"normal">> -> normal; |
111 |
272 |
undefined -> normal; |
112 |
974 |
_ -> false |
113 |
|
end. |
114 |
|
|
115 |
|
-spec merge_acc(mongoose_acc:t(), mongoose_acc:t()) -> mongoose_acc:t(). |
116 |
|
merge_acc(Acc, EventPusherAcc) -> |
117 |
1083 |
NS = mongoose_acc:get(event_pusher, EventPusherAcc), |
118 |
1083 |
mongoose_acc:set_permanent(event_pusher, NS, Acc). |
119 |
|
|
120 |
|
-spec hooks(Host :: jid:server()) -> [ejabberd_hooks:hook()]. |
121 |
|
hooks(Host) -> |
122 |
52 |
[ |
123 |
|
{filter_local_packet, Host, ?MODULE, filter_local_packet, 90}, |
124 |
|
{unset_presence_hook, Host, ?MODULE, user_not_present, 90}, |
125 |
|
{user_available_hook, Host, ?MODULE, user_present, 90}, |
126 |
|
{user_send_packet, Host, ?MODULE, user_send_packet, 90}, |
127 |
|
{rest_user_send_packet, Host, ?MODULE, user_send_packet, 90}, |
128 |
|
{unacknowledged_message, Host, ?MODULE, unacknowledged_message, 90} |
129 |
|
]. |