mod_pubsub_text_interface/mod_pubsub_text_interface.lua
author Kim Alvefur <zash@zash.se>
Sun, 03 Mar 2024 11:23:40 +0100
changeset 5857 97c9b76867ca
parent 5138 e0d0ef564095
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:
3247
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     1
local st = require "util.stanza";
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     2
local jid = require "util.jid";
3251
ada7a0c7221c mod_pubsub_text_interface: Generate a stanza id for replies
Kim Alvefur <zash@zash.se>
parents: 3247
diff changeset
     3
local id = require "util.id";
3247
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     4
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     5
local pubsub = module:depends "pubsub".service;
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     6
4045
cb5ea9d25cb2 mod_pubsub_text_interface: Hint at possible commands using XEP-0439: Quick Response
Kim Alvefur <zash@zash.se>
parents: 3648
diff changeset
     7
local xmlns_quick_resp = "urn:xmpp:tmp:quick-response";
3247
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     8
local name = module:get_option_string("name", "PubSub Service on "..module.host);
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     9
local help = name..[[
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    10
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    11
Commands:
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    12
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    13
- `help` - this help message
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    14
- `list` - list available nodes
3492
4ddb034a8a03 mod_pubsub_text_interface: Add command for listing current subscriptions
Kim Alvefur <zash@zash.se>
parents: 3433
diff changeset
    15
- `subscriptions` - list nodes you are subscribed to
5138
e0d0ef564095 mod_pubsub_text_interface: Try to clarify help message wrt node arguments
Kim Alvefur <zash@zash.se>
parents: 5137
diff changeset
    16
- `subscribe NODE` - subscribe to a node
e0d0ef564095 mod_pubsub_text_interface: Try to clarify help message wrt node arguments
Kim Alvefur <zash@zash.se>
parents: 5137
diff changeset
    17
- `unsubscribe NODE` - unsubscribe from a node]];
3332
7d39ffd058d5 mod_pubsub_text_interface: Handle lack of `pubsub:get_last_item` in Prosody 0.10
Kim Alvefur <zash@zash.se>
parents: 3297
diff changeset
    18
if pubsub.get_last_item then -- COMPAT not available in 0.10
5138
e0d0ef564095 mod_pubsub_text_interface: Try to clarify help message wrt node arguments
Kim Alvefur <zash@zash.se>
parents: 5137
diff changeset
    19
	help = help ..  "\n- `last NODE` - send the last item (again)"
3332
7d39ffd058d5 mod_pubsub_text_interface: Handle lack of `pubsub:get_last_item` in Prosody 0.10
Kim Alvefur <zash@zash.se>
parents: 3297
diff changeset
    20
end
5137
d7652471ae3e mod_pubsub_text_interface: Improve error messages
Kim Alvefur <zash@zash.se>
parents: 4649
diff changeset
    21
-- FIXME better word for "node"
d7652471ae3e mod_pubsub_text_interface: Improve error messages
Kim Alvefur <zash@zash.se>
parents: 4649
diff changeset
    22
d7652471ae3e mod_pubsub_text_interface: Improve error messages
Kim Alvefur <zash@zash.se>
parents: 4649
diff changeset
    23
local friendly_pubsub_errors = {
d7652471ae3e mod_pubsub_text_interface: Improve error messages
Kim Alvefur <zash@zash.se>
parents: 4649
diff changeset
    24
	["forbidden"] = "You are not allowed to do that";
d7652471ae3e mod_pubsub_text_interface: Improve error messages
Kim Alvefur <zash@zash.se>
parents: 4649
diff changeset
    25
	["item-not-found"] = "That node does not exist";
d7652471ae3e mod_pubsub_text_interface: Improve error messages
Kim Alvefur <zash@zash.se>
parents: 4649
diff changeset
    26
	["internal-server-error"] = "Something went wrong (see server logs)";
d7652471ae3e mod_pubsub_text_interface: Improve error messages
Kim Alvefur <zash@zash.se>
parents: 4649
diff changeset
    27
	["not-subscribed"] = "You were not subscribed";
d7652471ae3e mod_pubsub_text_interface: Improve error messages
Kim Alvefur <zash@zash.se>
parents: 4649
diff changeset
    28
};
3247
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    29
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    30
module:hook("message/host", function (event)
3493
33b3f02a9e7d mod_pubsub_text_interface: Remove unused variable [luacheck]
Kim Alvefur <zash@zash.se>
parents: 3492
diff changeset
    31
	local stanza = event.stanza;
3247
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    32
	local body = stanza:get_child_text("body");
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    33
	if not body then return end -- bail out
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    34
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    35
	local from = stanza.attr.from;
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    36
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    37
	local reply = st.reply(stanza);
3251
ada7a0c7221c mod_pubsub_text_interface: Generate a stanza id for replies
Kim Alvefur <zash@zash.se>
parents: 3247
diff changeset
    38
	reply.attr.id = id.medium();
3247
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    39
3253
8f4a7084c466 mod_pubsub_text_interface: Rename variable to avoid name clash [luacheck]
Kim Alvefur <zash@zash.se>
parents: 3252
diff changeset
    40
	local command, node_arg = body:match("^(%a+)%s+(.*)");
3254
5801b5cf8f54 mod_pubsub_text_interface: Ignore whitespace after all commands
Kim Alvefur <zash@zash.se>
parents: 3253
diff changeset
    41
	command = (command or body):lower();
3252
ecec46f7d020 mod_pubsub_text_interface: Fix chain that accidentally produced nested <body>
Kim Alvefur <zash@zash.se>
parents: 3251
diff changeset
    42
3254
5801b5cf8f54 mod_pubsub_text_interface: Ignore whitespace after all commands
Kim Alvefur <zash@zash.se>
parents: 3253
diff changeset
    43
	if command == "help" then
4648
bbf9e36db3a9 mod_pubsub_text_interface: Fix move quick response tags out of <body>
Kim Alvefur <zash@zash.se>
parents: 4493
diff changeset
    44
		reply:body(help):up();
4045
cb5ea9d25cb2 mod_pubsub_text_interface: Hint at possible commands using XEP-0439: Quick Response
Kim Alvefur <zash@zash.se>
parents: 3648
diff changeset
    45
		reply:tag("response", { xmlns = xmlns_quick_resp, value = "list", }):up();
cb5ea9d25cb2 mod_pubsub_text_interface: Hint at possible commands using XEP-0439: Quick Response
Kim Alvefur <zash@zash.se>
parents: 3648
diff changeset
    46
		reply:tag("response", { xmlns = xmlns_quick_resp, value = "subscriptions", }):up();
3254
5801b5cf8f54 mod_pubsub_text_interface: Ignore whitespace after all commands
Kim Alvefur <zash@zash.se>
parents: 3253
diff changeset
    47
	elseif command == "list" then
3247
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    48
		local ok, nodes = pubsub:get_nodes(from);
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    49
		if ok then
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    50
			local list = {};
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    51
			for node, node_obj in pairs(nodes) do
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    52
				table.insert(list, ("- `%s` %s"):format(node, node_obj.config.title or ""));
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    53
			end
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    54
			reply:body(table.concat(list, "\n"));
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    55
		else
5137
d7652471ae3e mod_pubsub_text_interface: Improve error messages
Kim Alvefur <zash@zash.se>
parents: 4649
diff changeset
    56
			reply:body(friendly_pubsub_errors[nodes] or nodes);
3247
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    57
		end
3492
4ddb034a8a03 mod_pubsub_text_interface: Add command for listing current subscriptions
Kim Alvefur <zash@zash.se>
parents: 3433
diff changeset
    58
	elseif command == "subscriptions" then
4ddb034a8a03 mod_pubsub_text_interface: Add command for listing current subscriptions
Kim Alvefur <zash@zash.se>
parents: 3433
diff changeset
    59
		local ok, subs = pubsub:get_subscriptions(nil, from, from);
4ddb034a8a03 mod_pubsub_text_interface: Add command for listing current subscriptions
Kim Alvefur <zash@zash.se>
parents: 3433
diff changeset
    60
		if not ok then
5137
d7652471ae3e mod_pubsub_text_interface: Improve error messages
Kim Alvefur <zash@zash.se>
parents: 4649
diff changeset
    61
			reply:body(friendly_pubsub_errors[subs] or subs);
3492
4ddb034a8a03 mod_pubsub_text_interface: Add command for listing current subscriptions
Kim Alvefur <zash@zash.se>
parents: 3433
diff changeset
    62
		elseif #subs == 0 then
4ddb034a8a03 mod_pubsub_text_interface: Add command for listing current subscriptions
Kim Alvefur <zash@zash.se>
parents: 3433
diff changeset
    63
			reply:body("You are not subscribed to anything from this pubsub service");
4ddb034a8a03 mod_pubsub_text_interface: Add command for listing current subscriptions
Kim Alvefur <zash@zash.se>
parents: 3433
diff changeset
    64
		else
4ddb034a8a03 mod_pubsub_text_interface: Add command for listing current subscriptions
Kim Alvefur <zash@zash.se>
parents: 3433
diff changeset
    65
			local response = {};
4ddb034a8a03 mod_pubsub_text_interface: Add command for listing current subscriptions
Kim Alvefur <zash@zash.se>
parents: 3433
diff changeset
    66
			for i = 1, #subs do
4ddb034a8a03 mod_pubsub_text_interface: Add command for listing current subscriptions
Kim Alvefur <zash@zash.se>
parents: 3433
diff changeset
    67
				response[i] = string.format("- `%s`", subs[i].node);
4045
cb5ea9d25cb2 mod_pubsub_text_interface: Hint at possible commands using XEP-0439: Quick Response
Kim Alvefur <zash@zash.se>
parents: 3648
diff changeset
    68
				reply:tag("response", { xmlns = xmlns_quick_resp, value = "unsubscribe "..subs[i].node, }):up();
cb5ea9d25cb2 mod_pubsub_text_interface: Hint at possible commands using XEP-0439: Quick Response
Kim Alvefur <zash@zash.se>
parents: 3648
diff changeset
    69
				reply:tag("response", { xmlns = xmlns_quick_resp, value = "last "..subs[i].node, }):up();
3492
4ddb034a8a03 mod_pubsub_text_interface: Add command for listing current subscriptions
Kim Alvefur <zash@zash.se>
parents: 3433
diff changeset
    70
			end
4ddb034a8a03 mod_pubsub_text_interface: Add command for listing current subscriptions
Kim Alvefur <zash@zash.se>
parents: 3433
diff changeset
    71
			reply:body(table.concat(response, "\n"));
4ddb034a8a03 mod_pubsub_text_interface: Add command for listing current subscriptions
Kim Alvefur <zash@zash.se>
parents: 3433
diff changeset
    72
		end
3252
ecec46f7d020 mod_pubsub_text_interface: Fix chain that accidentally produced nested <body>
Kim Alvefur <zash@zash.se>
parents: 3251
diff changeset
    73
	elseif command == "subscribe" then
3253
8f4a7084c466 mod_pubsub_text_interface: Rename variable to avoid name clash [luacheck]
Kim Alvefur <zash@zash.se>
parents: 3252
diff changeset
    74
		local ok, err = pubsub:add_subscription(node_arg, from, jid.bare(from), { ["pubsub#include_body"] = true });
5137
d7652471ae3e mod_pubsub_text_interface: Improve error messages
Kim Alvefur <zash@zash.se>
parents: 4649
diff changeset
    75
		reply:body(ok and "OK" or friendly_pubsub_errors[err] or err);
3247
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    76
	elseif command == "unsubscribe" then
3253
8f4a7084c466 mod_pubsub_text_interface: Rename variable to avoid name clash [luacheck]
Kim Alvefur <zash@zash.se>
parents: 3252
diff changeset
    77
		local ok, err = pubsub:remove_subscription(node_arg, from, jid.bare(from));
5137
d7652471ae3e mod_pubsub_text_interface: Improve error messages
Kim Alvefur <zash@zash.se>
parents: 4649
diff changeset
    78
		reply:body(ok and "OK" or friendly_pubsub_errors[err] or err);
3332
7d39ffd058d5 mod_pubsub_text_interface: Handle lack of `pubsub:get_last_item` in Prosody 0.10
Kim Alvefur <zash@zash.se>
parents: 3297
diff changeset
    79
	elseif command == "last" and pubsub.get_last_item then
3297
f728c8c42860 mod_pubsub_text_interface: Add a 'last' command for sending the last item
Kim Alvefur <zash@zash.se>
parents: 3254
diff changeset
    80
		local ok, item_id, item = pubsub:get_last_item(node_arg, from);
f728c8c42860 mod_pubsub_text_interface: Add a 'last' command for sending the last item
Kim Alvefur <zash@zash.se>
parents: 3254
diff changeset
    81
		if not ok then
5137
d7652471ae3e mod_pubsub_text_interface: Improve error messages
Kim Alvefur <zash@zash.se>
parents: 4649
diff changeset
    82
			reply:body(friendly_pubsub_errors[item_id] or item_id);
3297
f728c8c42860 mod_pubsub_text_interface: Add a 'last' command for sending the last item
Kim Alvefur <zash@zash.se>
parents: 3254
diff changeset
    83
		elseif not item_id then
5137
d7652471ae3e mod_pubsub_text_interface: Improve error messages
Kim Alvefur <zash@zash.se>
parents: 4649
diff changeset
    84
			reply:body("That node does not contain any items");
3297
f728c8c42860 mod_pubsub_text_interface: Add a 'last' command for sending the last item
Kim Alvefur <zash@zash.se>
parents: 3254
diff changeset
    85
		else
f728c8c42860 mod_pubsub_text_interface: Add a 'last' command for sending the last item
Kim Alvefur <zash@zash.se>
parents: 3254
diff changeset
    86
			pubsub.config.broadcaster("items", node_arg, {
f728c8c42860 mod_pubsub_text_interface: Add a 'last' command for sending the last item
Kim Alvefur <zash@zash.se>
parents: 3254
diff changeset
    87
				[from] = { ["pubsub#include_body"] = true }
4493
725768d83830 mod_pubsub_text_interface: Pass node object to broadcaster for config access
Kim Alvefur <zash@zash.se>
parents: 4238
diff changeset
    88
			}, item, nil, pubsub.nodes[node_arg]);
3297
f728c8c42860 mod_pubsub_text_interface: Add a 'last' command for sending the last item
Kim Alvefur <zash@zash.se>
parents: 3254
diff changeset
    89
			reply:body("OK");
f728c8c42860 mod_pubsub_text_interface: Add a 'last' command for sending the last item
Kim Alvefur <zash@zash.se>
parents: 3254
diff changeset
    90
		end
3247
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    91
	else
4649
25ce28711fac mod_pubsub_text_interface: Move quick response out of unknown command text
Kim Alvefur <zash@zash.se>
parents: 4648
diff changeset
    92
		reply:body("Unknown command. `help` to list commands."):up();
4045
cb5ea9d25cb2 mod_pubsub_text_interface: Hint at possible commands using XEP-0439: Quick Response
Kim Alvefur <zash@zash.se>
parents: 3648
diff changeset
    93
		reply:tag("response", { xmlns = xmlns_quick_resp, value = "help", }):up();
3247
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    94
	end
3648
9980ea72ff91 mod_pubsub_text_interface: Respond to receipts
Kim Alvefur <zash@zash.se>
parents: 3493
diff changeset
    95
	reply:reset();
9980ea72ff91 mod_pubsub_text_interface: Respond to receipts
Kim Alvefur <zash@zash.se>
parents: 3493
diff changeset
    96
4046
78ac5500a844 mod_pubsub_text_interface: Reflect XEP-0334 hints
Kim Alvefur <zash@zash.se>
parents: 4045
diff changeset
    97
	if stanza:get_child("no-copy", "urn:xmpp:hints") then
78ac5500a844 mod_pubsub_text_interface: Reflect XEP-0334 hints
Kim Alvefur <zash@zash.se>
parents: 4045
diff changeset
    98
		reply:tag("no-copy", { xmlns = "urn:xmpp:hints" }):up();
78ac5500a844 mod_pubsub_text_interface: Reflect XEP-0334 hints
Kim Alvefur <zash@zash.se>
parents: 4045
diff changeset
    99
	end
78ac5500a844 mod_pubsub_text_interface: Reflect XEP-0334 hints
Kim Alvefur <zash@zash.se>
parents: 4045
diff changeset
   100
78ac5500a844 mod_pubsub_text_interface: Reflect XEP-0334 hints
Kim Alvefur <zash@zash.se>
parents: 4045
diff changeset
   101
	if stanza:get_child("no-store", "urn:xmpp:hints") then
78ac5500a844 mod_pubsub_text_interface: Reflect XEP-0334 hints
Kim Alvefur <zash@zash.se>
parents: 4045
diff changeset
   102
		reply:tag("no-store", { xmlns = "urn:xmpp:hints" }):up();
78ac5500a844 mod_pubsub_text_interface: Reflect XEP-0334 hints
Kim Alvefur <zash@zash.se>
parents: 4045
diff changeset
   103
	end
78ac5500a844 mod_pubsub_text_interface: Reflect XEP-0334 hints
Kim Alvefur <zash@zash.se>
parents: 4045
diff changeset
   104
3433
1f0c290bd28a mod_pubsub_text_interface: Send replies trough normal stanza routing
Kim Alvefur <zash@zash.se>
parents: 3332
diff changeset
   105
	module:send(reply);
3247
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   106
	return true;
ca856a892719 mod_pubsub_text_interface: A chat interface to PubSub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   107
end);