Software /
code /
prosody-modules
Changeset
3496:262e68821f3f
mod_map: Experimental module exposing MAM summary
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Mon, 25 Feb 2019 15:52:46 +0100 |
parents | 3495:5567098a7f91 |
children | 3497:bc67519803f5 |
files | mod_map/README.markdown mod_map/mod_map.lua |
diffstat | 2 files changed, 119 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /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} +<iq id="lx7" type="get"> + <summary xmlns="xmpp:prosody.im/mod_map"/> +</iq> +``` + +Answered like: + +``` {.xml} +<?xml version="1.0"?> +<iq type="result" id="lx7"> + <summary xmlns="xmpp:prosody.im/mod_map"> + <item jid="juliet@capulet.lit"> + <count>3</count> + </item> + </summary> +</iq> +``` + +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} +<iq id="lx8" type="get"> + <summary xmlns="xmpp:prosody.im/mod_map"> + <set xmlns="http://jabber.org/protocol/rsm"> + <max>10</max> + <after>09af3-cc343-b409f</after> + </set> + </summary> +</iq> +```
--- /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);