Software / code / 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 |
| 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 |