A very complicated solution for a very simple (and stupid) idea

Gideon Rosenthal
6 min readApr 29, 2020

--

A quixotic and chaotic, months-long journey to create a bot that tweets random plays from the NBA.

Note: I wanted to keep this as short as possible and briefly discuss the lengths I went through to create this bot. Therefore, I kept the tech specifics to a minimum. However, I’m happy to go into more detail, so reach out if you’re interested in learning more.

Dentist Bot

Ok, here’s a joke for you.

Question: What time should you go to the dentist?
Answer: Tooth-hurty

It’s a simple premise, and at first it was in fact a simple solution. Using a couple Amazon Web Services (Lambda + Cloudwatch), I created @dentist_appt on Twitter, whose sole purpose of existence consisted of tweeting everyday at 2:30pm EST, “Time to see the dentist.” All-in-all, this only took me about an hour to get up and running.

But that got pretty old, pretty quick. As you can see from my friend’s tweet.

Nonetheless, because I’m stubborn, I never took it down, nor disabled it. Instead, the bot stayed like this for a couple months, until my friend Louis approached me with a better idea for a bot…

Dr. Ersan Ilyasova

The casual NBA fan may not be intimately familiar with Ersan Ilyasova, a 10+ year veteran on the Milwaukee Bucks. Even if they are familiar with him, they are most likely unaware how good he is at drawing charges.

From nba.com

Of course, the one downside in constantly trying to draw a charge, is you open yourself to these kinds of embarrassments. The rest of the time however, the end result is 4 minutes and 55 seconds of pure art.

This gave Louis the idea for a bot that tweeted out the video every time Ersan successfully drew a charge. Fortunately, stats.nba.com (Stats) publishes a full play-by-play after every game. For example, here is the pbp for the last game of the 2020 season before it was suspended. Unfortunately, Stats does not make it easy to collect or aggregate this information. A lot of companies choose to make this information available for public consumption through what is called an Open API; the prevailing thought being that if developers can use it in interesting ways, it will only lead to further customer engagement. That being said, a lot has been written about how these peripheral viewing habits are potentially contributing to the league’s declining TV ratings.

Regardless of their reasoning, I had to spend a lot of time inspecting their website to see how they themselves operated with the API. One such project that I believe did a lot of similar work is 3ball.io. (You should check it out. The site allows you to search by player and play-type.)

So, after a painstaking number of days, via trial and error, I was able to determine that for Stats, Ersan had the player id, “101141”. And equally as important, a play type of “26” meant a charge. I was then able to scrape the play-by-plays to get the ones where our man taught someone a lesson about overzealously driving down the lane. That’s where the real problems started.

The play-by-play web page calls this url to get the video of the play: https://stats.nba.com/stats/videoeventsasset?GameEventID=610&GameID=0021900973

However, if you click on that link, you’ll notice that your browser just gets stuck loading and never actually returns a response. After a couple more hours of trial and error, I circumvented this security block, through ways that I don’t really want to share here, on the small chance someone from the NBA actually reads this post and makes a simple change which would break my entire setup. (I think that might be a run-on sentence, but I’m leaving it.)

After getting the script running on my own computer, it was time to put the code up on an Amazon web server. Without hosting it on a 3rd party, I would have to leave it running on my computer at all times. 24/7/365. Meaning that I would never be able to shutdown or even close my laptop. This of course isn’t very sustainable, but nonetheless, remember this solution for later in the post.

Generally speaking, working with AWS is pretty straight forward. I thought the rest of this project would be a piece of cake. Incorrect.

Websites often block certain IP addresses in order protect themselves against bots, and it appears Stats did just that. This means, that they were able to tell that I was running something on an Amazon server and simply not respond to any of the calls I sent to their site. This ultimately led me to what I thought was a brilliant solution. On Amazon, I setup a Tor router, and directed my traffic through it. For those who are unfamiliar with Tor, or how it works, you can watch this quick explanation. TL-DR: the Tor network is primarily used by terrorists and dissidents living under authoritarian governments as a means of obfuscating their IP addresses and therefore their identity.

And by me, who just wants to post videos of Ersan Ilyasova drawing offensive charges.

For a few, beautiful months, the bot worked perfectly. Although for some reason, Ersan wasn’t drawing that many charges, so the bot wasn’t actually tweeting that regularly. He wasn’t even among the league leaders.

I smell collusion. Going to need an E:60 on the subject.

The bot did still tweet everyday at 2:30, just to keep the original joke alive. (It’s also why I named the bot, Dr. Ersan Ilyasova. 50% basketball player, 50% dentist. 100% hustle.)

Then, on March 11th, for reasons you are already aware of, the NBA suspended its season indefinitely. Our protagonist would not be drawing any charges for the foreseeable future.

Yet, once again, Louis had an idea for a bot.

Now, what if we just tweeted a completely random play, from any player, from any game.

Now that I knew how everything worked, I just had to refactor the code to grab any play from any game. But once again, I discovered the NBA had added more security to stats.nba.com. I’m not sure when, or how, but my Tor router no longer worked. Their server never responded with the data I needed. At this point, I decided the only solution was to in fact run the bot on a computer at my house.

Now, I obviously couldn’t run it on my work laptop, because I need to be able to close it from time to time (#WorkLifeBalance). That’s when I turned to the Raspberry Pi, a programmable “mini computer”, that people mostly use for DIY projects at home. (There are a lot of examples on Youtube, but my favorite is this smart mirror.)

This computer has one purpose in life. It is unburdened by life’s larger questions.

So now, every 3 hours, this Raspberry Pi tweets out a random play from the NBA. You can follow along here, @nba_random_play. As it stands, it only tweets from the 2018–2019 season, and due to the way they structure the data, plays from the 2019 NBA Finals are posted with more frequency. (I may fix both of these flaws in the next couple weeks.) In the meantime, this some of the riveting content you can expect from the Random NBA Plays account.

The End

If you enjoyed this, don’t forget to follow the bot on Twitter.

If you really really enjoyed this and want to show some appreciation, I teach a tech class at an after school program in Venice, CA. We’ve been doing weekly food drives and would greatly appreciate your support.

Once again, if you’re interested in learning more about the NBA Stats api, or how I accomplished some of the other aspects of the bot, feel free to DM me.

--

--