riddim.plugins.servercontact: Query for XEP-0157: Contact Addresses for XMPP Services

Sun, 20 May 2018 02:16:48 +0200

author
Kim Alvefur <zash@zash.se>
date
Sun, 20 May 2018 02:16:48 +0200
changeset 140
4aa787757235
parent 139
6de453570270
child 141
be0754cc0ede

riddim.plugins.servercontact: Query for XEP-0157: Contact Addresses for XMPP Services

plugins/servercontact.lua file | annotate | diff | comparison | revisions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/servercontact.lua	Sun May 20 02:16:48 2018 +0200
@@ -0,0 +1,95 @@
+local disco_info = "http://jabber.org/protocol/disco#info";
+local verse = require "verse"
+local riddim = require "riddim"
+
+local dataform = require "util.dataforms".new;
+
+local serverinfo_form = dataform {
+	{ value = "http://jabber.org/network/serverinfo"; type = "hidden"; name = "FORM_TYPE"; };
+	{ name = "abuse-addresses", type = "list-multi" };
+	{ name = "admin-addresses", type = "list-multi" };
+	{ name = "feedback-addresses", type = "list-multi" };
+	{ name = "sales-addresses", type = "list-multi" };
+	{ name = "security-addresses", type = "list-multi" };
+	{ name = "support-addresses", type = "list-multi" };
+};
+
+local valid_types = {
+	abuse = true;
+	admin = true;
+	feedback = true;
+	sales = true;
+	security = true;
+	support = true;
+};
+
+function riddim.plugins.servercontact(bot)
+	bot:hook("commands/contact", function (command)
+		local target, typ = command.param;
+		if not target then
+			return "Which server?";
+		elseif target:find("%s") then
+			typ, target = target:match("(%a+)%s*(%S+)");
+			if not valid_types[typ] then
+				command:reply("Valid types are abuse, admin, feedback, sales, security and support");
+				return;
+			end
+		end
+		if target:find("[@/]") then
+			target = target:match("@?([^@/]+)/?");
+		end
+		bot.stream:send_iq(verse.iq({ type = "get", to = target }):query(disco_info), function (reply)
+			if reply.attr.type == "error" then
+				local _, condition, text = reply:get_error();
+				command:reply(("Could not reach %s: %s"):format(command.param, text or condition));
+				return
+			end
+
+			for form in reply.tags[1]:childtags("x", "jabber:x:data") do
+				local data = serverinfo_form:data(form);
+				if data.FORM_TYPE == serverinfo_form[1].value then
+					if typ then
+						local addresses = data[typ .. "-addresses"];
+						if addresses and addresses[1] then
+							command:reply(("%s contacts for %s %s: %s"):format(typ:gsub("^.", string.upper), target, addresses[2] and "are" or "is", table.concat(addresses, " ")));
+						else
+							command:reply(target .. " doesn't have any contact addresses for "..typ);
+						end
+					else
+						local addresses_kinds = {};
+						for kind, addresses in pairs(data) do
+							kind = kind:sub(1,-11);
+							if valid_types[kind] then
+								for _, addr in ipairs(addresses) do
+									local a = addresses_kinds[addr];
+									if not a then
+										addresses_kinds[addr] = {
+											kind, [kind] = true;
+										};
+									elseif a and not a[kind] then
+										table.insert(a, kind)
+										a[kind] = true;
+									end
+								end
+							end
+						end
+						if next(addresses_kinds) ~= nil then
+							local reply = {"Contact addresses for", target, "is"};
+							for addr, kinds in pairs(addresses_kinds) do
+								if kinds[2] then reply[3] = "are" end
+								table.insert(reply, addr);
+								table.insert(reply, "(" .. table.concat(kinds, ", ") .. ")");
+							end
+							if reply[6] then reply[3] = "are" end
+							command:reply(table.concat(reply, " "));
+						end
+					end
+					break;
+				end
+			end
+			command:reply(target .. " doesn't have any contact addresses");
+		end);
+		return true;
+	end);
+end
+

mercurial