# HG changeset patch # User tmolitor # Date 1459273628 -7200 # Node ID 218a3d3f7f97a41531d6aed6fa091023bc53f261 # Parent 3a94b3cd31e2ad338b3e70f85645084aef357da6 mod_cloud_notify: added ability to notify even if the session is hibernated by mod_smacks diff -r 3a94b3cd31e2 -r 218a3d3f7f97 mod_cloud_notify/README.markdown --- a/mod_cloud_notify/README.markdown Sun Mar 27 16:13:20 2016 +0200 +++ b/mod_cloud_notify/README.markdown Tue Mar 29 19:47:08 2016 +0200 @@ -28,12 +28,5 @@ Configured in-band by supporting clients. -Future -====== - -Adding support for sending notifications for users who are online but -not currently connected, such as when `mod_smacks` is keeping their -session alive, should be added. - [^1]: The service which is expected to forward notifications to something like Google Cloud Messaging or Apple Notification Service diff -r 3a94b3cd31e2 -r 218a3d3f7f97 mod_cloud_notify/mod_cloud_notify.lua --- a/mod_cloud_notify/mod_cloud_notify.lua Sun Mar 27 16:13:20 2016 +0200 +++ b/mod_cloud_notify/mod_cloud_notify.lua Tue Mar 29 19:47:08 2016 +0200 @@ -6,6 +6,7 @@ local st = require"util.stanza"; local jid = require"util.jid"; local dataform = require"util.dataforms".new; +local filters = require "util.filters"; local xmlns_push = "urn:xmpp:push:0"; @@ -78,8 +79,7 @@ }; -- http://xmpp.org/extensions/xep-0357.html#publishing -module:hook("message/offline/handle", function(event) - local origin, stanza = event.origin, event.stanza; +local function handle_notify_request(origin, stanza) local to = stanza.attr.to; local node = to and jid.split(to) or origin.username; local user_push_services = push_enabled[node]; @@ -111,8 +111,55 @@ end module:send(push_publish); end +end + +-- publish on offline message +module:hook("message/offline/handle", function(event) + if event.stanza._notify then + event.stanza._notify = nil; + return; + end + return handle_notify_request(event.origin, event.stanza); end, 1); +-- publish on unacked smacks message +local function process_new_stanza(stanza, session) + if getmetatable(stanza) ~= st.stanza_mt then + return stanza; -- Things we don't want to touch + end + if stanza.name == "message" and stanza.attr.xmlns == nil and + ( stanza.attr.type == "chat" or ( stanza.attr.type or "normal" ) == "normal" ) and + -- not already notified via cloud + not stanza._notify then + stanza._notify = true; + session.log("debug", "Invoking cloud handle_notify_request for new smacks hibernated stanza..."); + handle_notify_request(session, stanza) + end + return stanza; +end + +-- smacks hibernation is started +local function hibernate_session(event) + local session = event.origin; + local queue = event.queue; + -- process already unacked stanzas + for i=1,#queue do + process_new_stanza(queue[i], session); + end + -- process future unacked (hibernated) stanzas + filters.add_filter(session, "stanzas/out", process_new_stanza); +end + +-- smacks hibernation is ended +local function restore_session(event) + local session = event.origin; + filters.remove_filter(session, "stanzas/out", process_new_stanza); +end + +module:hook("smacks-hibernation-start", hibernate_session); +module:hook("smacks-hibernation-end", restore_session); + + module:hook("message/offline/broadcast", function(event) local user_push_services = push_enabled[event.origin.username]; if not user_push_services then return end