Overview
This guide covers creating polls in WhatsApp chats, casting votes on existing polls, and decrypting encrypted vote results. Polls support both single-select and multi-select modes and work in both direct messages and group chats.Creating a poll
Use thepolls() accessor on the client to create a poll:
create method returns a tuple of (SendResult, message_secret). The SendResult contains the message_id and to JID (see SendResult). You must store the message_secret (a 32-byte key) to decrypt votes later.
Multi-select polls
Setselectable_count to allow voters to pick multiple options:
Polls must have between 2 and 12 options, and all option names must be unique. The
selectable_count must be between 1 and the total number of options.Voting on a poll
To vote on an existing poll, you need the poll’s message ID, the poll creator’s JID, and themessage_secret from when the poll was created:
message_secret, the poll message ID, the poll creator’s JID, and the voter’s JID.
Decrypting votes
When you receive poll update events, the vote payload is encrypted. Usedecrypt_vote to retrieve the selected option hashes:
wacore::poll::compute_option_hash.
decrypt_vote and aggregate_votes became instance methods on client.polls() (instead of static Polls::… helpers) in v0.6 so they can consult the LID↔PN cache. If the poll creator and voter were originally addressed in one namespace and the vote is delivered in the other (which happens during LID migration), the client retries decryption with the swapped namespace before giving up.Aggregating results
For tallying votes across multiple voters, useaggregate_votes. This handles vote replacement (last-vote-wins) and maps hashes back to option names. Voters are deduped by canonical identity, so a voter who re-votes under the opposite namespace counts once:
Pass votes in chronological order (oldest first). When a voter changes their vote, only the latest vote counts. An empty selection clears the voter’s previous vote.
Encryption details
Poll votes use a multi-step encryption process:- Each option is identified by its SHA-256 hash (not the option name)
- An encryption key is derived using HKDF-SHA256 from the
message_secret, poll message ID, creator JID, and voter JID - The selected option hashes are serialized as a protobuf
PollVoteMessage - The payload is encrypted with AES-256-GCM using the derived key and a random 12-byte IV
- Additional authenticated data (AAD) includes the poll message ID and voter JID
message_secret.
Error handling
- Fewer than 2 or more than 12 options
- Duplicate option names
selectable_countout of range- Invalid
message_secretlength (must be 32 bytes) - GCM tag verification failure during vote decryption
Next steps
- Sending messages - Send text, reactions, and other message types
- Receiving messages - Handle incoming messages and events
- Group management - Work with group chats