Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Bookmarklet to view Twitter poll result without voting
* Used to remove comments and minify the code to use it as a bookmarklet
function () {
/* Exiting if the webpage is not Twitter or a valid tweet */
if (window.location.origin !== '' || window.location.pathname.split('/').length !== 4) return alert('This is not a valid Twitter poll!');
alert('Please wait this can take up to 30 seconds. Select OK or close to get started. If this is a valid poll, you will get the result when it is ready...:)');
/* This string will hold our poll result */
let result = '';
/* This boolean denotes if our job is done and if true, doesn't execute the addEventListener anymore. */
let processDone = false;
let oldXHROpen =;
const startTime =; = function () {
if (processDone) {
return oldXHROpen.apply(this, arguments);
/* onLoad event handler to intercept the Twitter API response to read the poll results. */
function listenEvent() {
try {
if (this.responseURL.includes('poll')) {
* JSON from the Twitter API response On a poll page every 30 seconds, Twitter hits the API to retrieve the latest poll results
const pollResultJson = JSON.parse(this.responseText);
const pollBindingValues = pollResultJson.card.binding_values;
const resultObj = Object.keys(pollBindingValues).reduce(function (accum, key) {
if (key.includes('_label')) {
const label = pollBindingValues[key].string_value;
const choiceNumber = key.replace(/\D/g, '');
const voteCount = pollBindingValues[`choice${choiceNumber}_count`].string_value;
accum.choiceVoteCountMap[label] = +voteCount;
accum.noOfVotes += +voteCount;
return accum;
}, { noOfVotes: 0, choiceVoteCountMap: {} });
const { choiceVoteCountMap, noOfVotes } = resultObj;
Object.keys(choiceVoteCountMap).forEach(function (label) {
result += `${label}: ${((choiceVoteCountMap[label] / noOfVotes) * 100).toFixed(2)}% with ${choiceVoteCountMap[label]} votes\n`
} catch (e) {
processDone = true;
/* For error reporting. Incase if the bookmarklet fails to work in future, people will be able to report...:) */
if (window.confirm('Something went wrong. Could you please report the issue?')) {'', '_blank');
this.removeEventListener('load', listenEvent);
this.addEventListener('load', listenEvent);
/* If result holds proper string, we need to stop listening to the event */
if (result) {
processDone = true;
this.removeEventListener('load', listenEvent);
/* If the page is a proper tweet and doesn't have a poll, we must stop listening to the load event. It happens after 40 seconds. */
if ( - startTime > 40000 && !processDone) {
processDone = true;
/* To get feedback if it's actually a poll and the script fails to detect it */
if (window.confirm('Seems like it is not a valid Twitter poll. Press OK to report the issue if it is a valid poll and the bookmarklet failed to detect it.')) {'', '_blank');
this.removeEventListener('load', listenEvent);
return oldXHROpen.apply(this, arguments);
Copy link

WAZAAAAA0 commented Mar 9, 2021

just open the twitter poll on a random nitter instance, they usually just expose the results without logging in

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment