changeset 1747:985e05ac833b

mod_mamsub: Experimental implementation of MAM subscriptions
author Kim Alvefur <zash@zash.se>
date Mon, 18 May 2015 03:27:08 +0200
parents 5734a6199938
children 0697fbef9134
files mod_mamsub/mod_mamsub.lua
diffstat 1 files changed, 63 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_mamsub/mod_mamsub.lua	Mon May 18 03:27:08 2015 +0200
@@ -0,0 +1,63 @@
+-- MAM Subscriptions prototype
+-- Copyright (C) 2015 Kim Alvefur
+--
+-- This file is MIT/X11 licensed.
+
+local mt = require"util.multitable";
+local st = require"util.stanza";
+
+local xmlns_mamsub = "http://prosody.im/protocol/mamsub";
+
+module:add_feature(xmlns_mamsub);
+
+local host_sessions = prosody.hosts[module.host].sessions;
+
+local weak = { __mode = "k" };
+
+module:hook("iq-set/self/"..xmlns_mamsub..":subscribe", function (event)
+	local origin, stanza = event.origin, event.stanza;
+	if origin.mamsub ~= nil then
+		origin.send(st.error_reply(stanza, "modify", "conflict"));
+		return true;
+	end
+	origin.mamsub = xmlns_mamsub;
+	local mamsub_sessions = host_sessions[origin.username].mamsub_sessions;
+	if not mamsub_sessions then
+		mamsub_sessions = setmetatable({}, weak);
+		host_sessions[origin.username].mamsub_sessions = mamsub_sessions;
+	end
+	mamsub_sessions[origin] = true;
+	origin.send(st.reply(stanza));
+	return true;
+end);
+
+module:hook("iq-set/self/"..xmlns_mamsub..":unsubscribe", function (event)
+	local origin, stanza = event.origin, event.stanza;
+	if origin.mamsub ~= xmlns_mamsub then
+		origin.send(st.error_reply(stanza, "modify", "conflict"));
+		return true;
+	end
+	origin.mamsub = nil;
+	local mamsub_sessions = host_sessions[origin.username].mamsub_sessions;
+	if mamsub_sessions then
+		mamsub_sessions[origin] = nil;
+	end
+	origin.send(st.reply(stanza));
+	return true;
+end);
+
+module:hook("archive-message-added", function (event)
+	local mamsub_sessions = host_sessions[event.for_user].mamsub_sessions;
+	if not mamsub_sessions then return end;
+
+	local for_broadcast = st.message():tag("mamsub", { xmlns = xmlns_mamsub })
+		:tag("forwarded", { xmlns = "urn:xmpp:forward:0" })
+			:add_child(event.stanza);
+
+	for session in pairs(mamsub_sessions) do
+		if session.mamsub == xmlns_mamsub then
+			for_broadcast.attr.to = session.full_jid;
+			session.send(for_broadcast);
+		end
+	end
+end);