Note: the `end` attribute is the poll end date timestamp. The `votes` attributes are the number of votes (total on `x-poll` and per choice on each `x-poll-choice` tag). The `choice` attribute is the key to use to vote for this choice (`choice='1'` can by voted by sending `!1`).
### Poll votes
Users can then vote by sending messages in the room, using the format "!1".
These groupchat messages will be intercepted by the module, and counted as votes.
If the "anonymous votes" feature is enabled, vote will be taken into account, but the message will be bounced with an error saying: "Your vote is taken into account. Votes are anonymous, they will not be shown to other participants."
This means that you can vote with any XMPP clients!
If an occupant votes multiple times, their vote will be updated.
If an occupant is muted (has visitor role), votes won't be counted.
When there are new votes, messages are broadcated so that compatible clients can update the current vote progress.
These messages are debounced: the module waits 5 seconds after a vote to send the update message, and only send one for all votes that were done in those 5 seconds.
These messages are `groupchat` message without `body`, and with some specific `urn:xmpp:hints`.
They contains the `x-poll` tag with same meta data as above.
The message is also sent as the poll creator (`from` and `occupant-id`).
Please note the `over` attributes that indicated that the poll is over.
If users are voting just after the poll ends (less than 30 seconds after the poll end), and the vote is anonymous, their votes will be bounced, to avoid leaking votes for late users.
### Security
Following tags will be stripped of any incoming groupchat message: `x-poll`, `x-poll-question`, `x-poll-choice`.
This is to avoid any poll spoofing.
## Fronted
The poll Converse plugin does multiple things.
It checks for the `http://jabber.org/protocol/muc#x-poll` disco feature to show the "create poll" button.
It uses standards XMPP forms to get the poll creation form and submit it.
It uses the `parseMUCMessage` hook to check if messages have `x-poll` data.
If so, and if message are not archived, it creates or updates the poll banner.
When clicking on a choice in the banner, it just sends a message in the chat ("!1" for example).
As the backend does no localization, it also translate on the fly the english sentences coming from the backend (in the form definition, in poll start/end message, and in bounce/error messages).