Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Bookmarklet to view Twitter poll result without voting
/**
* Used https://www.odditysoftware.com/page-webtools16.htm 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 !== 'https://twitter.com' || 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 = window.XMLHttpRequest.prototype.open;
const startTime = Date.now();
window.XMLHttpRequest.prototype.open = 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?')) {
window.open('https://www.syncwithtech.org/twitter-poll-result-wo-voting/', '_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;
alert(result);
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 (Date.now() - 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.')) {
window.open('https://www.syncwithtech.org/twitter-poll-result-wo-voting/', '_blank');
}
this.removeEventListener('load', listenEvent);
}
return oldXHROpen.apply(this, arguments);
}
}
)();
@Felipeplz

This comment has been minimized.

Copy link

@Felipeplz Felipeplz commented Dec 11, 2018

For polls with video replies (which are iframes too):

https://gist.github.com/Felipeplz/d41056f5eaa1b6787670a21ddaa7db0e

@Stevoisiak

This comment has been minimized.

Copy link

@Stevoisiak Stevoisiak commented May 24, 2020

This does not work as of May 23rd, 2020.

@vicke4

This comment has been minimized.

Copy link
Owner Author

@vicke4 vicke4 commented Aug 28, 2020

This does not work as of May 23rd, 2020.

I have updated the script. It has to work now. You may want to check this using the bookmarklet.

@WAZAAAAA0

This comment has been minimized.

Copy link

@WAZAAAAA0 WAZAAAAA0 commented Mar 9, 2021

just open the twitter poll on a random nitter instance, they usually just expose the results without logging in https://github.com/zedeus/nitter/wiki/Instances

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