Files
vnctalk-prosody/vnctalk/mod_vnc_remotemucstore.lua

167 lines
6.9 KiB
Lua

-- Prosody IM
-- Copyright (C) 2008-2017 Matthew Wild
-- Copyright (C) 2008-2017 Waqas Hussain
-- Copyright (C) 2011-2017 Kim Alvefur
-- Copyright (C) 2011-2017 Stefan Sänger
--
-- This project is MIT/X11 licensed. Please see the
-- COPYING file in the source package for more information.
--
-- store groupchat messages from / to remote hosts based on mod_mam
--
local um = require "core.usermanager";
local st = require "util.stanza";
local rsm = require "util.rsm";
local jid_bare = require "util.jid".bare;
local jid_split = require "util.jid".split;
local jid_prepped_split = require "util.jid".prepped_split;
local host = module.host;
module:log("running on host: %s", host);
local archive_store = "muc_remote";
local archive = module:open_store(archive_store, "archive");
local mr_store = module:open_store("muc_remote", "map");
local time_now = os.time;
local m_min = math.min;
local timestamp, timestamp_parse = require "util.datetime".datetime, require "util.datetime".parse;
local function dumpTable(t, depth)
local result = "";
if (not depth) then depth = 0 end;
local prefix = string.rep(" ", depth);
if (type(t) ~= "table") then
result = result.." "..tostring(t);
else
for key,value in pairs(t) do
result = result..prefix..tostring(key).." => "..dumpTable(value, depth+1).."\n"
end
end
return result;
end
local function presence_handler(event,c2s)
local origin, stanza = event.origin, event.stanza;
local muc_child = (stanza:get_child("x", "http://jabber.org/protocol/muc#user") or nil);
local item_child = nil;
local presence_type = (stanza.attr.type or nil);
local from_node, from_host, from_res = jid_split(stanza.attr.from);
local to_node, to_host = jid_split(stanza.attr.to);
if not (prosody.hosts[from_host]) then
if (muc_child and not(presence_type)) then
item_child = muc_child:get_child("item");
if (item_child) then
-- module:log("info", "got muc presence from: %s - to: %s, jid: %s || raw: %s", stanza.attr.from, stanza.attr.to, jid_bare(item_child.attr.jid), tostring(stanza));
if (item_child.attr.jid) then
local fjid = stanza.attr.from;
if (stanza.attr.from == jid_bare(stanza.attr.from)) then
fjid = stanza.attr.from .. "/" .. jid_bare(item_child.attr.jid);
end
-- module:log("info", "got item... from= %s item.attr.jid= %s", fjid, jid_bare(item_child.attr.jid));
mr_store:set(to_node, fjid, jid_bare(item_child.attr.jid));
end
if (from_res) then
mr_store:set(to_node,stanza.attr.from, from_res);
-- module:log("info", "got muc presence from_res: %s - to: %s, jid: %s || raw: %s", stanza.attr.from, stanza.attr.to, from_res, tostring(stanza));
end
end
-- mr_store:set(to_node,stanza.attr.from, );
end
end
end
-- Handle messages
local function message_handler(event, c2s)
local origin, stanza = event.origin, event.stanza;
if stanza.attr.type == "groupchat" then
local from_node, from_host, from_res = jid_split(stanza.attr.from);
local remote_muc = from_node.."@"..from_host;
local to_node, to_host, to_res = jid_split(stanza.attr.to);
-- module:log("info", "seen from_host: %s", from_host);
-- module:log("info", "seen to_res: %s", to_res);
if prosody.hosts[from_host] then
-- message is from a local host, no further action required
module:log("debug", "seen stanza from local host - from: %s", stanza.attr.from);
-- return nil;
else
-- message is from remote host, going to handle...
-- module:log("info", "seen stanza with muc %s@%s - raw: %s - to %s with type %s with id %s", from_node, from_host, stanza.attr.from, stanza.attr.to, stanza.attr.type, stanza.attr.id);
local mkey = stanza.attr.id;
local muc_with = from_node.."@"..from_host;
local content = (stanza and stanza:get_child("body") and stanza:get_child("body")[1] or nil)
-- module:log("info","got content: %s", content);
local delayedDelivery = stanza:get_child("delay", "urn:xmpp:delay");
if (delayedDelivery) then
-- module:log("info","got delay: %s", delayedDelivery);
end
local muc_subject = (stanza:get_child_text("subject") or nil);
if (muc_subject) then
-- module:log("info","subject for %s: %s", stanza.attr.from, muc_subject);
mr_store:set(to_node, remote_muc, muc_subject);
end
local nick = (stanza:get_child_text("nick", "http://jabber.org/protocol/nick") or nil);
local muc_child = (stanza:get_child("x", "http://jabber.org/protocol/muc#user") or nil);
local item_child = nil;
if (muc_child) then
-- module:log("info","got muc_child: %s", muc_child);
item_child = muc_child:get_child("item");
if (item_child and nick) then
-- module:log("info","got sender jid nick: %s: %s => %s", stanza.attr.from, nick, item_child.attr.jid);
mr_store:set(to_node,stanza.attr.from, item_child.attr.jid);
end
end
if (mkey and content and not(delayedDelivery)) then
-- module:log("info", "seen stanza with muc %s@%s - raw: %s - to %s with type %s with id %s", from_node, from_host, stanza.attr.from, stanza.attr.to, stanza.attr.type, stanza.attr.id);
-- module:log("info", "going to store - to: %s, conten: %s", to_node, content);
local storeok = archive:append(to_node, mkey, stanza, time_now(), muc_with);
-- prevent further processing for messages to offline user (to bare jid)
if (to_res == nil) then
-- module:log("info", "going prevent stanza processing to bare from muc - to: %s, conten: %s", to_node, content);
return true;
end
end
end
else
-- module:log("info","seen stanza.attr.type: %s", stanza.attr.type);
local from_node, from_host, from_res = jid_split(stanza.attr.from);
local to_node, to_host, to_res = jid_split(stanza.attr.to);
local muc_child = (stanza:get_child("x", "http://jabber.org/protocol/muc#user") or nil);
local invite_child = nil;
local invite_from = nil;
if (muc_child) then
invite_child = (muc_child:get_child("invite") or nil);
if (invite_child) then
module:log("info", "got invite_child: %s", dumpTable(invite_child));
invite_from = (invite_child.attr.from or nil);
if (invite_from) then
local invite_from_node, invite_from_host = jid_split(invite_from);
module:log("info","got invite from %s to muc %s for %s", invite_from_node.."@"..invite_from_host, stanza.attr.from, to_node.."@"..to_host );
local store_key = stanza.attr.from.."/"..invite_from_node.."@"..invite_from_host;
local store_value = invite_from_node.."@"..invite_from_host;
-- module:log("debug","storing: %s -> %s -> %s", to_node, stanza.attr.from.."/"..invite_from_node.."@"..invite_from_host, invite_from_node.."@"..invite_from_host);
mr_store:set(to_node, store_key, store_value);
else
module:log("info","found empty part - check %s", invite_from);
end
end
end
end
end
-- Stanzas to local clients
module:hook("message/bare", message_handler, 0);
module:hook("message/full", message_handler, 0);
module:hook("presence/full", presence_handler, 10);
module:hook("presence/bare", presence_handler, 10);