# HG changeset patch # User Kim Alvefur # Date 1551106366 -3600 # Node ID 262e68821f3fd0af276541f6215840ee95543a8f # Parent 5567098a7f91616790c7814495ed04b9c6760add mod_map: Experimental module exposing MAM summary diff -r 5567098a7f91 -r 262e68821f3f mod_map/README.markdown --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_map/README.markdown Mon Feb 25 15:52:46 2019 +0100 @@ -0,0 +1,52 @@ +--- +labels: +- 'Stage-Experimental' +summary: Prototype MAM summary +--- + +This is a prototype for an experimental archive summary API recently +added in [Prosody trunk](https://hg.prosody.im/trunk/rev/2c5546cc5c70). + +# Protocol + +::: {.alert .alert-danger} +This is not a finished protocol, but a prototype meant for testing. +::: + +A basic query: + +``` {.xml} + + + +``` + +Answered like: + +``` {.xml} + + + + + 3 + + + +``` + +It can also take dataform and RSM parameters similar to a [filtered MAM +query](https://xmpp.org/extensions/xep-0313.html#filter). + +E.g if the last message you received had an id `09af3-cc343-b409f` then +the following query would tell you who sent you messages since: + +``` {.xml} + + + + 10 + 09af3-cc343-b409f + + + +``` diff -r 5567098a7f91 -r 262e68821f3f mod_map/mod_map.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_map/mod_map.lua Mon Feb 25 15:52:46 2019 +0100 @@ -0,0 +1,67 @@ + +local st = require "util.stanza"; +local jid_bare = require "util.jid".bare; +local rsm = require "util.rsm"; +local dataform = require "util.dataforms".new; + +local archive = module:open_store("archive", "archive"); + +local query_form = dataform { + { name = "with"; type = "jid-single"; }; + { name = "start"; type = "text-single" }; + { name = "end"; type = "text-single"; }; +}; + +if not archive.summary then + module:log("error", "The archive:summary() API is not supported by %s", archive._provided_by); + return +end + +module:hook("iq-get/self/xmpp:prosody.im/mod_map:summary", function(event) + local origin, stanza = event.origin, event.stanza; + + local query = stanza.tags[1]; + + -- Search query parameters + local qwith, qstart, qend; + local form = query:get_child("x", "jabber:x:data"); + if form then + local err; + form, err = query_form:data(form); + if err then + origin.send(st.error_reply(stanza, "modify", "bad-request", select(2, next(err)))); + return true; + end + qwith, qstart, qend = form["with"], form["start"], form["end"]; + qwith = qwith and jid_bare(qwith); -- dataforms does jidprep + end + + local qset = rsm.get(query); + local qmax = qset and qset.max; + local before, after = qset and qset.before, qset and qset.after; + if type(before) ~= "string" then before = nil; end + + local summary = archive:summary(origin.username, { + start = qstart; ["end"] = qend; -- Time range + with = qwith; + limit = qmax; + before = before; after = after; + }); + if not summary then + module:send(st.error_reply(stanza, "wait", "internal-server-error")); + return true; + end + + local reply = st.reply(stanza); + reply:tag("summary", { xmlns = "xmpp:prosody.im/mod_map" }); + for jid, count in pairs(summary) do + reply:tag("item", { jid = jid }); + if type(count) == "number" then + reply:text_tag("count", ("%d"):format(count)); + end + reply:up(); + end + + module:send(reply); + return true; +end);