# HG changeset patch # User Kim Alvefur # Date 1431912428 -7200 # Node ID 985e05ac833b851335d76a3a223a542a8a3323ae # Parent 5734a619993879f762198d1a5545c72a9a5d679c mod_mamsub: Experimental implementation of MAM subscriptions diff -r 5734a6199938 -r 985e05ac833b mod_mamsub/mod_mamsub.lua --- /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);