# HG changeset patch # User Kim Alvefur # Date 1526775408 -7200 # Node ID 4aa787757235db6b0edb3821582832d47e7caa7e # Parent 6de45357027046215c2184fe7e7ea40d33b2122f riddim.plugins.servercontact: Query for XEP-0157: Contact Addresses for XMPP Services diff -r 6de453570270 -r 4aa787757235 plugins/servercontact.lua --- /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 +