Mercurial > prosody-modules
changeset 2712:d89ab70808f6
mod_cloud_notify: fix bug when multiple resources are used
This bug was triggered under the rare circumstances that a message arrived
and one resource was smacks hibernated while the other one(s) were offline.
Then only the hibernated resource but not the offline one(s) (or the other
way round) got notified.
author | tmolitor <thilo@eightysoft.de> |
---|---|
date | Mon, 08 May 2017 18:24:29 +0200 |
parents | ff1f7e61517f |
children | eea1d5bac451 |
files | mod_cloud_notify/mod_cloud_notify.lua |
diffstat | 1 files changed, 46 insertions(+), 40 deletions(-) [+] |
line wrap: on
line diff
--- a/mod_cloud_notify/mod_cloud_notify.lua Fri Apr 28 12:09:51 2017 +0100 +++ b/mod_cloud_notify/mod_cloud_notify.lua Mon May 08 18:24:29 2017 +0200 @@ -207,54 +207,60 @@ -- http://xmpp.org/extensions/xep-0357.html#publishing local function handle_notify_request(stanza, node, user_push_services) - if not user_push_services or not #user_push_services then return end + local pushes = 0; + if not user_push_services or not #user_push_services then return pushes end for push_identifier, push_info in pairs(user_push_services) do + local send_push = true; -- only send push to this node when not already done for this stanza or if no stanza is given at all if stanza then if not stanza._push_notify then stanza._push_notify = {}; end if stanza._push_notify[push_identifier] then module:log("debug", "Already sent push notification for %s@%s to %s (%s)", node, module.host, push_info.jid, tostring(push_info.node)); - return; + send_push = false; end stanza._push_notify[push_identifier] = true; end - - -- increment count and save it - push_info.count = push_info.count + 1; - push_store:set_identifier(node, push_identifier, push_info); - -- construct push stanza - local stanza_id = hashes.sha256(push_identifier, true); - local push_publish = st.iq({ to = push_info.jid, from = node .. "@" .. module.host, type = "set", id = stanza_id }) - :tag("pubsub", { xmlns = "http://jabber.org/protocol/pubsub" }) - :tag("publish", { node = push_info.node }) - :tag("item") - :tag("notification", { xmlns = xmlns_push }); - local form_data = { - ["message-count"] = tostring(push_info.count); - }; - if stanza and include_sender then - form_data["last-message-sender"] = stanza.attr.from; + + if send_push then + -- increment count and save it + push_info.count = push_info.count + 1; + push_store:set_identifier(node, push_identifier, push_info); + -- construct push stanza + local stanza_id = hashes.sha256(push_identifier, true); + local push_publish = st.iq({ to = push_info.jid, from = node .. "@" .. module.host, type = "set", id = stanza_id }) + :tag("pubsub", { xmlns = "http://jabber.org/protocol/pubsub" }) + :tag("publish", { node = push_info.node }) + :tag("item") + :tag("notification", { xmlns = xmlns_push }); + local form_data = { + ["message-count"] = tostring(push_info.count); + }; + if stanza and include_sender then + form_data["last-message-sender"] = stanza.attr.from; + end + if stanza and include_body then + form_data["last-message-body"] = stanza:get_child_text("body"); + end + push_publish:add_child(push_form:form(form_data)); + push_publish:up(); -- / notification + push_publish:up(); -- / publish + push_publish:up(); -- / pubsub + if push_info.options then + push_publish:tag("publish-options"):add_child(st.deserialize(push_info.options)); + end + -- send out push + module:log("debug", "Sending push notification for %s@%s to %s (%s)", node, module.host, push_info.jid, tostring(push_info.node)); + -- handle push errors for this node + if push_errors[push_identifier] == nil then + push_errors[push_identifier] = 0; + module:hook("iq-error/bare/"..stanza_id, handle_push_error); + module:hook("iq-result/bare/"..stanza_id, handle_push_success); + end + module:send(push_publish); + pushes = pushes + 1; end - if stanza and include_body then - form_data["last-message-body"] = stanza:get_child_text("body"); - end - push_publish:add_child(push_form:form(form_data)); - push_publish:up(); -- / notification - push_publish:up(); -- / publish - push_publish:up(); -- / pubsub - if push_info.options then - push_publish:tag("publish-options"):add_child(st.deserialize(push_info.options)); - end - -- send out push - module:log("debug", "Sending push notification for %s@%s to %s (%s)", node, module.host, push_info.jid, tostring(push_info.node)); - -- handle push errors for this node - if push_errors[push_identifier] == nil then - push_errors[push_identifier] = 0; - module:hook("iq-error/bare/"..stanza_id, handle_push_error); - module:hook("iq-result/bare/"..stanza_id, handle_push_success); - end - module:send(push_publish); end + return pushes; end -- small helper function to extract relevant push settings @@ -268,7 +274,7 @@ -- publish on offline message module:hook("message/offline/handle", function(event) local node, user_push_services = get_push_settings(event.stanza, event.origin); - return handle_notify_request(event.stanza, node, user_push_services); + handle_notify_request(event.stanza, node, user_push_services); end, 1); -- publish on unacked smacks message @@ -350,7 +356,7 @@ end end - return handle_notify_request(event.stanza, to, notify_push_sevices); + handle_notify_request(event.stanza, to, notify_push_sevices); end end @@ -363,7 +369,7 @@ local user = event.user; local user_push_services = push_store:get(user); local push_services = event.push_services or user_push_services; - return handle_notify_request(nil, user, push_services); + handle_notify_request(nil, user, push_services); end -- can be used by other modules to ping one or more (or all) push endpoints module:hook("cloud-notify-ping", send_ping);