
Show HN: I wrote a bookmarklet to know any Twitter poll result without your vote - vicke4
https://www.syncwithtech.org/twitter-poll-result-wo-voting/
======
blindm
And here's the code if anyone is interested in how it works:

    
    
        javascript:!function(){if('https://twitter.com'!==window.location.origin||4!==window.location.pathname.split('/').length)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...:)');let t='',e=!1,o=window.XMLHttpRequest.prototype.open;const i=Date.now();window.XMLHttpRequest.prototype.open=function(){if(e)return o.apply(this,arguments);function n(){try{if(this.responseURL.includes('poll')){const e=JSON.parse(this.responseText).card.binding_values,o=Object.keys(e).reduce(function(t,o){if(o.includes('_label')){const i=e[o].string_value,n=o.replace(/\D/g,''),s=e[`choice${n}_count`].string_value;t.choiceVoteCountMap[i]=+s,t.noOfVotes+=+s}return t},{noOfVotes:0,choiceVoteCountMap:{}}),{choiceVoteCountMap:i,noOfVotes:n}=o;Object.keys(i).forEach(function(e){t+=`${e}: ${(i[e]/n*100).toFixed(2)}%\n`})}}catch(t){e=!0,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',n)}}return this.addEventListener('load',n),t&&(e=!0,alert(t),this.removeEventListener('load',n)),Date.now()-i>4e4&&!e&&(e=!0,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',n)),o.apply(this,arguments)}}();

~~~
vicke4
More readable version of the code:

( 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)}%\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);
        }
      }

)();

------
vicke4
Hey guys,

I wanted to check the Twitter poll results before voting for one of the
choices. So, I wrote a bookmarklet which opens an alert with the poll results
when used on an ongoing Twitter poll page. The script just intercepts the API
requests Twitter make to fetch poll results every 30 seconds and populates the
result. You can find the script as a gist:
[https://gist.github.com/vicke4/891b14bbf46f247fb7314cb3565d1...](https://gist.github.com/vicke4/891b14bbf46f247fb7314cb3565d1797)

To test the bookmarklet you need to find a poll. You can get only polls as
results when you search for one of the below queries,

card_name:poll2choice_text_only

card_name:poll3choice_text_only

card_name:poll4choice_text_only

card_name:poll2choice_image

card_name:poll3choice_image

card_name:poll4choice_image

On the mobile app, you can just turn off your data/WiFi and select one of the
choices, you'll be able to see the results for a moment.

