diff --git a/resources/prosody-plugins/mod_polls.lua b/resources/prosody-plugins/mod_polls.lua index ac22b9466f..6b68688aca 100644 --- a/resources/prosody-plugins/mod_polls.lua +++ b/resources/prosody-plugins/mod_polls.lua @@ -4,10 +4,11 @@ local json = require("util.json"); local st = require("util.stanza"); - +local jid = require "util.jid"; local util = module:require("util"); local muc = module:depends("muc"); +local NS_NICK = 'http://jabber.org/protocol/nick'; local is_healthcheck_room = util.is_healthcheck_room; -- Checks if the given stanza contains a JSON message, @@ -38,6 +39,28 @@ local function check_polls(room) return false; end +--- Returns a table having occupant id and occupant name. +--- If the id cannot be extracted from nick a nil value is returned +--- if the occupant name cannot be extracted from presence the Fellow Jitster +--- name is used +local function get_occupant_details(occupant) + if not occupant then + return nil + end + local presence = occupant:get_presence(); + local occupant_name; + if presence then + occupant_name = presence:get_child("nick", NS_NICK) and presence:get_child("nick", NS_NICK):get_text() or 'Fellow Jitster'; + else + occupant_name = 'Fellow Jitster' + end + local _, _, occupant_id = jid.split(occupant.nick) + if not occupant_id then + return nil + end + return { ["occupant_id"] = occupant_id, ["occupant_name"] = occupant_name } +end + -- Sets up poll data in new rooms. module:hook("muc-room-created", function(event) local room = event.room; @@ -62,17 +85,29 @@ module:hook("message/bare", function(event) if data.type == "new-poll" then if check_polls(room) then return end + local occupant_jid = event.stanza.attr.from; + local occupant = room:get_occupant_by_real_jid(occupant_jid); + if not occupant then + module:log("error", "Occupant %s was not found in room %s", occupant_jid, room.jid) + return + end + local poll_creator = get_occupant_details(occupant) + if not poll_creator then + module:log("error", "Cannot retrieve poll creator id and name for %s from %s", occupant.jid, room.jid) + return + end + local answers = {} - local compactAnswers = {} + local compact_answers = {} for i, name in ipairs(data.answers) do table.insert(answers, { name = name, voters = {} }); - table.insert(compactAnswers, { key = i, name = name}); + table.insert(compact_answers, { key = i, name = name}); end local poll = { id = data.pollId, - sender_id = data.senderId, - sender_name = data.senderName, + sender_id = poll_creator.occupant_id, + sender_name = poll_creator.occupant_name, question = data.question, answers = answers }; @@ -82,45 +117,55 @@ module:hook("message/bare", function(event) local pollData = { event = event, - room = room, + room = room, poll = { pollId = data.pollId, - senderId = data.senderId, - senderName = data.senderName, + senderId = poll_creator.occupant_id, + senderName = poll_creator.occupant_name, question = data.question, - answers = compactAnswers + answers = compact_answers } } - module:fire_event("poll-created", pollData); elseif data.type == "answer-poll" then if check_polls(room) then return end + local occupant_jid = event.stanza.attr.from; + local occupant = room:get_occupant_by_real_jid(occupant_jid); + if not occupant then + module:log("error", "Occupant %s does not exists for room %s", occupant_jid, room.jid) + return + end local poll = room.polls.by_id[data.pollId]; if poll == nil then module:log("warn", "answering inexistent poll"); return; end + local voter = get_occupant_details(occupant) + if not voter then + module:log("error", "Cannot retrieve voter id and name for %s from %s", occupant.jid, room.jid) + return + end + local answers = {}; - for i, value in ipairs(data.answers) do + for vote_option_idx, vote_flag in ipairs(data.answers) do table.insert(answers, { - key = i, - value = value, - name = poll.answers[i].name, + key = vote_option_idx, + value = vote_flag, + name = poll.answers[vote_option_idx].name, }); - poll.answers[i].voters[data.voterId] = value and data.voterName or nil; + poll.answers[vote_option_idx].voters[voter.occupant_id] = vote_flag and voter.occupant_name or nil; end local answerData = { event = event, room = room, pollId = poll.id, - voterName = data.voterName, - voterId = data.voterId, + voterName = voter.occupant_name, + voterId = voter.occupant_id, answers = answers } - module:fire_event("answer-poll", answerData); end end); @@ -154,6 +199,5 @@ module:hook("muc-occupant-joined", function(event) :tag("json-message", { xmlns = "http://jitsi.org/jitmeet" }) :text(json.encode(data)) :up(); - room:route_stanza(stanza); end);