Neil Lyons

Freelance Web Developer based in the UK.

I tried to win $1,000 recently

All I needed to do was be one of the first ten comments on a YouTube video. To do that I wrote a little program that would post a comment whenever the video was published and hope I was faster than anyone else who had the same idea or anyone who was trying to post a comment manually.

That was the plan, but I wasn't quite fast enough. I actually had five people in total using this program and unfortunately none of us won.

I'm not even sure what position our comments came as there is no easy way to check. I do know we were in the top 3,000, as that is how many comments I saw when I clicked on the video myself. My guess is that we were actually in the top few hundred. As of 28th Dec 2019 the video has over 250,000 comments.

These are the people that won. No idea if they were bots like me or people that posted a comment manually.

The program works by receiving a POST request with an XML body that contains the new video ID. In order to get the XML sent to me I needed to register an endpoint with YouTube's Push Notifications API.

I then use this video ID to POST some JSON to YouTube's API that will insert the comment.

Before you can use YouTube's API you need to register an app with Google and then do the oauth2 dance for each user to get an access token.

To increase the odds of success I hosted the program in the US. I did this in the hope of reducing latency between my server and YouTube's Push Notifications server. Not sure if this helped as I don't know where their server is located, but my guess is the US as YouTube is a US company.

I also rented a fast server (Heroku Performance M dyno). It is quite expensive to rent ($250 per month) but because I knew the exact time the video was to be published I only needed it for an hour. Which only cost $0.35.

As I was posting comments on behalf of several people I wanted to post the comments all at once. I normally use Python for everything but for this project I chose Elixir as it has a better concurrency story. I think this project would have worked fine with Python asyncio but with Elixir it is super easy and efficient to utilise all the cores on the server which you can't do as efficiently in Python plus I wanted to learn Elixir.

This is how you execute code in parallel. You just need to pass async_stream an Enumerable (In Python land this would be an iterable) and a function.

Task.async_stream(1..10, fn i ->
  IO.puts "Do some work on any CPU core with #{i}"
end) |>

If I had more time I would have used Erlang Term Storage (ETS) to cache my users in memory instead of performing a network request and fetching them from a Postgres database. In reality I don't think this would have made a big difference to the outcome. The main culprit is the fact that YouTube's Push Notification service isn't instant. There is definitly a few seconds delay between a video being published and the push notification event.

This was my first project with Elixir and I'm really impressed. For new comers to the language the mix tool to setup new projects and manage dependencies is fantastic.

Looking forward to building my next project in Elixir.