Mercurial > prosody-modules
comparison mod_push2/mod_push2.lua @ 6181:811bd0872682
mod_push2: Do not push MUC reflections
Messages from myself to a MUC come back and should not get pushed.
MUC subjects don't have a body so seperately checking for those is not needed.
| author | Stephen Paul Weber <singpolyma@singpolyma.net> |
|---|---|
| date | Mon, 24 Mar 2025 08:53:36 -0500 |
| parents | 051974b4c900 |
| children | fe9f2c618e8a |
comparison
equal
deleted
inserted
replaced
| 6180:051974b4c900 | 6181:811bd0872682 |
|---|---|
| 6 local watchdog = require "util.watchdog"; | 6 local watchdog = require "util.watchdog"; |
| 7 local uuid = require "util.uuid"; | 7 local uuid = require "util.uuid"; |
| 8 local base64 = require "util.encodings".base64; | 8 local base64 = require "util.encodings".base64; |
| 9 local crypto = require "util.crypto"; | 9 local crypto = require "util.crypto"; |
| 10 local jwt = require "util.jwt"; | 10 local jwt = require "util.jwt"; |
| 11 | |
| 12 pcall(function() module:depends("track_muc_joins") end) | |
| 11 | 13 |
| 12 local xmlns_push = "urn:xmpp:push2:0"; | 14 local xmlns_push = "urn:xmpp:push2:0"; |
| 13 | 15 |
| 14 -- configuration | 16 -- configuration |
| 15 local contact_uri = module:get_option_string("contact_uri", "xmpp:" .. module.host) | 17 local contact_uri = module:get_option_string("contact_uri", "xmpp:" .. module.host) |
| 154 | 156 |
| 155 return body ~= nil and body ~= "" | 157 return body ~= nil and body ~= "" |
| 156 end | 158 end |
| 157 | 159 |
| 158 -- is this push a high priority one | 160 -- is this push a high priority one |
| 159 local function is_important(stanza) | 161 local function is_important(stanza, session) |
| 160 local is_voip_stanza, urgent_reason = is_voip(stanza) | 162 local is_voip_stanza, urgent_reason = is_voip(stanza) |
| 161 if is_voip_stanza then return true; end | 163 if is_voip_stanza then return true; end |
| 162 | 164 |
| 163 local st_name = stanza and stanza.name or nil | 165 local st_name = stanza and stanza.name or nil |
| 164 if not st_name then return false; end -- nonzas are never important here | 166 if not st_name then return false; end -- nonzas are never important here |
| 175 if st_type == "headline" then return false; end | 177 if st_type == "headline" then return false; end |
| 176 | 178 |
| 177 -- carbon copied outgoing messages are not important | 179 -- carbon copied outgoing messages are not important |
| 178 if carbon and stanza_direction == "out" then return false; end | 180 if carbon and stanza_direction == "out" then return false; end |
| 179 | 181 |
| 180 -- groupchat subjects are not important here | 182 -- groupchat reflections are not important here |
| 181 if st_type == "groupchat" and stanza:get_child_text("subject") then | 183 if st_type == "groupchat" and session and session.rooms_joined then |
| 182 return false | 184 local muc = jid.bare(stanza.attr.from) |
| 185 local from_nick = jid.resource(stanza.attr.from) | |
| 186 if from_nick == session.rooms_joined[muc] then | |
| 187 return false | |
| 188 end | |
| 183 end | 189 end |
| 184 | 190 |
| 185 -- empty bodies are not important | 191 -- empty bodies are not important |
| 186 return has_body(stanza) | 192 return has_body(stanza) |
| 187 end | 193 end |
| 293 end | 299 end |
| 294 payload.sub = contact_uri | 300 payload.sub = contact_uri |
| 295 push_notification_payload:text_tag("jwt", signer(payload), { key = base64.encode(public_key) }) | 301 push_notification_payload:text_tag("jwt", signer(payload), { key = base64.encode(public_key) }) |
| 296 end | 302 end |
| 297 | 303 |
| 298 local function handle_notify_request(stanza, node, user_push_services, log_push_decline) | 304 local function handle_notify_request(stanza, node, user_push_services, session, log_push_decline) |
| 299 local pushes = 0; | 305 local pushes = 0; |
| 300 if not #user_push_services then return pushes end | 306 if not #user_push_services then return pushes end |
| 301 | 307 |
| 302 local notify_push_services = {}; | 308 local notify_push_services = {}; |
| 303 if is_important(stanza) then | 309 if is_important(stanza, session) then |
| 304 notify_push_services = user_push_services | 310 notify_push_services = user_push_services |
| 305 else | 311 else |
| 306 for identifier, push_info in pairs(user_push_services) do | 312 for identifier, push_info in pairs(user_push_services) do |
| 307 for _, match in ipairs(push_info.matches) do | 313 for _, match in ipairs(push_info.matches) do |
| 308 if match.match == "urn:xmpp:push2:match:important" then | 314 if match.match == "urn:xmpp:push2:match:important" then |
| 328 end | 334 end |
| 329 | 335 |
| 330 if send_push then | 336 if send_push then |
| 331 local push_notification_payload = st.stanza("notification", { xmlns = xmlns_push }) | 337 local push_notification_payload = st.stanza("notification", { xmlns = xmlns_push }) |
| 332 push_notification_payload:text_tag("client", push_info.client) | 338 push_notification_payload:text_tag("client", push_info.client) |
| 333 push_notification_payload:text_tag("priority", is_voip(stanza) and "high" or (is_important(stanza) and "normal" or "low")) | 339 push_notification_payload:text_tag("priority", is_voip(stanza) and "high" or (is_important(stanza, session) and "normal" or "low")) |
| 334 if is_voip(stanza) then | 340 if is_voip(stanza) then |
| 335 push_notification_payload:tag("voip"):up() | 341 push_notification_payload:tag("voip"):up() |
| 336 end | 342 end |
| 337 | 343 |
| 338 local sends_added = {}; | 344 local sends_added = {}; |
| 339 for _, match in ipairs(push_info.matches) do | 345 for _, match in ipairs(push_info.matches) do |
| 340 local does_match = false; | 346 local does_match = false; |
| 341 if match.match == "urn:xmpp:push2:match:all" then | 347 if match.match == "urn:xmpp:push2:match:all" then |
| 342 does_match = true | 348 does_match = true |
| 343 elseif match.match == "urn:xmpp:push2:match:important" then | 349 elseif match.match == "urn:xmpp:push2:match:important" then |
| 344 does_match = is_important(stanza) | 350 does_match = is_important(stanza, session) |
| 345 elseif match.match == "urn:xmpp:push2:match:archived" then | 351 elseif match.match == "urn:xmpp:push2:match:archived" then |
| 346 does_match = stanza:get_child("stana-id", "urn:xmpp:sid:0") | 352 does_match = stanza:get_child("stana-id", "urn:xmpp:sid:0") |
| 347 elseif match.match == "urn:xmpp:push2:match:archived-with-body" then | 353 elseif match.match == "urn:xmpp:push2:match:archived-with-body" then |
| 348 does_match = stanza:get_child("stana-id", "urn:xmpp:sid:0") and has_body(stanza) | 354 does_match = stanza:get_child("stana-id", "urn:xmpp:sid:0") and has_body(stanza) |
| 349 end | 355 end |
| 383 | 389 |
| 384 -- publish on offline message | 390 -- publish on offline message |
| 385 module:hook("message/offline/handle", function(event) | 391 module:hook("message/offline/handle", function(event) |
| 386 local node, user_push_services = get_push_settings(event.stanza, event.origin); | 392 local node, user_push_services = get_push_settings(event.stanza, event.origin); |
| 387 module:log("debug", "Invoking handle_notify_request() for offline stanza"); | 393 module:log("debug", "Invoking handle_notify_request() for offline stanza"); |
| 388 handle_notify_request(event.stanza, node, user_push_services, true); | 394 handle_notify_request(event.stanza, node, user_push_services, event.origin, true); |
| 389 end, 1); | 395 end, 1); |
| 390 | 396 |
| 391 -- publish on bare groupchat | 397 -- publish on bare groupchat |
| 392 -- this picks up MUC messages when there are no devices connected | 398 -- this picks up MUC messages when there are no devices connected |
| 393 module:hook("message/bare/groupchat", function(event) | 399 module:hook("message/bare/groupchat", function(event) |
| 401 notify_push_services[identifier] = push_info; | 407 notify_push_services[identifier] = push_info; |
| 402 end | 408 end |
| 403 end | 409 end |
| 404 end | 410 end |
| 405 | 411 |
| 406 handle_notify_request(event.stanza, node, notify_push_services, true); | 412 handle_notify_request(event.stanza, node, notify_push_services, event.origin, true); |
| 407 end, 1); | 413 end, 1); |
| 408 | 414 |
| 409 local function process_stanza_queue(queue, session, queue_type) | 415 local function process_stanza_queue(queue, session, queue_type) |
| 410 if not session.push_registration_id then return; end | 416 if not session.push_registration_id then return; end |
| 411 local notified = { unimportant = false; important = false } | 417 local notified = { unimportant = false; important = false } |
| 414 -- fast ignore of already pushed stanzas | 420 -- fast ignore of already pushed stanzas |
| 415 if stanza and not (stanza._push_notify2 and stanza._push_notify2[session.push_registration_id]) then | 421 if stanza and not (stanza._push_notify2 and stanza._push_notify2[session.push_registration_id]) then |
| 416 local node, all_push_services = get_push_settings(stanza, session) | 422 local node, all_push_services = get_push_settings(stanza, session) |
| 417 local user_push_services = {[session.push_registration_id] = all_push_services[session.push_registration_id]} | 423 local user_push_services = {[session.push_registration_id] = all_push_services[session.push_registration_id]} |
| 418 local stanza_type = "unimportant"; | 424 local stanza_type = "unimportant"; |
| 419 if is_important(stanza) then stanza_type = "important"; end | 425 if is_important(stanza, session) then stanza_type = "important"; end |
| 420 if not notified[stanza_type] then -- only notify if we didn't try to push for this stanza type already | 426 if not notified[stanza_type] then -- only notify if we didn't try to push for this stanza type already |
| 421 if handle_notify_request(stanza, node, user_push_services, false) ~= 0 then | 427 if handle_notify_request(stanza, node, user_push_services, session, false) ~= 0 then |
| 422 if session.hibernating and not session.first_hibernated_push then | 428 if session.hibernating and not session.first_hibernated_push then |
| 423 -- if the message was important | 429 -- if the message was important |
| 424 -- then record the time of first push in the session for the smack module which will extend its hibernation | 430 -- then record the time of first push in the session for the smack module which will extend its hibernation |
| 425 -- timeout based on the value of session.first_hibernated_push | 431 -- timeout based on the value of session.first_hibernated_push |
| 426 if is_important(stanza) then | 432 if is_important(stanza, session) then |
| 427 session.first_hibernated_push = os_time(); | 433 session.first_hibernated_push = os_time(); |
| 428 -- check for prosody 0.12 mod_smacks | 434 -- check for prosody 0.12 mod_smacks |
| 429 if session.hibernating_watchdog and session.original_smacks_callback and session.original_smacks_timeout then | 435 if session.hibernating_watchdog and session.original_smacks_callback and session.original_smacks_timeout then |
| 430 -- restore old smacks watchdog (--> the start of our original timeout will be delayed until first push) | 436 -- restore old smacks watchdog (--> the start of our original timeout will be delayed until first push) |
| 431 session.hibernating_watchdog:cancel(); | 437 session.hibernating_watchdog:cancel(); |
| 566 notify_push_services[identifier] = push_info | 572 notify_push_services[identifier] = push_info |
| 567 end | 573 end |
| 568 end | 574 end |
| 569 end | 575 end |
| 570 | 576 |
| 571 handle_notify_request(stanza, to_user, notify_push_services, true); | 577 handle_notify_request(stanza, to_user, notify_push_services, event.origin, true); |
| 572 end | 578 end |
| 573 end | 579 end |
| 574 | 580 |
| 575 module:hook("smacks-hibernation-start", hibernate_session); | 581 module:hook("smacks-hibernation-start", hibernate_session); |
| 576 module:hook("smacks-hibernation-end", restore_session); | 582 module:hook("smacks-hibernation-end", restore_session); |
