Fudging Medium Stats with NodeJS

Kashyap Mukkamala
Level Up Coding
Published in
5 min readMar 6, 2019

--

This is not going be one of my usual articles in which we discuss how we can complete a certain task using the tools and frameworks at our disposal.

Instead, we will be using our superpowers for doing something evil, such as pumping up our medium stats (Views, Reads and Read Ratio). But before we proceed, I would like to point out that inflating stats is bad for obvious reasons, it’s not something that is public for others to view and it is certainly not an indication for how good or bad an article is. So, let’s start.

Inspiration

Some might wonder why I went down this path. The answer is as simple as it gets — curiosity. One day, while reading an article, I opened the CDT (Chrome Developer Tools) to see what kind of XHR calls are being made by the browser. I was curious about the data exchange format, and how the documents are saved in Mediums servers (rich text, JSON etc). And during this exploration I noticed that there are several calls being made to track the interactions with the article.

For instance, a request is made to the servers which contains a batch of events recording all the interactions since the last sync. This request is fired (as per my observation) when the client is idle.

Sample Batch request with Analytics data on article load

I wont pretend to know the details of everything that is going on here, but, its clear that most of this payload is related to performance monitoring and initial load of the article.

When we start scrolling the page, the same is request made but a new interaction type post.streamScrolled is now available in the list of events. This new payload type also contains information of the client itself (height, width etc) and how much the user has scrolled the page, when the visit started etc.

Breakdown of the streamScrolled interaction

And when we scroll to the very end, we can see another special type of event called post.clientRead which to me indicates that the article has been read.

This got me thinking further, are these the events that Medium uses to track how much an article is read? Do the Views and Read Ratio derived from these numbers as well?

The Script

To further validate my understanding, I wanted to see if I could simply replicate this behavior as an external reader. There was no easy way for me to automate this process for a simple reason: I do not know enough about what Medium tracks, whether or not they identify a single user based on certain factors (cookies/browser storage/auth tokens). So the answer was becoming clearer that to automate:

  1. I needed to go incognito which would at least remove any lingering information.
  2. I need more granular control over what requests I might need to intercept (and if possible modify them)

Achieving #1 is easy, we can do that with any E2E testing frameworks, but, since we might need #2 it is better to go with running Google Chrome in headless mode and control it with the chrome-remote-interface package available from NPM.

Setting up the script is simple as well:

mkdir medium-stats
cd medium-stats
npm init -y

Next, install the chrome-launcher and the chrome-remote-interface packages

npm i -S chrome-remote-interface chrome-launcher

We are now ready to start with setup part of the scripting which is fairly straightforward:

Once the initial setup is complete, we can now add the fudgeTheStats method which is going to clear browser storage and cookies, open our article, scroll to bottom, wait for API calls to finish and then repeat the process for a predefined number of times.

When put together, we can watch it execute as expected. Luckily, we did not have to intercept any requests here so it might have been easier to use an automation framework to achieve similar result.

Conclusion

Now, there is no definite way to tell that this approach will continue to be a success (since Medium can and does keep changing this frequently), but a fake article and put through the script and had its stats updated as expected.

One unexpected, yet surprising side effect is that the articles sometimes do get picked up by Googles Recommendations “Articles for You” section and that drives up the traffic further with real views from real people. This could be happening because of high number of visits to the article from Google Chromes address/search bar. This, however, is a not always the case and it can keep changing based on how Googles tools and products evolve.

All things said and done. Don’t be evil or you will end up like our beloved friend:

Source code shown in the example is here.

If you enjoyed this blog be sure to give it a few claps, read more or follow me on LinkedIn and Twitter.

--

--