mod_presence: Fix a comment
[prosody.git] / plugins / mod_message.lua
1
2 local full_sessions = full_sessions;
3 local bare_sessions = bare_sessions;
4
5 local jid_bare = require "util.jid".bare;
6 local user_exists = require "core.usermanager".user_exists;
7 local offlinemanager = require "core.offlinemanager";
8
9 local function select_top_resources(user)
10         local priority = 0;
11         local recipients = {};
12         for _, session in pairs(user.sessions) do -- find resource with greatest priority
13                 if session.presence then
14                         -- TODO check active privacy list for session
15                         local p = session.priority;
16                         if p > priority then
17                                 priority = p;
18                                 recipients = {session};
19                         elseif p == priority then
20                                 t_insert(recipients, session);
21                         end
22                 end
23         end
24         return recipients;
25 end
26
27 local function process_to_bare(bare, origin, stanza)
28         local user = bare_sessions[bare];
29         
30         local t = stanza.attr.type;
31         if t == "error" then
32                 -- discard
33         elseif t == "groupchat" then
34                 origin.send(st.error_reply(stanza, "cancel", "service-unavailable"));
35         elseif t == "headline" then
36                 if user then
37                         for _, session in pairs(user.sessions) do
38                                 if session.presence and session.priority >= 0 then
39                                         session.send(stanza);
40                                 end
41                         end
42                 end  -- current policy is to discard headlines if no recipient is available
43         else -- chat or normal message
44                 if user then -- some resources are connected
45                         local recipients = select_top_resources(user);
46                         if #recipients > 0 then
47                                 for i=1,#recipients do
48                                         recipients[i].send(stanza);
49                                 end
50                                 return true;
51                         end
52                 end
53                 -- no resources are online
54                 local node, host = jid_split(bare);
55                 if user_exists(node, host) then
56                         -- TODO apply the default privacy list
57                         offlinemanager.store(node, host, stanza);
58                 else
59                         origin.send(st.error_reply(stanza, "cancel", "service-unavailable"));
60                 end
61         end
62         return true;
63 end
64
65 module:hook("message/full", function(data)
66         -- message to full JID recieved
67         local origin, stanza = data.origin, data.stanza;
68         
69         local session = full_sessions[stanza.attr.to];
70         if session then
71                 -- TODO fire post processing event
72                 session.send(stanza);
73                 return true;
74         else -- resource not online
75                 return process_to_bare(jid_bare(stanza.attr.to), origin, stanza);
76         end
77 end);
78
79 module:hook("message/bare", function(data)
80         -- message to bare JID recieved
81         local origin, stanza = data.origin, data.stanza;
82
83         return process_to_bare(stanza.attr.to or (origin.username..'@'..origin.host), origin, stanza);
84 end);