Quickie: HockeyApp -> App Center. What's next?

Quickie: HockeyApp -> App Center. What's next?


Back in 2014, Microsoft announced that it had acquired a popular developer tool called HockeyApp. Since then, its days as a standalone service have been numbered. As of today (November 16, 2019), HockeyApp has stopped offering their services, and instead it has been enveloped by Visual Studio App Center - Microsoft's own all-in-one developer toolkit and answer to services like HockeyApp.

I can't comment on Microsoft's claims of easy migration to their platform, since I haven't used HockeyApp for its primary purpose. Instead, I will comment on what this change means to chronic API abusers like me.

How I used to abuse HockeyApp's website

Like all services that were made before the spread of the cancer that is modern web development, HockeyApp's website is clean, slick, and easy to use. Take Telegram's Android Beta as an example: the download button is an <a> tag, the version text and description is easy to single out of the page, and the page can even load without JavaScript being enabled.

Telegram Beta 2 on HockeyApp
The "Download" button behind the scenes

For my purposes, this was perfect: I made a script that checked if the version number changed, and if it did, it would promptly grab the latest version and upload it to a Telegram channel. The script would run once a minute, and it was a great way to be notified of the latest beta.

An example of the script's end result: a post in a private channel.

I had two reasons for making this script: a) HockeyApp only serves the latest version of any given app, and I wanted to have an archive of every Telegram Beta version; and b) It allowed me to be notified about new updates without constantly needing to be on my phone.

Sidenote: By my standards, this isn't really abuse, since I'm only making 1 request per minute. Many webmasters, however, look down on scraping and actively discourage it, so in their eyes it may very well be abuse.

All in all, I was very happy with this arrangement. It allowed me to amass an archive of Telegram Beta versions to data mine, without having to manually download them. I built the script to last, so I could focus on other things while it was chugging away. And it would have continued happily running on my server if not for a little thorn in my side: Microsoft.

How I abuse App Center's API

Since its inception, my little script has grown into a ~500-line behemoth, encompassing different Telegram betas and alphas, all hosted on different platforms. However, a couple of days ago, the script stopped posting any macOS versions. While I was trying to figure out what went wrong, one of my friends informed me that the macOS Telegram dev migrated from HockeyApp to App Center.

After several minutes of digging around App Center, one of my worst fears had been confirmed: App Center's pages are actually dynamically generated webpacks. The more I looked around the page, the more I cursed the state of modern web development. The easy-to-abuse <a> tag is now gone, replaced with a <button> tag. The gymnastics that the page has to go through to get the download link are astounding, no doubt put in place in order to keep scrapers like myself from programmatically downloading app versions.

What the [naughty word] is this?! How am I supposed to extract a download link from this mess?

Needless to say, I was immensely disappointed, but I wasn't going to let some multi-billion dollar corporation force me to not abuse their website, so I got digging. Let's look at the requests App Center makes when we load the page.

App Center Requests

Two requests stick out like a sore thumb: "public_releases?scope=tester" and "2356". Let's look at the "public_releases?scope=tester" request first.

The "public_releases?scope=tester" request, prettified with Waterfox

When we make a request to the "public_releases?scope=tester" endpoint, it returns 25 of the app's latest versions. In our case, we only care about first one: 0. The only value that matters here is the ID. If we look at it, we can see that it matches the request made right after the first one: "2356". Let's take a look at it.

The "2356" request, prettified with Waterfox. This image will be JPEG'd in Instant View, if you want to view the whole thing you should open it in a browser. Sorry

Bingo! Among the JSON we can find the key we were looking for: "download_url". All we have to do now is to plug in the value of "download_url" into our request library of choice and download the file.

All in all, while not every HockeyApp user has migrated over to App Center, Microsoft has conveniently provided an API endpoint for cheeky coders like me to abuse. Hopefully they won't plan to kill it off any time soon.

P.S.: For the technically inclined, I whipped up a little proof-of-concept as en educational resource. Feel free to use it in your code responsibly!