Mercurial > prosody-modules
annotate mod_muc_cloud_notify/mod_muc_cloud_notify.lua @ 4249:64aa1d9d70ac
mod_rest: Catch and log errors in callback promise chain
From the code it looks like it should be possible to reply to an error
stanza, but it did not. Turns out I was saved by my local developer mode
module which throws errors if an attempt is made to create an errror
reply to an error stanza. However nothing collects this error from the
promise, so all I got was confusion.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sun, 15 Nov 2020 16:25:49 +0100 |
parents | 571249f69577 |
children | 524a9103fb45 |
rev | line source |
---|---|
3319 | 1 -- XEP-XXX: MUC Push Notifications |
2 -- Copyright (C) 2015-2016 Kim Alvefur | |
3 -- Copyright (C) 2017-2018 Thilo Molitor | |
4 -- | |
5 -- This file is MIT/X11 licensed. | |
6 | |
7 local s_match = string.match; | |
8 local s_sub = string.sub; | |
9 local os_time = os.time; | |
10 local next = next; | |
11 local st = require"util.stanza"; | |
12 local jid = require"util.jid"; | |
13 local dataform = require"util.dataforms".new; | |
14 local hashes = require"util.hashes"; | |
15 | |
16 local xmlns_push = "urn:xmpp:push:0"; | |
17 | |
18 -- configuration | |
19 local include_body = module:get_option_boolean("push_notification_with_body", false); | |
20 local include_sender = module:get_option_boolean("push_notification_with_sender", false); | |
21 local max_push_errors = module:get_option_number("push_max_errors", 16); | |
22 local max_push_devices = module:get_option_number("push_max_devices", 5); | |
23 local dummy_body = module:get_option_string("push_notification_important_body", "New Message!"); | |
24 | |
25 local host_sessions = prosody.hosts[module.host].sessions; | |
26 local push_errors = {}; | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
27 local id2node = {}; |
3319 | 28 |
29 module:depends("muc"); | |
30 | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
31 -- ordered table iterator, allow to iterate on the natural order of the keys of a table, |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
32 -- see http://lua-users.org/wiki/SortedIteration |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
33 local function __genOrderedIndex( t ) |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
34 local orderedIndex = {} |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
35 for key in pairs(t) do |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
36 table.insert( orderedIndex, key ) |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
37 end |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
38 -- sort in reverse order (newest one first) |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
39 table.sort( orderedIndex, function(a, b) |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
40 if a == nil or t[a] == nil or b == nil or t[b] == nil then return false end |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
41 -- only one timestamp given, this is the newer one |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
42 if t[a].timestamp ~= nil and t[b].timestamp == nil then return true end |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
43 if t[a].timestamp == nil and t[b].timestamp ~= nil then return false end |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
44 -- both timestamps given, sort normally |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
45 if t[a].timestamp ~= nil and t[b].timestamp ~= nil then return t[a].timestamp > t[b].timestamp end |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
46 return false -- normally not reached |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
47 end) |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
48 return orderedIndex |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
49 end |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
50 local function orderedNext(t, state) |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
51 -- Equivalent of the next function, but returns the keys in timestamp |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
52 -- order. We use a temporary ordered key table that is stored in the |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
53 -- table being iterated. |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
54 |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
55 local key = nil |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
56 --print("orderedNext: state = "..tostring(state) ) |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
57 if state == nil then |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
58 -- the first time, generate the index |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
59 t.__orderedIndex = __genOrderedIndex( t ) |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
60 key = t.__orderedIndex[1] |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
61 else |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
62 -- fetch the next value |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
63 for i = 1, #t.__orderedIndex do |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
64 if t.__orderedIndex[i] == state then |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
65 key = t.__orderedIndex[i+1] |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
66 end |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
67 end |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
68 end |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
69 |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
70 if key then |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
71 return key, t[key] |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
72 end |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
73 |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
74 -- no more value to return, cleanup |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
75 t.__orderedIndex = nil |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
76 return |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
77 end |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
78 local function orderedPairs(t) |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
79 -- Equivalent of the pairs() function on tables. Allows to iterate |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
80 -- in order |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
81 return orderedNext, t, nil |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
82 end |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
83 |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
84 -- small helper function to return new table with only "maximum" elements containing only the newest entries |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
85 local function reduce_table(table, maximum) |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
86 local count = 0; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
87 local result = {}; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
88 for key, value in orderedPairs(table) do |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
89 count = count + 1; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
90 if count > maximum then break end |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
91 result[key] = value; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
92 end |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
93 return result; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
94 end |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
95 |
3319 | 96 -- For keeping state across reloads while caching reads |
97 local push_store = (function() | |
98 local store = module:open_store(); | |
99 local push_services = {}; | |
100 local api = {}; | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
101 function api:get(user) |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
102 if not push_services[user] then |
3319 | 103 local err; |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
104 push_services[user], err = store:get(user); |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
105 if not push_services[user] and err then |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
106 module:log("warn", "Error reading push notification storage for user '%s': %s", user, tostring(err)); |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
107 push_services[user] = {}; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
108 return push_services[user], false; |
3319 | 109 end |
110 end | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
111 if not push_services[user] then push_services[user] = {} end |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
112 return push_services[user], true; |
3319 | 113 end |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
114 function api:set(user, data) |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
115 push_services[user] = reduce_table(data, max_push_devices); |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
116 local ok, err = store:set(user, push_services[user]); |
3319 | 117 if not ok then |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
118 module:log("error", "Error writing push notification storage for user '%s': %s", user, tostring(err)); |
3319 | 119 return false; |
120 end | |
121 return true; | |
122 end | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
123 function api:set_identifier(user, push_identifier, data) |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
124 local services = self:get(user); |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
125 services[push_identifier] = data; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
126 return self:set(user, services); |
3319 | 127 end |
128 return api; | |
129 end)(); | |
130 | |
131 | |
132 -- Forward declarations, as both functions need to reference each other | |
133 local handle_push_success, handle_push_error; | |
134 | |
135 function handle_push_error(event) | |
136 local stanza = event.stanza; | |
137 local error_type, condition = stanza:get_error(); | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
138 local node = id2node[stanza.attr.id]; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
139 if node == nil then return false; end -- unknown stanza? Ignore for now! |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
140 local from = stanza.attr.from; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
141 local user_push_services = push_store:get(node); |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
142 local changed = false; |
3319 | 143 |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
144 for push_identifier, _ in pairs(user_push_services) do |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
145 local stanza_id = hashes.sha256(push_identifier, true); |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
146 if stanza_id == stanza.attr.id then |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
147 if user_push_services[push_identifier] and user_push_services[push_identifier].jid == from and error_type ~= "wait" then |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
148 push_errors[push_identifier] = push_errors[push_identifier] + 1; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
149 module:log("info", "Got error of type '%s' (%s) for identifier '%s': " |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
150 .."error count for this identifier is now at %s", error_type, condition, push_identifier, |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
151 tostring(push_errors[push_identifier])); |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
152 if push_errors[push_identifier] >= max_push_errors then |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
153 module:log("warn", "Disabling push notifications for identifier '%s'", push_identifier); |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
154 -- remove push settings from sessions |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
155 if host_sessions[node] then |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
156 for _, session in pairs(host_sessions[node].sessions) do |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
157 if session.push_identifier == push_identifier then |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
158 session.push_identifier = nil; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
159 session.push_settings = nil; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
160 session.first_hibernated_push = nil; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
161 end |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
162 end |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
163 end |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
164 -- save changed global config |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
165 changed = true; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
166 user_push_services[push_identifier] = nil |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
167 push_errors[push_identifier] = nil; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
168 -- unhook iq handlers for this identifier (if possible) |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
169 if module.unhook then |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
170 module:unhook("iq-error/host/"..stanza_id, handle_push_error); |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
171 module:unhook("iq-result/host/"..stanza_id, handle_push_success); |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
172 id2node[stanza_id] = nil; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
173 end |
3319 | 174 end |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
175 elseif user_push_services[push_identifier] and user_push_services[push_identifier].jid == from and error_type == "wait" then |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
176 module:log("debug", "Got error of type '%s' (%s) for identifier '%s': " |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
177 .."NOT increasing error count for this identifier", error_type, condition, push_identifier); |
3319 | 178 end |
179 end | |
180 end | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
181 if changed then |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
182 push_store:set(node, user_push_services); |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
183 end |
3319 | 184 return true; |
185 end | |
186 | |
187 function handle_push_success(event) | |
188 local stanza = event.stanza; | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
189 local node = id2node[stanza.attr.id]; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
190 if node == nil then return false; end -- unknown stanza? Ignore for now! |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
191 local from = stanza.attr.from; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
192 local user_push_services = push_store:get(node); |
3319 | 193 |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
194 for push_identifier, _ in pairs(user_push_services) do |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
195 if hashes.sha256(push_identifier, true) == stanza.attr.id then |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
196 if user_push_services[push_identifier] and user_push_services[push_identifier].jid == from and push_errors[push_identifier] > 0 then |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
197 push_errors[push_identifier] = 0; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
198 module:log("debug", "Push succeeded, error count for identifier '%s' is now at %s again", push_identifier, tostring(push_errors[push_identifier])); |
3319 | 199 end |
200 end | |
201 end | |
202 return true; | |
203 end | |
204 | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
205 -- http://xmpp.org/extensions/xep-0357.html#disco |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
206 local function account_dico_info(event) |
3319 | 207 (event.reply or event.stanza):tag("feature", {var=xmlns_push}):up(); |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
208 end |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
209 module:hook("account-disco-info", account_dico_info); |
3319 | 210 |
211 -- http://xmpp.org/extensions/xep-0357.html#enabling | |
212 local function push_enable(event) | |
213 local origin, stanza = event.origin, event.stanza; | |
214 local enable = stanza.tags[1]; | |
215 origin.log("debug", "Attempting to enable push notifications"); | |
216 -- MUST contain a 'jid' attribute of the XMPP Push Service being enabled | |
217 local push_jid = enable.attr.jid; | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
218 -- SHOULD contain a 'node' attribute |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
219 local push_node = enable.attr.node; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
220 -- CAN contain a 'include_payload' attribute |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
221 local include_payload = enable.attr.include_payload; |
3319 | 222 if not push_jid then |
223 origin.log("debug", "MUC Push notification enable request missing the 'jid' field"); | |
224 origin.send(st.error_reply(stanza, "modify", "bad-request", "Missing jid")); | |
225 return true; | |
226 end | |
227 local publish_options = enable:get_child("x", "jabber:x:data"); | |
228 if not publish_options then | |
229 -- Could be intentional | |
230 origin.log("debug", "No publish options in request"); | |
231 end | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
232 local push_identifier = push_jid .. "<" .. (push_node or ""); |
3319 | 233 local push_service = { |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
234 jid = push_jid; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
235 node = push_node; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
236 include_payload = include_payload; |
3319 | 237 options = publish_options and st.preserialize(publish_options); |
238 timestamp = os_time(); | |
239 }; | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
240 local ok = push_store:set_identifier(origin.username.."@"..origin.host, push_identifier, push_service); |
3319 | 241 if not ok then |
242 origin.send(st.error_reply(stanza, "wait", "internal-server-error")); | |
243 else | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
244 origin.push_identifier = push_identifier; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
245 origin.push_settings = push_service; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
246 origin.first_hibernated_push = nil; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
247 origin.log("info", "MUC Push notifications enabled for %s by %s (%s)", |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
248 tostring(stanza.attr.to), |
3319 | 249 tostring(stanza.attr.from), |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
250 tostring(origin.push_identifier) |
3319 | 251 ); |
252 origin.send(st.reply(stanza)); | |
253 end | |
254 return true; | |
255 end | |
256 module:hook("iq-set/host/"..xmlns_push..":enable", push_enable); | |
257 | |
258 | |
259 -- http://xmpp.org/extensions/xep-0357.html#disabling | |
260 local function push_disable(event) | |
261 local origin, stanza = event.origin, event.stanza; | |
262 local push_jid = stanza.tags[1].attr.jid; -- MUST include a 'jid' attribute | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
263 local push_node = stanza.tags[1].attr.node; -- A 'node' attribute MAY be included |
3319 | 264 if not push_jid then |
265 origin.send(st.error_reply(stanza, "modify", "bad-request", "Missing jid")); | |
266 return true; | |
267 end | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
268 local user_push_services = push_store:get(origin.username); |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
269 for key, push_info in pairs(user_push_services) do |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
270 if push_info.jid == push_jid and (not push_node or push_info.node == push_node) then |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
271 origin.log("info", "Push notifications disabled (%s)", tostring(key)); |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
272 if origin.push_identifier == key then |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
273 origin.push_identifier = nil; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
274 origin.push_settings = nil; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
275 origin.first_hibernated_push = nil; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
276 end |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
277 user_push_services[key] = nil; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
278 push_errors[key] = nil; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
279 if module.unhook then |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
280 module:unhook("iq-error/host/"..key, handle_push_error); |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
281 module:unhook("iq-result/host/"..key, handle_push_success); |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
282 id2node[key] = nil; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
283 end |
3319 | 284 end |
285 end | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
286 local ok = push_store:set(origin.username, user_push_services); |
3319 | 287 if not ok then |
288 origin.send(st.error_reply(stanza, "wait", "internal-server-error")); | |
289 else | |
290 origin.send(st.reply(stanza)); | |
291 end | |
292 return true; | |
293 end | |
294 module:hook("iq-set/host/"..xmlns_push..":disable", push_disable); | |
295 | |
296 -- Patched version of util.stanza:find() that supports giving stanza names | |
297 -- without their namespace, allowing for every namespace. | |
298 local function find(self, path) | |
299 local pos = 1; | |
300 local len = #path + 1; | |
301 | |
302 repeat | |
303 local xmlns, name, text; | |
304 local char = s_sub(path, pos, pos); | |
305 if char == "@" then | |
306 return self.attr[s_sub(path, pos + 1)]; | |
307 elseif char == "{" then | |
308 xmlns, pos = s_match(path, "^([^}]+)}()", pos + 1); | |
309 end | |
310 name, text, pos = s_match(path, "^([^@/#]*)([/#]?)()", pos); | |
311 name = name ~= "" and name or nil; | |
312 if pos == len then | |
313 if text == "#" then | |
314 local child = xmlns ~= nil and self:get_child(name, xmlns) or self:child_with_name(name); | |
315 return child and child:get_text() or nil; | |
316 end | |
317 return xmlns ~= nil and self:get_child(name, xmlns) or self:child_with_name(name); | |
318 end | |
319 self = xmlns ~= nil and self:get_child(name, xmlns) or self:child_with_name(name); | |
320 until not self | |
321 return nil; | |
322 end | |
323 | |
324 -- is this push a high priority one (this is needed for ios apps not using voip pushes) | |
325 local function is_important(stanza) | |
326 local st_name = stanza and stanza.name or nil; | |
327 if not st_name then return false; end -- nonzas are never important here | |
328 if st_name == "presence" then | |
329 return false; -- same for presences | |
330 elseif st_name == "message" then | |
331 -- unpack carbon copies | |
332 local stanza_direction = "in"; | |
333 local carbon; | |
334 local st_type; | |
335 -- support carbon copied message stanzas having an arbitrary message-namespace or no message-namespace at all | |
336 if not carbon then carbon = find(stanza, "{urn:xmpp:carbons:2}/forwarded/message"); end | |
337 if not carbon then carbon = find(stanza, "{urn:xmpp:carbons:1}/forwarded/message"); end | |
338 stanza_direction = carbon and stanza:child_with_name("sent") and "out" or "in"; | |
339 if carbon then stanza = carbon; end | |
340 st_type = stanza.attr.type; | |
341 | |
342 -- headline message are always not important | |
343 if st_type == "headline" then return false; end | |
344 | |
345 -- carbon copied outgoing messages are not important | |
346 if carbon and stanza_direction == "out" then return false; end | |
347 | |
348 -- We can't check for body contents in encrypted messages, so let's treat them as important | |
349 -- Some clients don't even set a body or an empty body for encrypted messages | |
350 | |
351 -- check omemo https://xmpp.org/extensions/inbox/omemo.html | |
352 if stanza:get_child("encrypted", "eu.siacs.conversations.axolotl") or stanza:get_child("encrypted", "urn:xmpp:omemo:0") then return true; end | |
353 | |
354 -- check xep27 pgp https://xmpp.org/extensions/xep-0027.html | |
355 if stanza:get_child("x", "jabber:x:encrypted") then return true; end | |
356 | |
357 -- check xep373 pgp (OX) https://xmpp.org/extensions/xep-0373.html | |
358 if stanza:get_child("openpgp", "urn:xmpp:openpgp:0") then return true; end | |
359 | |
360 local body = stanza:get_child_text("body"); | |
361 if st_type == "groupchat" and stanza:get_child_text("subject") then return false; end -- groupchat subjects are not important here | |
362 return body ~= nil and body ~= ""; -- empty bodies are not important | |
363 end | |
364 return false; -- this stanza wasn't one of the above cases --> it is not important, too | |
365 end | |
366 | |
367 local push_form = dataform { | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
368 { name = "FORM_TYPE"; type = "hidden"; value = "urn:xmpp:push:summary"; }; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
369 { name = "message-count"; type = "text-single"; }; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
370 { name = "pending-subscription-count"; type = "text-single"; }; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
371 { name = "last-message-sender"; type = "jid-single"; }; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
372 { name = "last-message-body"; type = "text-single"; }; |
3319 | 373 }; |
374 | |
375 -- http://xmpp.org/extensions/xep-0357.html#publishing | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
376 local function handle_notify_request(stanza, node, user_push_services, log_push_decline) |
3319 | 377 local pushes = 0; |
378 if not user_push_services or next(user_push_services) == nil then return pushes end | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
379 |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
380 -- XXX: customized |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
381 local body = stanza:get_child_text("body"); |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
382 if not body then |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
383 return pushes; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
384 end |
3319 | 385 |
386 for push_identifier, push_info in pairs(user_push_services) do | |
387 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 | |
388 if stanza then | |
389 if not stanza._push_notify then stanza._push_notify = {}; end | |
390 if stanza._push_notify[push_identifier] then | |
391 if log_push_decline then | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
392 module:log("debug", "Already sent push notification for %s@%s to %s (%s)", node, module.host, push_info.jid, tostring(push_info.node)); |
3319 | 393 end |
394 send_push = false; | |
395 end | |
396 stanza._push_notify[push_identifier] = true; | |
397 end | |
398 | |
399 if send_push then | |
400 -- construct push stanza | |
401 local stanza_id = hashes.sha256(push_identifier, true); | |
402 local push_publish = st.iq({ to = push_info.jid, from = module.host, type = "set", id = stanza_id }) | |
403 :tag("pubsub", { xmlns = "http://jabber.org/protocol/pubsub" }) | |
404 :tag("publish", { node = push_info.node }) | |
405 :tag("item") | |
406 :tag("notification", { xmlns = xmlns_push }); | |
407 local form_data = { | |
408 -- hardcode to 1 because other numbers are just meaningless (the XEP does not specify *what exactly* to count) | |
409 ["message-count"] = "1"; | |
410 }; | |
411 if stanza and include_sender then | |
412 form_data["last-message-sender"] = stanza.attr.from; | |
413 end | |
414 if stanza and include_body then | |
415 form_data["last-message-body"] = stanza:get_child_text("body"); | |
416 elseif stanza and dummy_body and is_important(stanza) then | |
417 form_data["last-message-body"] = tostring(dummy_body); | |
418 end | |
419 push_publish:add_child(push_form:form(form_data)); | |
420 push_publish:up(); -- / notification | |
421 push_publish:up(); -- / publish | |
422 push_publish:up(); -- / pubsub | |
423 if push_info.options then | |
424 push_publish:tag("publish-options"):add_child(st.deserialize(push_info.options)); | |
425 end | |
426 -- send out push | |
427 module:log("debug", "Sending%s push notification for %s@%s to %s (%s)", form_data["last-message-body"] and " important" or "", node, module.host, push_info.jid, tostring(push_info.node)); | |
428 -- module:log("debug", "PUSH STANZA: %s", tostring(push_publish)); | |
429 -- handle push errors for this node | |
430 if push_errors[push_identifier] == nil then | |
431 push_errors[push_identifier] = 0; | |
432 module:hook("iq-error/host/"..stanza_id, handle_push_error); | |
433 module:hook("iq-result/host/"..stanza_id, handle_push_success); | |
434 id2node[stanza_id] = node; | |
435 end | |
436 module:send(push_publish); | |
437 pushes = pushes + 1; | |
438 end | |
439 end | |
440 return pushes; | |
441 end | |
442 | |
3570
8a93af85f319
mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents:
3319
diff
changeset
|
443 local function extract_reference(text, i, j) |
8a93af85f319
mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents:
3319
diff
changeset
|
444 -- COMPAT w/ pre-Lua 5.3 |
8a93af85f319
mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents:
3319
diff
changeset
|
445 local c, pos, p1 = 0, 0, nil; |
8a93af85f319
mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents:
3319
diff
changeset
|
446 for char in text:gmatch("([%z\1-\127\194-\244][\128-\191]*)") do |
8a93af85f319
mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents:
3319
diff
changeset
|
447 c, pos = c + 1, pos + #char; |
8a93af85f319
mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents:
3319
diff
changeset
|
448 if not p1 and i < c then |
8a93af85f319
mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents:
3319
diff
changeset
|
449 p1 = pos; |
8a93af85f319
mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents:
3319
diff
changeset
|
450 end |
8a93af85f319
mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents:
3319
diff
changeset
|
451 if c == j then |
8a93af85f319
mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents:
3319
diff
changeset
|
452 return text:sub(p1, pos); |
8a93af85f319
mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents:
3319
diff
changeset
|
453 end |
8a93af85f319
mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents:
3319
diff
changeset
|
454 end |
8a93af85f319
mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents:
3319
diff
changeset
|
455 end |
3319 | 456 |
457 -- archive message added | |
458 local function archive_message_added(event) | |
459 -- event is: { origin = origin, stanza = stanza, for_user = store_user, id = id } | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
460 -- only notify for new mam messages when at least one device is online |
3319 | 461 local room = event.room; |
462 local stanza = event.stanza; | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
463 local body = stanza:get_child_text('body'); |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
464 |
3319 | 465 for reference in stanza:childtags("reference", "urn:xmpp:reference:0") do |
466 if reference.attr['type'] == 'mention' and reference.attr['begin'] and reference.attr['end'] then | |
3570
8a93af85f319
mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents:
3319
diff
changeset
|
467 local nick = extract_reference(body, reference.attr['begin'], reference.attr['end']); |
3319 | 468 local jid = room:get_registered_jid(nick); |
469 | |
470 if room._occupants[room.jid..'/'..nick] then | |
471 -- We only notify for members not currently in the room | |
472 module:log("debug", "Not notifying %s, because he's currently in the room", jid); | |
473 else | |
474 -- We only need to notify once, even when there are multiple mentions. | |
475 local user_push_services = push_store:get(jid); | |
476 handle_notify_request(event.stanza, jid, user_push_services, true); | |
477 return | |
478 end | |
479 end | |
480 end | |
481 end | |
482 | |
483 module:hook("muc-add-history", archive_message_added); | |
484 | |
485 local function send_ping(event) | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
486 local user = event.user; |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
487 local user_push_services = push_store:get(user); |
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
488 local push_services = event.push_services or user_push_services; |
3319 | 489 handle_notify_request(nil, user, push_services, true); |
490 end | |
491 -- can be used by other modules to ping one or more (or all) push endpoints | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
492 module:hook("cloud-notify-ping", send_ping); |
3319 | 493 |
494 module:log("info", "Module loaded"); | |
495 function module.unload() | |
496 if module.unhook then | |
497 module:unhook("account-disco-info", account_dico_info); | |
498 module:unhook("iq-set/host/"..xmlns_push..":enable", push_enable); | |
499 module:unhook("iq-set/host/"..xmlns_push..":disable", push_disable); | |
500 | |
501 module:unhook("muc-add-history", archive_message_added); | |
502 module:unhook("cloud-notify-ping", send_ping); | |
503 | |
504 for push_identifier, _ in pairs(push_errors) do | |
505 local stanza_id = hashes.sha256(push_identifier, true); | |
506 module:unhook("iq-error/host/"..stanza_id, handle_push_error); | |
507 module:unhook("iq-result/host/"..stanza_id, handle_push_success); | |
3883
571249f69577
mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents:
3882
diff
changeset
|
508 id2node[stanza_id] = nil; |
3319 | 509 end |
510 end | |
511 | |
512 module:log("info", "Module unloaded"); | |
513 end |