comparison 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
parents mod_muc_room_mention_notifications/mod_muc_room_mention_notifications.lua@747a14017d00
children 2d42dd45638a
comparison
equal deleted inserted replaced
4306:747a14017d00 4307:af7297e49885
1 local jid = require "util.jid";
2 local st = require "util.stanza";
3 local datetime = require "util.datetime";
4 local jid_resource = require "util.jid".resource;
5
6 local notify_unaffiliated_users = module:get_option("muc_mmn_notify_unaffiliated_users", false)
7
8 local muc_affiliation_store = module:open_store("config", "map");
9
10 local mmn_xmlns = "urn:xmpp:mmn:0";
11 local reference_xmlns = "urn:xmpp:reference:0";
12 local forwarded_xmlns = "urn:xmpp:forward:0";
13 local deplay_xmlns = "urn:xmpp:delay";
14
15
16 module:log("debug", "**************************************")
17 module:log("debug", "**************************************")
18 module:log("debug", "**************************************")
19 module:log("debug", "**************************************")
20 module:log("debug", "**************************************")
21 module:log("debug", "**************************************")
22 module:log("debug", "**************************************")
23 module:log("debug", "**************************************")
24 module:log("debug", "**************************************")
25 module:log("debug", "**************************************")
26 module:log("debug", "**************************************")
27
28 -- Returns a set of rooms the user is affiliated to
29 local function get_user_rooms(user_bare_jid)
30 return muc_affiliation_store:get_all(user_bare_jid);
31 end
32
33 local function is_eligible(user_bare_jid, room)
34 if notify_unaffiliated_users then return true; end
35
36 local user_rooms, err = get_user_rooms(user_bare_jid);
37 if not user_rooms then
38 if err then
39 return false, err;
40 end
41 return false;
42 end
43
44 local room_node = jid.node(room.jid)
45 if user_rooms[room_node] then
46 return true;
47 end
48
49 return false
50 end
51
52 -- Send a single notification for a room, updating data structures as needed
53 local function send_single_notification(user_bare_jid, room_jid, mention_stanza)
54 local notification = st.message({ to = user_bare_jid, from = module.host })
55 :tag("mentions", { xmlns = mmn_xmlns })
56 :tag("forwarded", {xmlns = forwarded_xmlns})
57 :tag("delay", {xmlns = deplay_xmlns, stamp = datetime.datetime()}):up()
58 :add_child(mention_stanza)
59 :reset();
60 module:log("debug", "Sending mention notification from %s to %s", room_jid, user_bare_jid);
61 return module:send(notification);
62 end
63
64 local function notify_mentioned_users(room, client_mentions, mention_stanza)
65 module:log("debug", "NOTIFYING FOR %s", room.jid)
66 for mentioned_jid in pairs(client_mentions) do
67 local user_bare_jid = mentioned_jid;
68 if (string.match(mentioned_jid, room.jid)) then
69 local nick = jid_resource(mentioned_jid);
70 user_bare_jid = room:get_registered_jid(nick);
71 end
72 if is_eligible(user_bare_jid, room) then
73 send_single_notification(user_bare_jid, room.jid, mention_stanza);
74 end
75 end
76 end
77
78 local function get_mentions(stanza)
79 local has_mentions = false
80 local client_mentions = {}
81
82 for element in stanza:childtags("reference", reference_xmlns) do
83 if element.attr.type == "mention" then
84 local user_bare_jid = element.attr.uri:match("^xmpp:(.+)$");
85 if user_bare_jid then
86 client_mentions[user_bare_jid] = user_bare_jid;
87 has_mentions = true
88 end
89 end
90 end
91
92 return has_mentions, client_mentions
93 end
94
95 if rawget(_G, "setfenv") == nil then
96 rawset(_G, "setfenv", false)
97 end
98 if rawget(_G, "getfenv") == nil then
99 rawset(_G, "getfenv", false)
100 end
101
102 module:hook("muc-broadcast-message", function (event)
103
104 require("mobdebug").start()
105 local room, stanza = event.room, event.stanza;
106 local body = stanza:get_child_text("body")
107 if not body or #body < 1 then return; end
108 local correction = stanza:get_child("replace", "urn:xmpp:message-correct:0");
109 if correction then return; end -- Do not notify on message corrections
110
111 local has_mentions, client_mentions = get_mentions(stanza)
112 if not has_mentions then return; end
113
114 -- Notify any users that need to be notified
115 notify_mentioned_users(room, client_mentions, stanza);
116 end, -1);