Software /
code /
prosody-modules
Diff
mod_muc_mention_notifications/mod_muc_mention_notifications.lua @ 4307:af7297e49885
muc_mention_notifications: Rename module
No need for the additional "room" in the name.
author | JC Brand <jc@opkode.com> |
---|---|
date | Mon, 21 Dec 2020 15:43:35 +0100 |
parent | 4306:747a14017d00 |
child | 4308:2d42dd45638a |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_muc_mention_notifications/mod_muc_mention_notifications.lua Mon Dec 21 15:43:35 2020 +0100 @@ -0,0 +1,116 @@ +local jid = require "util.jid"; +local st = require "util.stanza"; +local datetime = require "util.datetime"; +local jid_resource = require "util.jid".resource; + +local notify_unaffiliated_users = module:get_option("muc_mmn_notify_unaffiliated_users", false) + +local muc_affiliation_store = module:open_store("config", "map"); + +local mmn_xmlns = "urn:xmpp:mmn:0"; +local reference_xmlns = "urn:xmpp:reference:0"; +local forwarded_xmlns = "urn:xmpp:forward:0"; +local deplay_xmlns = "urn:xmpp:delay"; + + +module:log("debug", "**************************************") +module:log("debug", "**************************************") +module:log("debug", "**************************************") +module:log("debug", "**************************************") +module:log("debug", "**************************************") +module:log("debug", "**************************************") +module:log("debug", "**************************************") +module:log("debug", "**************************************") +module:log("debug", "**************************************") +module:log("debug", "**************************************") +module:log("debug", "**************************************") + +-- Returns a set of rooms the user is affiliated to +local function get_user_rooms(user_bare_jid) + return muc_affiliation_store:get_all(user_bare_jid); +end + +local function is_eligible(user_bare_jid, room) + if notify_unaffiliated_users then return true; end + + local user_rooms, err = get_user_rooms(user_bare_jid); + if not user_rooms then + if err then + return false, err; + end + return false; + end + + local room_node = jid.node(room.jid) + if user_rooms[room_node] then + return true; + end + + return false +end + +-- Send a single notification for a room, updating data structures as needed +local function send_single_notification(user_bare_jid, room_jid, mention_stanza) + local notification = st.message({ to = user_bare_jid, from = module.host }) + :tag("mentions", { xmlns = mmn_xmlns }) + :tag("forwarded", {xmlns = forwarded_xmlns}) + :tag("delay", {xmlns = deplay_xmlns, stamp = datetime.datetime()}):up() + :add_child(mention_stanza) + :reset(); + module:log("debug", "Sending mention notification from %s to %s", room_jid, user_bare_jid); + return module:send(notification); +end + +local function notify_mentioned_users(room, client_mentions, mention_stanza) + module:log("debug", "NOTIFYING FOR %s", room.jid) + for mentioned_jid in pairs(client_mentions) do + local user_bare_jid = mentioned_jid; + if (string.match(mentioned_jid, room.jid)) then + local nick = jid_resource(mentioned_jid); + user_bare_jid = room:get_registered_jid(nick); + end + if is_eligible(user_bare_jid, room) then + send_single_notification(user_bare_jid, room.jid, mention_stanza); + end + end +end + +local function get_mentions(stanza) + local has_mentions = false + local client_mentions = {} + + for element in stanza:childtags("reference", reference_xmlns) do + if element.attr.type == "mention" then + local user_bare_jid = element.attr.uri:match("^xmpp:(.+)$"); + if user_bare_jid then + client_mentions[user_bare_jid] = user_bare_jid; + has_mentions = true + end + end + end + + return has_mentions, client_mentions +end + +if rawget(_G, "setfenv") == nil then + rawset(_G, "setfenv", false) +end +if rawget(_G, "getfenv") == nil then + rawset(_G, "getfenv", false) +end + +module:hook("muc-broadcast-message", function (event) + + require("mobdebug").start() + local room, stanza = event.room, event.stanza; + local body = stanza:get_child_text("body") + if not body or #body < 1 then return; end + local correction = stanza:get_child("replace", "urn:xmpp:message-correct:0"); + if correction then return; end -- Do not notify on message corrections + + local has_mentions, client_mentions = get_mentions(stanza) + if not has_mentions then return; end + + -- Notify any users that need to be notified + notify_mentioned_users(room, client_mentions, stanza); +end, -1);