Mercurial > prosody-modules
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 |
parents | |
children | 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 |