mod_pubsub_text_interface/mod_pubsub_text_interface.lua
author Ben Smith <bens@effortlessis.com>
Tue, 14 May 2024 07:31:34 -0700
changeset 5912 dcea4b4c415d
parent 5138 e0d0ef564095
permissions -rw-r--r--
Tweaking documentation to clarify that Oauth2 can be used for VirtualHosts and Component installations.
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);