mod_muc_mention_notifications/mod_muc_mention_notifications.lua
author Kim Alvefur <zash@zash.se>
Sun, 03 Mar 2024 11:23:40 +0100
changeset 5857 97c9b76867ca
parent 4317 fc5c53d9d340
permissions -rw-r--r--
mod_log_ringbuffer: Detach event handlers on logging reload (thanks Menel) Otherwise the global event handlers accumulate, one added each time logging is reoladed, and each invocation of the signal or event triggers one dump of each created ringbuffer.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4284
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
     1
local jid = require "util.jid";
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
     2
local st = require "util.stanza";
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
     3
local datetime = require "util.datetime";
4309
2ca55a4da3ea muc_room_mention_notifications: Handle referenced JID being a MUC nickname JID
JC Brand <jc@opkode.com>
parents: 4284
diff changeset
     4
local jid_resource = require "util.jid".resource;
4284
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
     5
4311
af7297e49885 muc_mention_notifications: Rename module
JC Brand <jc@opkode.com>
parents: 4310
diff changeset
     6
local notify_unaffiliated_users = module:get_option("muc_mmn_notify_unaffiliated_users", false)
4284
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
     7
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
     8
local muc_affiliation_store = module:open_store("config", "map");
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
     9
4310
747a14017d00 muc_room_mention_notifications: Set xmlns to what's used in the protoXEP
JC Brand <jc@opkode.com>
parents: 4309
diff changeset
    10
local mmn_xmlns = "urn:xmpp:mmn:0";
4284
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    11
local reference_xmlns = "urn:xmpp:reference:0";
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    12
local forwarded_xmlns = "urn:xmpp:forward:0";
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    13
local deplay_xmlns = "urn:xmpp:delay";
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    14
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    15
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    16
-- Returns a set of rooms the user is affiliated to
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    17
local function get_user_rooms(user_bare_jid)
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    18
	return muc_affiliation_store:get_all(user_bare_jid);
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    19
end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    20
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    21
local function is_eligible(user_bare_jid, room)
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    22
	if notify_unaffiliated_users then return true; end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    23
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    24
	local user_rooms, err = get_user_rooms(user_bare_jid);
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    25
	if not user_rooms then
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    26
		if err then
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    27
			return false, err;
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    28
		end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    29
		return false;
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    30
	end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    31
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    32
	local room_node = jid.node(room.jid)
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    33
	if user_rooms[room_node] then
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    34
		return true;
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    35
	end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    36
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    37
	return false
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    38
end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    39
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    40
-- Send a single notification for a room, updating data structures as needed
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    41
local function send_single_notification(user_bare_jid, room_jid, mention_stanza)
4317
fc5c53d9d340 mod_muc_mention_notifications: Send mention notifications from the MUC JID
JC Brand <jc@opkode.com>
parents: 4312
diff changeset
    42
	local notification = st.message({ to = user_bare_jid, from = room_jid })
4310
747a14017d00 muc_room_mention_notifications: Set xmlns to what's used in the protoXEP
JC Brand <jc@opkode.com>
parents: 4309
diff changeset
    43
		:tag("mentions", { xmlns = mmn_xmlns })
4284
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    44
		:tag("forwarded", {xmlns = forwarded_xmlns})
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    45
		:tag("delay", {xmlns = deplay_xmlns, stamp = datetime.datetime()}):up()
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    46
		:add_child(mention_stanza)
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    47
		:reset();
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    48
	module:log("debug", "Sending mention notification from %s to %s", room_jid, user_bare_jid);
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    49
	return module:send(notification);
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    50
end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    51
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    52
local function notify_mentioned_users(room, client_mentions, mention_stanza)
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    53
	module:log("debug", "NOTIFYING FOR %s", room.jid)
4309
2ca55a4da3ea muc_room_mention_notifications: Handle referenced JID being a MUC nickname JID
JC Brand <jc@opkode.com>
parents: 4284
diff changeset
    54
	for mentioned_jid in pairs(client_mentions) do
2ca55a4da3ea muc_room_mention_notifications: Handle referenced JID being a MUC nickname JID
JC Brand <jc@opkode.com>
parents: 4284
diff changeset
    55
		local user_bare_jid = mentioned_jid;
2ca55a4da3ea muc_room_mention_notifications: Handle referenced JID being a MUC nickname JID
JC Brand <jc@opkode.com>
parents: 4284
diff changeset
    56
		if (string.match(mentioned_jid, room.jid)) then
2ca55a4da3ea muc_room_mention_notifications: Handle referenced JID being a MUC nickname JID
JC Brand <jc@opkode.com>
parents: 4284
diff changeset
    57
			local nick = jid_resource(mentioned_jid);
2ca55a4da3ea muc_room_mention_notifications: Handle referenced JID being a MUC nickname JID
JC Brand <jc@opkode.com>
parents: 4284
diff changeset
    58
			user_bare_jid = room:get_registered_jid(nick);
2ca55a4da3ea muc_room_mention_notifications: Handle referenced JID being a MUC nickname JID
JC Brand <jc@opkode.com>
parents: 4284
diff changeset
    59
		end
4284
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    60
		if is_eligible(user_bare_jid, room) then
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    61
			send_single_notification(user_bare_jid, room.jid, mention_stanza);
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    62
		end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    63
	end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    64
end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    65
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    66
local function get_mentions(stanza)
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    67
	local has_mentions = false
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    68
	local client_mentions = {}
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    69
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    70
	for element in stanza:childtags("reference", reference_xmlns) do
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    71
		if element.attr.type == "mention" then
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    72
			local user_bare_jid = element.attr.uri:match("^xmpp:(.+)$");
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    73
			if user_bare_jid then
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    74
				client_mentions[user_bare_jid] = user_bare_jid;
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    75
				has_mentions = true
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    76
			end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    77
		end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    78
	end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    79
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    80
	return has_mentions, client_mentions
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    81
end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    82
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    83
module:hook("muc-broadcast-message", function (event)
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    84
	local room, stanza = event.room, event.stanza;
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    85
	local body = stanza:get_child_text("body")
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    86
	if not body or #body < 1 then return; end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    87
	local correction = stanza:get_child("replace", "urn:xmpp:message-correct:0");
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    88
	if correction then return; end -- Do not notify on message corrections
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    89
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    90
	local has_mentions, client_mentions = get_mentions(stanza)
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    91
	if not has_mentions then return; end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    92
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    93
	-- Notify any users that need to be notified
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    94
	notify_mentioned_users(room, client_mentions, stanza);
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
    95
end, -1);