1 |
|
%%%------------------------------------------------------------------- |
2 |
|
%%% @author Dominik Stanaszek dominik.stanaszek@erlang-solutions.com |
3 |
|
%%% @copyright (C) 2018, Erlang-Solutions |
4 |
|
%%% @doc |
5 |
|
%%% |
6 |
|
%%% @end |
7 |
|
%%% Created : 6.07.2018 |
8 |
|
%%%------------------------------------------------------------------- |
9 |
|
-module(mod_inbox_muc). |
10 |
|
-author("dominik.stanaszek@erlang-solutions.com"). |
11 |
|
-include("jlib.hrl"). |
12 |
|
-include("mongoose.hrl"). |
13 |
|
|
14 |
|
-export([update_inbox_for_muc/3, start/1, stop/1]). |
15 |
|
|
16 |
|
%% User jid example is "alice@localhost" |
17 |
|
-type user_jid() :: jid:jid(). |
18 |
|
-type receiver_bare_user_jid() :: user_jid(). |
19 |
|
-type room_bare_jid() :: jid:jid(). |
20 |
|
-type packet() :: exml:element(). |
21 |
|
|
22 |
|
start(HostType) -> |
23 |
6 |
gen_hook:add_handlers(hooks(HostType)), |
24 |
|
% TODO check options: if system messages stored -> |
25 |
|
% add hook handler for system messages on hook ie. invitation_sent |
26 |
6 |
ok. |
27 |
|
|
28 |
|
stop(HostType) -> |
29 |
56 |
gen_hook:delete_handlers(hooks(HostType)), |
30 |
56 |
ok. |
31 |
|
|
32 |
|
hooks(HostType) -> |
33 |
62 |
[{update_inbox_for_muc, HostType, fun ?MODULE:update_inbox_for_muc/3, #{}, 90}]. |
34 |
|
|
35 |
|
-spec update_inbox_for_muc(Acc, Params, Extra) -> {ok, Acc} when |
36 |
|
Acc :: mod_muc_room:update_inbox_for_muc_payload(), |
37 |
|
Params :: map(), |
38 |
|
Extra :: gen_hook:extra(). |
39 |
|
update_inbox_for_muc( |
40 |
|
#{host_type := HostType, |
41 |
|
room_jid := Room, |
42 |
|
from_jid := From, |
43 |
|
from_room_jid := FromRoomJid, |
44 |
|
packet := Packet, |
45 |
|
affiliations_map := AffsMap} = Acc, _, _) -> |
46 |
18 |
F = fun(AffLJID, Affiliation) -> |
47 |
52 |
case is_allowed_affiliation(Affiliation) of |
48 |
|
true -> |
49 |
52 |
To = jid:to_bare(jid:make(AffLJID)), |
50 |
|
%% Guess direction based on user JIDs |
51 |
52 |
Direction = direction(From, To), |
52 |
52 |
Packet2 = jlib:replace_from_to(FromRoomJid, To, Packet), |
53 |
52 |
update_inbox_for_user(HostType, Direction, Room, To, Packet2); |
54 |
|
false -> |
55 |
:-( |
ok |
56 |
|
end |
57 |
|
end, |
58 |
18 |
mongoose_lib:maps_foreach(F, AffsMap), |
59 |
18 |
{ok, Acc}. |
60 |
|
|
61 |
|
-spec is_allowed_affiliation(mod_muc:affiliation()) -> boolean(). |
62 |
:-( |
is_allowed_affiliation(outcast) -> false; |
63 |
52 |
is_allowed_affiliation(_) -> true. |
64 |
|
|
65 |
|
-spec update_inbox_for_user(HostType, Direction, Room, To, Packet) -> term() when |
66 |
|
HostType :: mongooseim:host_type(), |
67 |
|
Direction :: incoming | outgoing, |
68 |
|
Room :: room_bare_jid(), |
69 |
|
To :: receiver_bare_user_jid(), |
70 |
|
Packet :: packet(). |
71 |
|
update_inbox_for_user(HostType, Direction, Room, To, Packet) -> |
72 |
52 |
ReceiverDomain = To#jid.lserver, |
73 |
52 |
MucDomain = mod_muc:server_host_to_muc_host(HostType, ReceiverDomain), |
74 |
52 |
case Room#jid.lserver of |
75 |
|
MucDomain -> |
76 |
52 |
handle_message(HostType, Room, To, Packet, Direction); |
77 |
|
_ -> |
78 |
|
%% We ignore inbox for users on the remote (s2s) hosts |
79 |
|
%% We ignore inbox for components (also known as services or bots) |
80 |
:-( |
ok |
81 |
|
end. |
82 |
|
|
83 |
|
handle_message(HostType, Room, To, Packet, outgoing) -> |
84 |
18 |
handle_outgoing_message(HostType, Room, To, Packet); |
85 |
|
handle_message(HostType, Room, To, Packet, incoming) -> |
86 |
34 |
handle_incoming_message(HostType, Room, To, Packet). |
87 |
|
|
88 |
|
-spec direction(From :: user_jid(), To :: user_jid()) -> incoming | outgoing. |
89 |
|
direction(From, To) -> |
90 |
52 |
case jid:are_bare_equal(From, To) of |
91 |
18 |
true -> outgoing; |
92 |
34 |
false -> incoming |
93 |
|
end. |
94 |
|
|
95 |
|
%% Sender and receiver is the same user |
96 |
|
-spec handle_outgoing_message(HostType, Room, To, Packet) -> term() when |
97 |
|
HostType :: mongooseim:host_type(), |
98 |
|
Room :: room_bare_jid(), |
99 |
|
To :: receiver_bare_user_jid(), |
100 |
|
Packet :: packet(). |
101 |
|
handle_outgoing_message(HostType, Room, To, Packet) -> |
102 |
18 |
Acc = mongoose_acc:new(#{location => ?LOCATION, lserver => To#jid.lserver, host_type => HostType}), |
103 |
18 |
maybe_reset_unread_count(HostType, To, Room, Packet, Acc), |
104 |
18 |
maybe_write_to_inbox(HostType, To, Room, Packet, Acc, fun write_to_sender_inbox/5). |
105 |
|
|
106 |
|
-spec handle_incoming_message(HostType, Room, To, Packet) -> term() when |
107 |
|
HostType :: mongooseim:host_type(), |
108 |
|
Room :: room_bare_jid(), |
109 |
|
To :: receiver_bare_user_jid(), |
110 |
|
Packet :: packet(). |
111 |
|
handle_incoming_message(HostType, Room, To, Packet) -> |
112 |
34 |
Acc = mongoose_acc:new(#{location => ?LOCATION, lserver => To#jid.lserver, host_type => HostType}), |
113 |
34 |
maybe_write_to_inbox(HostType, Room, To, Packet, Acc, fun write_to_receiver_inbox/5). |
114 |
|
|
115 |
|
maybe_reset_unread_count(HostType, User, Room, Packet, Acc) -> |
116 |
18 |
mod_inbox_utils:maybe_reset_unread_count(HostType, User, Room, Packet, Acc). |
117 |
|
|
118 |
|
maybe_write_to_inbox(HostType, User, Remote, Packet, Acc, WriteF) -> |
119 |
52 |
mod_inbox_utils:maybe_write_to_inbox(HostType, User, Remote, Packet, Acc, WriteF). |
120 |
|
|
121 |
|
write_to_sender_inbox(Server, User, Remote, Packet, Acc) -> |
122 |
14 |
mod_inbox_utils:write_to_sender_inbox(Server, User, Remote, Packet, Acc). |
123 |
|
|
124 |
|
write_to_receiver_inbox(Server, User, Remote, Packet, Acc) -> |
125 |
26 |
mod_inbox_utils:write_to_receiver_inbox(Server, User, Remote, Packet, Acc). |