Changeset

6215:e53f0967520c

mod_push: Allow filtering pushes for particular chats
author Stephen Paul Weber <singpolyma@singpolyma.net>
date Mon, 24 Mar 2025 13:01:05 -0500
parents 6214:fe9f2c618e8a
children 6216:2f2539ce8f3b
files mod_push2/mod_push2.lua mod_push2/push2.md
diffstat 2 files changed, 41 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/mod_push2/mod_push2.lua	Mon Mar 24 09:28:25 2025 -0500
+++ b/mod_push2/mod_push2.lua	Mon Mar 24 13:01:05 2025 -0500
@@ -31,7 +31,19 @@
 module:hook("account-disco-info", account_dico_info);
 
 local function parse_match(matchel)
-		local match = { match = matchel.attr.profile }
+		local match = { match = matchel.attr.profile, chats = {} }
+
+		for chatel in matchel:childtags("chat") do
+			local chat = {}
+			if chatel:get_child("mention") then
+				chat.mention = true
+			end
+			if chatel:get_child("reply") then
+				chat.reply = true
+			end
+			match.chats[chatel.attr.jid] = chat
+		end
+
 		local send = matchel:get_child("send", "urn:xmpp:push2:send:notify-only:0")
 		if send then
 			match.send = send.attr.xmlns
@@ -355,6 +367,29 @@
 					does_match = stanza:get_child("stana-id", "urn:xmpp:sid:0") and has_body(stanza)
 				end
 
+				local chat = match.chats and (match.chats[stanza.attr.from] or match.chats[jid.bare(stanza.attr.from)] or match.chats[jid.host(stanza.attr.from)])
+				if does_match and chat then
+					does_match = false
+
+					local to_user, to_host = jid.split(stanza.attr.to)
+					to_user = to_user or session.username
+					to_host = to_host or module.host
+					local nick = session.rooms_joined[jid.bare(stanza.attr.from)] or to_user
+
+					if not does_match and chat.mention then
+						local body = stanza:get_child_text("body")
+						if body and body:find(nick, 1, true) then
+							does_match = true
+						end
+					end
+					if not does_match and chat.reply then
+						local reply = stanza:get_child("reply", "urn:xmpp:reply:0")
+						if reply and (reply.attr.to == to_user.."@"..to_host or (jid.bare(reply.attr.to) == jid.bare(stanza.attr.from) and jid.resource(reply.attr.to) == nick)) then
+							does_match = true
+						end
+					end
+				end
+
 				if does_match and not sends_added[match.send] then
 					sends_added[match.send] = true
 					if match.send == "urn:xmpp:push2:send:notify-only" then
--- a/mod_push2/push2.md	Mon Mar 24 09:28:25 2025 -0500
+++ b/mod_push2/push2.md	Mon Mar 24 13:01:05 2025 -0500
@@ -15,6 +15,9 @@
     <service>pusher@push.example.com</service>
     <client>https://push.example.com/adlfkjadafdasf</client>
     <match profile="urn:xmpp:push2:match:archived-with-body">
+        <chat jid="somemuc@conference.example.com">
+            <mention/>
+        </chat>
         <send xmlns="urn:xmpp:push2:send:notify-only:0"/>
     </match>
 </enable>
@@ -26,6 +29,8 @@
 
 The `<match/>` and `<send/>` elements define what profiles to use for matching stanzas and sending notifications. These are described later in this document.
 
+The optional `<chat/>` child of `<match/>` allows extra filtering of pushes for only specific chats. No specified filters means muted, do not push. `<mention/>` means push on mentions, `<reply/>` means push on replies.
+
 ## Match and send profiles
 
 Different clients and push services have different requirements for push notifications, often due to the differing capabilities of target platforms.