| 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 |