Comparison

mod_offline_email/mod_offline_email.lua @ 0:010452cfaf53

mod_offline_email: Initial commit
author Matthew Wild <mwild1@gmail.com>
date Sat, 22 Aug 2009 01:14:51 +0100
child 1285:f1a0a0754b87
comparison
equal deleted inserted replaced
-1:000000000000 0:010452cfaf53
1
2 local full_sessions = full_sessions;
3 local bare_sessions = bare_sessions;
4
5 local st = require "util.stanza";
6 local jid_bare = require "util.jid".bare;
7 local jid_split = require "util.jid".split;
8 local user_exists = require "core.usermanager".user_exists;
9 local urlencode = require "net.http".urlencode;
10 local add_task = require "util.timer".add_task;
11 local os_time = os.time;
12 local t_concat = table.concat;
13 local smtp = require "socket.smtp";
14
15 local smtp_server = module:get_option("smtp_server");
16 local smtp_user = module:get_option("smtp_username");
17 local smtp_pass = module:get_option("smtp_password");
18
19 local smtp_address = module:get_option("smtp_from") or ((smtp_user or "xmpp").."@"..(smtp_server or module.host));
20
21 local queue_offline_emails = module:get_option("queue_offline_emails");
22 if queue_offline_emails == true then queue_offline_emails = 300; end
23
24 local send_message_as_email;
25 local message_body_from_stanza;
26
27 function process_to_bare(bare, origin, stanza)
28 local user = bare_sessions[bare];
29
30 local t = stanza.attr.type;
31 if t == nil or t == "chat" or t == "normal" then -- chat or normal message
32 if not (user and user.top_resources) then -- No resources online?
33 if user_exists(jid_split(bare)) then
34 local text = message_body_from_stanza(stanza);
35 if text then
36 send_message_as_email(bare, jid_bare(stanza.attr.from), text);
37 else
38 module:log("error", "Unable to extract message body from offline message to put into an email");
39 end
40 end
41 end
42 end
43 return; -- Leave for further processing
44 end
45
46
47 module:hook("message/full", function(data)
48 -- message to full JID recieved
49 local origin, stanza = data.origin, data.stanza;
50
51 local session = full_sessions[stanza.attr.to];
52 if not session then -- resource not online
53 return process_to_bare(jid_bare(stanza.attr.to), origin, stanza);
54 end
55 end, 20);
56
57 module:hook("message/bare", function(data)
58 -- message to bare JID recieved
59 local origin, stanza = data.origin, data.stanza;
60
61 return process_to_bare(stanza.attr.to or (origin.username..'@'..origin.host), origin, stanza);
62 end, 20);
63
64 function send_message_as_email(address, from_address, message_text, subject)
65 module:log("info", "Forwarding offline message to %s via email", address);
66 local rcpt = "<"..address..">";
67 local from_user, from_domain = jid_split(from_address);
68 local from = "<"..urlencode(from_user).."@"..from_domain..">";
69
70 local mesgt = {
71 headers = {
72 to = address;
73 subject = subject or ("Offline message from "..jid_bare(from_address));
74 };
75 body = message_text;
76 };
77
78 local ok, err = smtp.send{ from = from, rcpt = rcpt, source = smtp.message(mesgt),
79 server = smtp_server, user = smtp_user, password = smtp_pass };
80 if not ok then
81 module:log("error", "Failed to deliver to %s: %s", tostring(address), tostring(err));
82 return false;
83 end
84 return true;
85 end
86
87 if queue_offline_emails then
88 local queues = {};
89 local real_send_message_as_email = send_message_as_email;
90 function send_message_as_email(address, from_address, message_text)
91 local pair_key = address.."\0"..from_address;
92 local queue = queues[pair_key];
93 if not queue then
94 queue = { from = from_address, to = address, messages = {} };
95 queues[pair_key] = queue;
96
97 add_task(queue_offline_emails+5, function ()
98 module:log("info", "Checking on %s", from_address);
99 local current_time = os_time();
100 local diff = current_time - queue.last_message_time;
101 if diff > queue_offline_emails then
102 module:log("info", "Enough silence, sending...");
103 real_send_message_as_email(address, from_address, t_concat(queue.messages, "\n"), "You have "..#queue.messages.." offline message"..(#queue.messages == 1 and "" or "s").." from "..from_address)
104 else
105 module:log("info", "Next check in %d", queue_offline_emails - diff + 5);
106 return queue_offline_emails - diff + 5;
107 end
108 end);
109 end
110
111 queue.last_message_time = os_time();
112
113 local messages = queue.messages;
114 messages[#messages+1] = message_text;
115 end
116 end
117
118 function message_body_from_stanza(stanza)
119 local message_text = stanza:child_with_name("body");
120 if message_text then
121 return message_text:get_text();
122 end
123 end