Annotate

mod_offline_email/mod_offline_email.lua @ 692:2de21fa40382

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