Build poll workflows and pin messages in WhatsApp
Create polls, observe decrypted votes, read synced totals and keep a message pinned for one, seven or thirty days.
OpenWA 5.5 adds a complete poll workflow around the native message: create it, listen for votes, read available totals, and submit or remove this account's choice. Message pins keep the result or instructions visible in the conversation.
const pollId = await client.sendPoll(chatId, 'Which day?', [
'Friday', 'Saturday', 'Sunday',
], { selectableCount: 1 });
if (typeof pollId === 'string') {
const results = await client.getPollResults(pollId);
await client.voteOnPoll(pollId, [results.options[0].id]);
// To remove this account's vote:
await client.voteOnPoll(pollId, []);
}
Options must be nonempty and unique. selectableCount defaults to one; zero allows all choices. Use option IDs from the returned results rather than deriving them from labels. Native WhatsApp limits still apply, and invalid, duplicate or excessive selections and closed polls reject explicitly.
Keep totals in sync
const listener = client.onPollVote(async vote => {
const results = await client.getPollResults(vote.pollId);
console.log(results.voterCount, results.options);
});
// Later:
listener.off();
Results have scope: 'synced': they describe the linked device's available vote store, not a guaranteed global census. Locally pending votes count; known failed sends don't. History hydration can emit listener callbacks, including this account's changes. Deduplicate ordinary votes by ID and timestamp when triggering side effects, and use a fresh results snapshot for current totals.
Closing times and hidden names
endTime uses Unix milliseconds, unlike event start times in seconds. Closing times and hideVoterNames require WhatsApp's sender feature flags for the account/chat, and recipient V6 rendering depends on its app and configuration. Unsupported sender features throw rather than dropping the option silently.
Hidden names describe native display behavior, not cryptographic anonymity. The SDK omits individual votes and identities from hidden-name results and notifications. These methods serve direct chats and groups; channel polls use another store and aren't exposed here.
Pin the useful message
await client.pinMessage(messageId); // Seven days.
await client.pinMessage(messageId, 'OneDay');
await client.pinMessage(messageId, 'ThirtyDays');
await client.unpinMessage(messageId);
Message pins affect the conversation and need native chat permissions. pinChat instead changes this account's chat list. Read the polls and pins guide for native feature requirements and listener behavior.