mod_muc_adhoc_bots/mod_muc_adhoc_bots.lua
author Kim Alvefur <zash@zash.se>
Sun, 03 Mar 2024 11:23:40 +0100
changeset 5857 97c9b76867ca
parent 5850 8b868c00e38e
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:
5656
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
     1
local jid = require "util.jid";
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
     2
local json = require "util.json";
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
     3
local promise = require "util.promise";
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
     4
local st = require "util.stanza";
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
     5
local uuid = require "util.uuid";
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
     6
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
     7
local xmlns_cmd = "http://jabber.org/protocol/commands";
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
     8
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
     9
module:hook("muc-disco#info", function(event)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    10
	event.reply:tag("feature", {var = xmlns_cmd}):up();
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    11
end);
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    12
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    13
module:hook("iq-get/bare/http://jabber.org/protocol/disco#items:query", function (event)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    14
	local room = prosody.hosts[module:get_host()].modules.muc.get_room_from_jid(event.stanza.attr.to);
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    15
	local occupant = room:get_occupant_by_real_jid(event.stanza.attr.from)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    16
	if event.stanza.tags[1].attr.node ~= xmlns_cmd or not occupant then
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    17
		return
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    18
	end
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    19
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    20
	local bots = module:get_option_array("adhoc_bots", {})
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    21
	bots:map(function(bot)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    22
		return module:send_iq(
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    23
			st.iq({ type = "get", id = uuid.generate(), to = bot, from = room:get_occupant_jid(event.stanza.attr.from) })
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    24
				:tag("query", { xmlns = "http://jabber.org/protocol/disco#items", node = xmlns_cmd }):up(),
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    25
			nil,
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    26
			5
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    27
		)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    28
	end)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    29
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    30
	promise.all_settled(bots):next(function (bot_commands)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    31
		local reply = st.reply(event.stanza):query("http://jabber.org/protocol/disco#items")
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    32
		for i, one_bot_reply in ipairs(bot_commands) do
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    33
			if one_bot_reply.status == "fulfilled"	then
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    34
			local query = one_bot_reply.value.stanza:get_child("query", "http://jabber.org/protocol/disco#items")
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    35
				if query then
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    36
					-- Should use query:childtags("item") but it doesn't work
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    37
					for j,item in ipairs(query.tags) do
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    38
						item.attr.node = json.encode({ jid = item.attr.jid, node = item.attr.node })
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    39
						item.attr.jid = event.stanza.attr.to
5850
8b868c00e38e mod_muc_adhoc_bots: Fix bug preventing multiple commands from showing
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5656
diff changeset
    40
						reply:add_child(item)
5656
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    41
					end
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    42
				end
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    43
			end
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    44
		end
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    45
		event.origin.send(reply:up())
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    46
	end):catch(function (e)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    47
		module:log("error", e)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    48
	end)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    49
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    50
	return true;
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    51
end, 500);
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    52
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    53
local function is_adhoc_bot(jid)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    54
	for i, bot_jid in ipairs(module:get_option_array("adhoc_bots", {})) do
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    55
		if jid == bot_jid then
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    56
			return true
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    57
		end
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    58
	end
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    59
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    60
	return false
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    61
end
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    62
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    63
module:hook("iq-set/bare/"..xmlns_cmd..":command", function (event)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    64
	local origin, stanza = event.origin, event.stanza;
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    65
	local node = stanza.tags[1].attr.node
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    66
	local meta = json.decode(node)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    67
	local room = prosody.hosts[module:get_host()].modules.muc.get_room_from_jid(stanza.attr.to);
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    68
	local occupant = room:get_occupant_by_real_jid(event.stanza.attr.from)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    69
	if meta and occupant and is_adhoc_bot(meta.jid) then
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    70
		local fwd = st.clone(stanza)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    71
		fwd.attr.to = meta.jid
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    72
		fwd.attr.from = room:get_occupant_jid(event.stanza.attr.from)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    73
		local command = fwd:get_child("command", "http://jabber.org/protocol/commands")
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    74
		command.attr.node = meta.node
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    75
		module:send_iq(fwd):next(function(response)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    76
			local response_command = response.stanza:get_child("command", "http://jabber.org/protocol/commands")
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    77
			response.stanza.attr.from = stanza.attr.to
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    78
			response.stanza.attr.to = stanza.attr.from
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    79
			response_command.attr.node = node
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    80
			origin.send(response.stanza)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    81
		end):catch(function (e)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    82
			module:log("error", e)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    83
		end)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    84
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    85
		return true
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    86
	end
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    87
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    88
	return
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    89
end, 500);
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    90
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    91
local function clean_xmlns(node)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    92
		-- Recursively remove "jabber:client" attribute from node.
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    93
		-- In Prosody internal routing, xmlns should not be set.
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    94
		-- Keeping xmlns would lead to issues like mod_smacks ignoring the outgoing stanza,
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    95
		-- so we remove all xmlns attributes with a value of "jabber:client"
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    96
		if node.attr.xmlns == 'jabber:client' then
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    97
				for childnode in node:childtags() do
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    98
						clean_xmlns(childnode)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    99
				end
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   100
				node.attr.xmlns = nil
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   101
		end
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   102
end
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   103
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   104
module:hook("message/bare", function (event)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   105
	local origin, stanza = event.origin, event.stanza;
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   106
	if not is_adhoc_bot(stanza.attr.from) then return; end
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   107
	local room = prosody.hosts[module:get_host()].modules.muc.get_room_from_jid(stanza.attr.to);
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   108
	if room == nil then return; end
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   109
	local privilege = stanza:get_child("privilege", "urn:xmpp:privilege:2")
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   110
	if privilege == nil then return; end
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   111
	local fwd = privilege:get_child("forwarded", "urn:xmpp:forward:0")
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   112
	if fwd == nil then return; end
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   113
	local message = fwd:get_child("message", "jabber:client")
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   114
	if message == nil then return; end
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   115
	if message.attr.to ~= stanza.attr.to or jid.bare(message.attr.from) ~= stanza.attr.to then
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   116
		return
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   117
	end
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   118
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   119
	clean_xmlns(message)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   120
	room:broadcast_message(message)
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   121
	return true
eade7ff9f52c mod_muc_adhoc_bots: add module
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   122
end)