July 8, 2019

Explaining (and Celebrating) my First Twitter Bot

After weeks of looking for a workable approach, I finally build a Node Twitter bot to automatically share anime quote artwork.

A few months ago I tweeted this absolutely true statement.

Over the last year my anime-related side projects fueling this plot have grown in scope:

  1. Scraping an anime image database to email me several each morning.
  2. Linking this scraped data to a custom API endpoint to show random images.
  3. Using this API endpoint to make an anime quote image maker.

The next roll I've taken down this slippery slope now includes:

  1. Create a bot that shares random anime quote images on Twitter all day long.

Last week this vision finally moved from delusion to reality, and the @AnimeQuoteImage bot was born! Yes, I'm now using robots to fuel my anime addiction.

To celebrate this latest step on my path to the nerd asylum, I wanted to share the basics of how it works and my favorites of its work so far.

How the Bot Works #

If you want to look over the actual code, you can check out the open-source repo with the bot's code.

For a high-level understanding of the bot, it runs on Node and uses a few third-party JavaScript modules to get going. I've included crude cartoon visuals for both necessity and boredom.

The bot uses Puppeteer to open my Anime Quote Maker in a headless Chrome browser. It's programmed to start with a random image, a random quote, and randomly style the quote from what's available (color schemes, filters, alignment, etc).

A robot pulling up a webpage.

Puppeteer sizes the browser in a 700 by 700 pixel window, which makes the random quote fill it just right, and takes a screenshot. It also grabs the quote's text and author from the DOM.

A robot taking a screenshot of the webpage.

Node passes this info to Twit, a popular Node add-on for using the Twitter API. It composes a tweet with the image, quote, and author, and sends it off.

A robot sending the screenshot out on Twitter.

This all goes to Heroku, which uses the Heroku Scheduler add-on to rerun all these steps every 30 minutes.

A robot being reminded to repeat all the past steps by Heroku.

I hit turbulence getting all the Puppeteer dependencies uploaded, but after that there were few issues and the Twitter bot was born!

My Bot's Favorite Work So Far #

I'll start with some positive examples of quotes, images, and styling that somehow came together almost perfectly.

One in particular looked like a bizarre, if late, tribute to pride month.

Some thought-provoking quotes actually seemed enhanced by their images.

Others didn't make me think as much as send a chill down my spine.

This one in particular still freaks me out. A quote about "positive vision" paired with an inverted image of someone with blood on their shirt and a hidden face. I really hope this was random and not a secret prophecy for the coming End of Days.

There's also many political quotes that get mixed in. Pairing real-world politics with anime is frequently...awkward.

There of course will be some creations I simply don't know how to respond to.

Lastly, here's my all-time favorite that's truly one of a kind, and other programmers who have handled APIs will likely appreciate it.

Either the API crapped out on me, or this is one of those "imagine your own quote" scenarios. If so, I'd go with a computer science quote about unit testing.

Wrapping Up #

Making a bot like this has been a far-off goal of mine for a long time, and making it real has reminded me of why I enjoy programming so much. Many things that seem impossible to make usually aren't if you keep at it and try enough different approaches. I looked at several Ruby setups for this before finally settling on Node, and after a few days of struggling to get things working on Heroku, it all finally came together.

Now I can kick back and enjoy it doing this work for me. At least until the cycle repeats and I get another idea that both improves my programming skills, indulges my love of anime, and costs me some sleep in the process.