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