Tiny Flashing Thumbs: How to Bot your way to Fake News Success

Making up the news is hard work, especially when the real news comes so fast and so furious. Why keep writing fake news the old-fashioned way — typing it with your fingers — when you can make a robot that will do it for you? Then you can use all that free time you’ve gained to learn how to play cards, improve your social skills, explore a career in manufacturing, or just contemplate your own mortality while awaiting the inevitable.

There are lots of reasons to make a Twitter bot, and likewise, there are lots of ways to make a Twitter Bot. Most programming languages or environments can interact automatically with Twitter, so many people have created bots that accomplish just about all of the things that human users do with Twitter.

As with many other job sectors where certain tasks have been deemed too dangerous, tedious, or demeaning for humans, robots are stepping up to the task of political discourse with enthusiasm and intensity. After all, if your goal is to elevate a politics that dehumanizes, oppresses, or stands to directly harm most of humanity, it would seem inconsistent to enlist the help of actual people in your misanthropic quest for power.

It’s time to build your own robot army.

In this post, I’m going to teach you one way to make a Twitter Bot, which will be accomplished with a web-based tool I created for this purpose. In later posts and lessons, we’ll try out different kinds of bots and purposes for bots.

I call my tool “SSBot” because it runs in Google Spreadsheets. I first created it for my students because I wanted to give them an easy access point to bot creation, and when that first version proved successful, I upgraded it to a more complete version and opened it up with a wider release. That version (0.4) has now grown stale, so this post is also an introduction to the fresh, new, and somewhat improved version of SSBot, version 0.5.1. It has some new features which may turn out to introduce some bugs, so bear with me as I work through these.

Creating your first bot with my tool requires following a series of steps, but in fact, you can complete these tasks in a different order. These steps below are organized in a way that make the most sense to me and generally follow what I do when I’m creating a new bot. Your amount of time with all this will vary, but the fundamental tasks of getting a bot tweeting on a schedule usually takes anywhere from 5 minutes to 30 minutes. Customizing your bot to give it purpose, personality, or controversy can take much longer. What kind of bot will you make? What will your bot do? Where will you get it’s vocabulary from? Will you make the fake news or fake the made news?

The directions below are intentionally verbose, so if you want to just jump right in to the SSBot and start playing around, you’re more than welcome to.

Step 1: Create your Bot’s Twitter Account

I like to do this first because it gives your bot a sense of identity while you work on it. You probably already know how to sign up for a Twitter account, so here are few tips:

  • Use the “infinite gmail” trick for your bot’s email address. This is the trick where you add “+something” to the name in your email. For example, my gmail address is “zach.whalen@gmail.com,” but I can also use something like “zach.whalen+myfakenewsbot@gmail.com” and it goes to the same inbox, which is convenient. Of course, if you want to really separate this bot from your real life, you can make a bespoke Gmail account.
  • Opt out of everything. Twitter changes this occasionally, but as of now, your account signup page includes three already-checked checkboxes that you should definitely uncheck: “Tailor Twitter by my recent website visits”, “Let others find me by my email address,” and “Let others find me by my phone number.” The latter two will be hidden under “Advanced Options.”
  • Do use a phone number. This will save you a step later, and you can always disconnect this number after the bot set up is complete. Since you can only have one Twitter account per phone number, text “STOP” to 40404 to disconnect whichever account is currently connected to your phone.
  • Don’t follow anyone, and don’t follow the bot from your real account. Not until you’re ready for other people to find it.
Here’s what your signup page should look like.

You can customize your bot’s profile now or later, but I always like to give my bots an avatar picture, a nice background, and an informative bio that explains the bot purpose while disclosing its botness.

Step 2. Set up your Spreadsheet

Take a look at the SSBot 0.5.1 spreadsheet, and make a copy of your own by going to File->Make copy… Save it somewhere in your Drive and you’re ready to get started.

As you explore the spreadsheet, you’ll find that the complete instructions for setting it up are all included in the sheet. You may therefore wish to follow those instructions instead of flipping band forth between your sheet and these more verbose instructions.

2A: Navigating the Spreadsheet

This is a big spreadsheet with lots of parts, so first let’s take a look at some of those parts and clarify the terms I’m going to be using. I’ve organized it into color-coded sheets or tabs at the bottom:

The tabs. Setup, Settings, Preview and log are dedicated to those functions. Green tabs are “constructors”

Setup and Settings are important as you’re working on getting the bot’s content to Twitter. The green sheets are the various constructors or ways of assembling text before sending it out. Edit those to give your bot it’s identity.

Another important detail that some people miss: some necessary functions live inside the “Bot” menu that comes to life when you open the spreadsheet. This menu resides in the menu bar:

Here is the Bot Menu. Here it is.

Finally, there’s an important group of options in the yellow “Settings” tab, and the most important of all is the Constructor setting, because that chooses which sheet to pull from when running either “Generate Preview” or actually tweeting. It’s set to “markov” by default.

2B: Understanding the Constructors

Like a lot of things that are computery, it’s probably best to learn about the constructors through trial and error: make some changes, hit “Generate Preview” in the Bot Menu, and see if you like what you get. I recommend at least trying all of the constructions to see how they work. Each one has a brief explanation on the sheet itself, and here are some slightly-less-brief explanations of each:

  • columns. Here, your bot will start with the B column and randomly select one of the values from B5 onward. Then it will proceed to C and pick a value from C5 afterward, and so on. It will keep moving to the right until it runs out of columns with text in them or it hits the maximum length specified in the Settings tab. The “Roses are Red” placeholder text demonstrates one use for this template-based approach. Still, careful attention to nuances of syntax could let you make something more grammatical with this constructor like @TheHigherDead or the Terms of Service Bot. Corpora (lists) are useful for this kind of template-filling. Darius Kazemi’s corpora repository is an excellent resource for lists of things.
  • rows. This is the same thing as columns but sideways, because sometimes the data you have is arranged that way and its just easier, or maybe it makes more sense to you to look at it this way. This is also useful if you want to precompose a bunch of tweets that the bot chooses from randomly. Just fill up the B column with your tweets.
  • markov. This constructor takes any text it finds in B5 and following and runs it through a Markov chaining algorithm to produce a plausible but nonsensical text fragment that sounds sort of like the original text. The results tend to be better if you feed it two different texts, and even better if their style or tone clashes sharply with one another. You can tweak the “depth” of the Markov-chaining up to 6 (where the higher the number the more like the original text), and you probably should increase the Minimum Length to 20 or more in order to avoid single-word tweets. Both of these options are in the Settings sheet.
  • every. This constructor works through a list of values, tweeting one then moving on to the next. It’s my version of the @everyword-style bots that exhaust a corpus. every will rotate its data upon a successful tweet so that the next tweet will always be in B3. Including the text ***STOP*** will cause the tweeting from this constructor to cease.
  • x + y. This one attempts to create a complete sentence by sampling from the corpus in column B and the corpus in column C. This is the @WhitmanFML-style bot. It does this by finding sentences with conjunctions in them (“and”, ”or”, ”but”, ”nor”, “yet”), splits those sentences into at least two pieces, and Frankenstein’s a new sentence from half or a sentence of column B and half of a sentence from column C. It helps to have two texts with lots of coordinating conjuctions; otherwise, it can be fairly repetitive.
  • _ebooks. This constructor uses the same Markov chaining that goes on in the markov constructor, with the major difference that its source text is another spreadsheet, a TAGS Archive of tweets. This takes some extra setup, like first creating a TAGS Archive and letting it collect some things, but the results can be quite fascinating.

2C: Understanding the Settings

I’ve mentioned the Settings tab a few times already, and the rest of the options may be self-explanatory. Or maybe not. I will explain them.

  • Constructor selects which constructor sheet to use.
  • Timing sets the interval tweets will post on. These are pretty limited, unfortunately, because I have to use Google’s internal time-based triggers and there are only so many choices.
  • Minimum and maximum length control the lower and upper limits of the tweets. All of the constructors will respect these constraints except for every, because I figure you can control the size of those yourself.
  • Quiet hours sets a curfew and wake up time for your bot, so if a scheduled trigger runs during that period (if you’ve set it to run every 15 minutes for example), it won’t actually send that out. You can use this to make your bot appear more like a real person, since real people sleep sometimes — unlike our current President.
  • Image urls will be converted to media attachments if you say so. These need to be images that are publicly accessible on the web, and they need to be fully qualified URLs that point to an image. So they should start with http:// and end in .jpg, .gif, or .png.
  • Markov depth defines the length of the chain’s seed fragments. Longer fragments internally will produce more coherent text externally, but it will start to sound exactly like the original text before too long.
  • Banned words are words that should never appear in your bots’ tweets. This is especially useful if you’re using the _ebooks constructor because its raw materials are unpredictable. There is a built-in ban list already, so words you add here will simply add more banned words.
  • Removing hashtags and mentions. You should do both of these unless you have a really good reason to. It’s good manners, and unsolicited mentions (@-ing people who don’t follow you) can get you banned.

Step 3: Connect your spreadsheet to Twitter

The final step is of course to connect your spreadsheet to Twitter. This involves a few steps, settings and authorizations. When things go wrong with SSBot, it’s usually related to this part of the process, so please follow closely.

To get your spreadsheet talking to Twitter, you need to create a “Twitter App,” a relationship between Twitter and another service. Do this at apps.twitter.com where, if you’re logged in to your bot’s account, you’ll see a “Create New App” button. Hit that button.

Application Details

The first three fields in the App Creation workflow can be just about anything. The “Name” must be unique, and the website URL must be complete, but other than that, there doesn’t seem to be any review of these, at least not for now.

The “Callback URL” field, however, is important. The value that goes here is generated by your spreadsheet, so go back to your Setup sheet and find the yellow cell with the callback URL for your sheet:

Note: Your character string will be different from mine. Also, the URL is quite long and it extends past the right edge of the cell.

Copy and paste the Callback URL into your Twitter App. As you do, make sure you don’t accidentally copy the cell formatting, since this will add a space character to the end of URL, which will lead Twitter to reject it. Instead, double-click the cell to select just the text of the Callback URL value.

Double-check it all, agree to the Developer Agreement, and Create Your Twitter Application.

Did you remember to verify your account and add a phone number way back at the beginning of this tutorial? If not you probably got an error message along those lines.


Under the “Permissions” tab of your App’s settings, double-check that its set to “Read and Write.” If not, make that change now, and wait a few minutes before proceeding. Sometimes it takes Twitter a few minutes to update your App’s permissions, and if you authorize before that update happens it will still use the original, read-only permissions.

Keys and Access Tokens

You need two values from the “Keys and Access Tokens” tab, the “Consumer Key (API Key),” and the “Consumer Secret (API Secret)”:

Mine are blurred out so you can’t steal them.

For both of these values, copy and paste them back into your Spreadsheet’s Setup sheet, in the green cells under step 3. Like with the Callback URL, make sure you don’t accidentally copy formatting, because this will add extra space to the value here and it won’t work.

Send a Test Tweet

This function creates the other half of the OAuth connection between your SSBot and Twitter, and if it works, it will tweet on your behalf. Double-check your app’s permissions and the Key and Secret values, and run “Send a Test Tweet” from the Bot Menu.

The first time you run this function, you’ll see a modal popup window prompting you to follow a link to authorize. This will take you Twitter where you can authorize your App to tweet on your behalf, and then once it’s all done, you’ll see a “Success! You can close this page” message. Run “Send a Test Tweet” one more time, and you should see it on your Twitter account’s timeline. If not, then it’s time for troubleshooting, which will be the next section.

Start Posting Tweets

If everything looks good, check your Settings, especially your Timing, and run “Start Posting Tweets” from the Bot Menu.

And now you have a bot!

Successful tweets and errors reported back from Twitter are logged in the logs sheet (the one with the black border, all the way to the right.)

Common Errors and Troubleshooting

Sometimes things go wrong, and that’s OK. Here are a few of those things and what to do about them.

The Twitter App says my Callback URL is an “invalid URL”

An “invalid URL” is one that doesn’t start with http:// or that includes characters that aren’t allowed for URLs like whitespace or hard returns. It’s easy to accidentally paste the URL with an extra space at the beginning or end, and that’s usually what generates this error. So double-check that URL you pasted.

Error starting OAuth flow: {“errors”:[{“code”:32,”message”:”Could not authenticate you.”}]}

If you get this in a red popup message when you try to send that first test tweet, it usually means that your Consumer Key / Consumer Secret were incorrect. It could also mean that your Twitter App is invalid for some reason. Again, double-check all those values.

“App is Read-Only”

You’ll see this in the log sheet if your App has the wrong permissions, i.e. it doesn’t have “write” permissions. To fix this, obviously, your first action should be to change those settings in the app. You’ll have to re-authorize your sheet as well, so “Revoke Twitter Authorization” from the Bot Menu and go through the “Send A Test Tweet” sequence again.

TypeError: Cannot call method “replace” of undefined.

You’ll get this message when you’re using the markov or _ebooks constructors and the chaining algorithm finds that it doesn’t have enough data to work with. This is not a very nuanced Markov implementation, so I’ve made several assumptions in order to simplify things, and one of those assumptions is that the text you’re feeding it has complete sentences starting with capital letters. Therefore, a source text that lacks capital letters will generate this error. If you’d like to bypass this assumption, you can change one line of code. Go to “Tools -> Script Editor…” to make changes to your spreadsheet’s code, and look for line 205. It should read like this:

if (/[A-ZА-Я]/.test(txt[i][0])){

To allow it to build strings from lower-case words, edit it to read like this:

if (/[a-zA-ZА-Я]/.test(txt[i][0])){

Of course, this change will have an impact on the coherence of the output, but maybe that’s a good thing.

Other Errors?

I’m moving this project into GitHub, so please post any issues you have in the issues tracker for my SSBot repository.



The main organ for news on the UnderAcademy Course: How to Write and Read Fake News: Journullism in the Age of Trump

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store