plugins/servercontact.lua

1
local disco_info = "http://jabber.org/protocol/disco#info";
2
local verse = require "verse"
3
local riddim = require "riddim"
4
 
5
local dataform = require "prosody.util.dataforms".new;
6
 
7
local serverinfo_form = dataform {
8
	{ value = "http://jabber.org/network/serverinfo"; type = "hidden"; name = "FORM_TYPE"; };
9
	{ name = "abuse-addresses", type = "list-multi" };
10
	{ name = "admin-addresses", type = "list-multi" };
11
	{ name = "feedback-addresses", type = "list-multi" };
12
	{ name = "sales-addresses", type = "list-multi" };
13
	{ name = "security-addresses", type = "list-multi" };
14
	{ name = "support-addresses", type = "list-multi" };
15
};
16
 
17
local valid_types = {
18
	abuse = true;
19
	admin = true;
20
	feedback = true;
21
	sales = true;
22
	security = true;
23
	support = true;
24
};
25
 
26
function riddim.plugins.servercontact(bot)
27
	bot:hook("commands/contact", function (command)
28
		local target, typ = command.param;
29
		if not target then
30
			return "Which server?";
31
		elseif target:find("%s") then
32
			typ, target = target:match("(%a+)%s*(%S+)");
33
			if not valid_types[typ] then
34
				command:reply("Valid types are abuse, admin, feedback, sales, security and support");
35
				return;
36
			end
37
		end
38
		if target:find("[@/]") then
39
			target = target:match("@?([^@/]+)/?");
40
		end
41
		bot.stream:send_iq(verse.iq({ type = "get", to = target }):query(disco_info), function (reply)
42
			if reply.attr.type == "error" then
43
				local _, condition, text = reply:get_error();
44
				command:reply(("Could not reach %s: %s"):format(command.param, text or condition));
45
				return
46
			end
47
 
48
			for form in reply.tags[1]:childtags("x", "jabber:x:data") do
49
				local data = serverinfo_form:data(form);
50
				if data.FORM_TYPE == serverinfo_form[1].value then
51
					if typ then
52
						local addresses = data[typ .. "-addresses"];
53
						if addresses and addresses[1] then
54
							command:reply(("%s contacts for %s %s: %s"):format(typ:gsub("^.", string.upper), target, addresses[2] and "are" or "is", table.concat(addresses, " ")));
55
						else
56
							command:reply(target .. " doesn't have any contact addresses for "..typ);
57
						end
58
					else
59
						local addresses_kinds = {};
60
						for kind, addresses in pairs(data) do
61
							kind = kind:sub(1,-11);
62
							if valid_types[kind] then
63
								for _, addr in ipairs(addresses) do
64
									local a = addresses_kinds[addr];
65
									if not a then
66
										addresses_kinds[addr] = {
67
											kind, [kind] = true;
68
										};
69
									elseif a and not a[kind] then
70
										table.insert(a, kind)
71
										a[kind] = true;
72
									end
73
								end
74
							end
75
						end
76
						if next(addresses_kinds) ~= nil then
77
							local reply = {"Contact addresses for", target, "is"};
78
							for addr, kinds in pairs(addresses_kinds) do
79
								if kinds[2] then reply[3] = "are" end
80
								table.insert(reply, addr);
81
								table.insert(reply, "(" .. table.concat(kinds, ", ") .. ")");
82
							end
83
							if reply[6] then reply[3] = "are" end
84
							command:reply(table.concat(reply, " "));
85
						end
86
					end
87
					break;
88
				end
89
			end
90
			command:reply(target .. " doesn't have any contact addresses");
91
		end);
92
		return true;
93
	end);
94
end