Your First Twitter Bot, in 20 minutes

Creating a Twitter bot is a great exercise for formalizing a simple concept in a concrete implementation. Some of the best bots demonstrate this simplicity: a nugget of an idea, with the nuance in the details. To implement a bot usually requires some programming, some data wrangling, and a server. However, it can be easier. By patching together some open datasets and a hosted version of a generative grammar, I’ll describe how to build a simple bot in 20 minutes. The bot that we’ll build is a generator of bad Clue guesses. Clue, or Cluedo in Europe, is a board game where players gather clues about a murder mystery, and try to determine the crime’s room, weapon, and culprit. When a player is confident in their information they make an accusation for the win (if correct) or disqualification (if wrong). Our bot will make terrible guesses in the style of the game’s accusations.

The Tools

For this exercise, we’ll use Tracery (Compton, Filstrup, and Mateas 2014). Tracery is an introductory tool for generative grammars. It allows a rules-based story to be written, patching together text in guided but random ways. Cheap Bots Done Quick is the glue that connects Tracery to Twitter: it hosts a version of Tracery that can post to Twitter, on-demand or at scheduled times. These two tools take much of the complexity out of creating a bot: Tracery lets you avoid the programming logic for generating a tweets (albeit for a much more restricted space of possibility) while Cheap Bots Done Quick saves you the hassle of dealing with Twitter authentication, code hosting, or scheduling. Getting started with Cheap Bots Done Quick is simple: browse to and “Sign In With Twitter”. Most people will want to create a new account for their Twitter bot (details at the bottom of this post), but using your regular account is sufficient: you can generate sample messages without posting. Screenshot_101915_025639_PM The default view shows a sample set of Tracery rules, formatted as JSON. There are three definitions, for ‘origin’, ‘alternatives’, and ‘completely different’: the only one that Tracery needs is ‘origin’. When Tracery is asked to generate a phrase or a story, it randomly chooses text from the options defined for ‘origin’. In the default view, those options are (a)  “this could be a tweet” (b) “this is #alternatives# tweet” and (c) “#completely different#”. When a phrase is bracketed by the number sign, #, that tells Tracery to replace that text with another definition: thus “#alternatives#” will be replaced with text from the alternatives definition, which might, in this case, be “an example”, “a different”, “another”, etc. You can also add circular references, such as:

 "origin": ["Have a #phrase#"],
 "phrase" : ["happy #phrase#", "birthday"]


Or perhaps something loopier: Screenshot_101915_032339_PM Those are the basics. With that very simple outline, let’s create our bot.

The Rules

In the game Clue, you work your way through a mansion that had been the site of a murder, picking up clues and establishing alibis. Once you have a sense of where the crime occurred, by whom, and with what weapon, you make an Accusation.

An accusation follows a common pattern, such as: “I think it was Professor Plum in the study with the candlestick“. Hasbro’s explanation of accusations (PDF) should look quite familiar:

When you think you’ve figured out [the crime], you may, on your turn, make an Accusation and name any three elements you want. First say, “I accuse (Suspect) of committing the crime in the (Room) with the (Weapon).”

Great! That’s our origin: “I accuse #suspect# of committing the crime in the #room# with the #weapon#”. This generator won’t work until we add lists of possibilities under the headings ‘suspect’, ‘room’, and ‘weapon’: these can all be found on Wikipedia. Thus, in just four rows, we have a random accuser for the game.

"origin": ["I accuse #suspect# of committing the crime in the #room# with the #weapon#!"],
"suspect": ["Miss Scarlett", "Colonel Mustard", "Mrs. White", "Reverend Green", "Mrs. Peacock", "Professor Plum", "Miss Peach", "Monsieur Brunette", "Madame Rose", " Sergeant Gray"],
"room": ["kitchen", "ballroom", "conservatory", "dining room", "billiard room", "library", "study", "hall", "lounge"],
"weapon": ["candlestick", "knife", "lead pipe", "dagger", "revolver", "rope", "wrench"]

This generates accusations like,

  • I accuse Colonel Mustard of committing the crime in the lounge with the lead pipe!
  • I accuse Monsieur Brunette of committing the crime in the conservatory with the dagger!
  • I accuse Professor Plum of committing the crime in the kitchen with the rope!


 The Details

We’re creating a terrible Clue guesser, why only stick to the game’s cast of characters? We can add characters, locations, weapons. Since I promised a 20-minute bot, let’s gather existing data instead of creating our own. Corpora fits that bill. Corpora, started by Darius Kazemi, is a repository for datasets which are useful and reusable, but not overengineered. Hosted on Github, you can find such eclectic data as a list of hot peppers, a list of knot names, and a list of states of drunkenness. Strangely, persons of interest in the Clue universe are named with a title combined with a color or an object highly associated with a color; e.g. Miss Scarlett, Professor Plum. Conspiracies aside, we can mimic this by expanding the suspect definitions to include “#title# #color#”. Tracery has a capitalization method, so “#title# #color.capitalize#” will ensure that the first character of the color is capitalized. To fill those definitions, Corpora has a list of crayon colors names, and English honorifics; for a Colonel Mustard-like “#title# #condiment#”, there is also a list of condiments. Each list is simply formatted, so you can easily wrangle it to a JSON list (e.g. [“one”, “two”, “three”]) in a word processor, with hand-tweaking and find-replace. You can also truncate the lists to your favorites.

"origin": ["I accuse #suspect# of committing the crime in the #room# with the #weapon#!"],

"suspect": ["Colonel #condiment.capitalize#", "#title# #color.capitalize#", "#clue-character#"],
"clue-character": ["Miss Scarlett", "Colonel Mustard", "Mrs. White", "Reverend Green", "Mrs. Peacock", "Professor Plum", "Miss Peach", "Monsieur Brunette", "Madame Rose", " Sergeant Gray"],
"color": ["Almond", "Antique Brass", "Apricot", "Aquamarine", "Asparagus", "Atomic Tangerine", "Banana Mania", "Beaver", "Bittersweet", "Black", "Blue", "Blue Bell", "Blue Green", "Blue Violet", "Blush", "Brick Red", "Brown", "Burnt Orange", "Burnt Sienna", "Cadet Blue", "Canary", "Caribbean Green", "Carnation Pink", "Cerise", "Cerulean", "Chestnut", "Copper", "Cornflower", "Cotton Candy", "Dandelion", "Denim", "Desert Sand", "Eggplant", "Electric Lime", "Fern", "Forest Green", "Fuchsia", "Fuzzy Wuzzy", "Gold", "Goldenrod", "Granny Smith Apple", "Gray", "Green", "Green Yellow", "Hot Magenta", "Inchworm", "Indigo", "Jazzberry Jam", "Jungle Green", "Laser Lemon", "Lavender", "Macaroni and Cheese", "Magenta", "Mahogany", "Manatee", "Mango Tango", "Maroon", "Mauvelous", "Melon", "Midnight Blue", "Mountain Meadow", "Navy Blue", "Neon Carrot", "Olive Green", "Orange", "Orchid", "Outer Space", "Outrageous Orange", "Pacific Blue", "Peach", "Periwinkle", "Piggy Pink", "Pine Green", "Pink Flamingo", "Pink Sherbert", "Plum", "Purple Heart", "Purple Mountain's Majesty", "Purple Pizzazz", "Radical Red", "Raw Sienna", "Razzle Dazzle Rose", "Razzmatazz", "Red", "Red Orange", "Red Violet", "Robin's Egg Blue", "Royal Purple", "Salmon", "Scarlet", "Screamin' Green", "Sea Green", "Sepia", "Shadow", "Shamrock", "Shocking Pink", "Silver", "Sky Blue", "Spring Green", "Sunglow", "Sunset Orange", "Tan", "Tickle Me Pink", "Timberwolf", "Tropical Rain Forest", "Tumbleweed", "Turquoise Blue", "Unmellow Yellow", "Violet", "Violet Red", "Vivid Tangerine", "Vivid Violet", "White", "Wild Blue Yonder", "Wild Strawberry", "Wild Watermelon", "Wisteria", "Yellow", "Yellow Green", "Yellow Orange"],
"title": ["Mr.","Mrs.","Ms.","Miss.","Dr.","A.V.M","AB","Admiral","Amb","AMN","Archbishop","Baron","Baroness","Bishop","Brig. Gen.","Bigadier","Bro.","Cantor","Capt.","Cardinal","Chaplain","Cmdr.","CMSGT","Col.","Consul","Count","Countess","Cpl.","CPO","CWO","Dean","Duchess","Duke","Earl","Ens.","Eur Eng","Father","Fr.","Gen.","Gov.","H. E.","Herr","Hon","HRH","Lady","Lord","Lt.","Lt. Cmdr.","Lt. Col.","Lt. Gen.","M.","Maj.","Maj. Gen","Master","Mile.","Mme.","Mother","MSGT","Pastor","PFC","Pres.", "Prince","Princess","Prof.", "Rabbi","Radm","Rev.","Rt. Hon.","Senator","Sgt.","Sgt. Maj.", "Sir","Sister", "Speaker","Squad. Ldr.","Sr.","SrA","Sra","Srta","SSGT","Swami"],
"condiment":[ "Aioli", "Barbecue sauce", "Chili peppers", "Chili sauce", "Chili oil", "Chimichurri", "Chutney", "Cocktail sauce", "Crushed red pepper", "Dip", "Fish paste", "Fish sauce", "Fruit preserves", "Fry sauce", "Gochujang", "Guacamole", "Honey dill", "Horseradish", "Hot sauce", "Ketchup", "Fruit ketchup", "Banana ketchup", "Curry ketchup", "Mayonnaise", "Monkey gland sauce", "Mushroom ketchup", "Mustard oil", "Nutritional yeast", "Olive oil", "Pepper jelly", "Pesto", "Pickled fruit", "Pico de gallo", "Mango pickle", "Pickled cucumber", "Pickled onion", "Pickled pepper", "Popcorn seasoning", "Relish", "Salad cream", "Salad dressing", "Salsa", "Salt", "Salt and pepper", "Sauerkraut", "Sesame oil", "Soy sauce", "Steak sauce", "Sweet chilli sauce", "Syrup", "Tartar sauce", "Tekka", "Teriyaki sauce", "Tkemali", "Toum", "Vinegar", "Black vinegar", "Watermelon rind preserves", "XO sauce" ],

"room": ["kitchen", "ballroom", "conservatory", "dining room", "billiard room", "library", "study", "hall", "lounge"],

"weapon": ["candlestick", "knife", "lead pipe", "dagger", "revolver", "rope", "wrench"]

After updating the name, our bot is sounding more interesting, albeit an even worse accuser:

  • I accuse Colonel Olive oil of committing the crime in the billiard room with the revolver!
  • I accuse Colonel Teriyaki sauce of committing the crime in the library with the revolver!

You can do the same for the room and weapon. It up to you how you choose to populate these lists. For example, I added Street Fighter fighting moves as weapons, or weaponized objects (i.e. “durian cannon”, “pine cone-inator“, “roll of stickers and a sheet of waxpaper“).

"room": ["in the #room-type#", "in the #room-modifier# #room-type#", "in the #archetype-setting#", "#archetype-setting-2#"],
"room-modifier": ["French", "English", "2nd"],
"room-type": ["aerary", "aircraft cabin", "airport lounge", "alcove", "anatomical theatre", "anechoic chamber", "antechamber", "anteroom", "armory", "assembly room", "atelier", "attic", "auditorium", "backroom", "ballroom", "basement", "bathroom", "bedroom", "billiard room", "boardroom", "boiler room", "boudoir", "breakfast nook", "breezeway", "cabin", "cafeteria", "caldarium", "cellar", "changing room", "chapel", "classroom", "clean room", "cloakroom", "closet", "cold room", "common room", "computer lab", "conference room", "conservatory", "control room", "conversation pit", "corner office", "courtroom", "cry room", "darkroom", "den", "dining room", "dormitory", "drawing room", "dressing room", "electrical room", "emergency room", "engine room", "equipment room", "fallout shelter", "family room", "fitting room", "foyer", "game room", "garage", "guest room", "gym", "hotel room", "kitchen", "laundry room", "library", "living room", "lobby", "locker room", "loft", "lounge", "mailroom", "map room", "motel room", "mud room", "newsroom", "nursery", "office", "panic room", "pantry", "parlor", "playroom", "pool room", "print room", "rec room", "salon", "sauna", "schoolroom", "showroom", "sitting room", "staff room", "stockroom", "storm cellar", "studio", "study", "sunroom", "tearoom", "throne room", "transmission control room", "tv room", "utility room", "waiting room", "washroom", "water closet", "weight room", "wine cellar", "wiring closet", "workshop" ],
"archetype-setting": ["void", "tavern","library","office","dungeon","haven","shop","church","tower","plaza","road", "forest","cave","shore","river","water","ocean","garden","desert" ,"labyrinth","day","night","fortress"],
"archetype-setting-2": ["on the bridge", "at the crossroads", "on the island", "on the mountain", "at dawn","at dusk"]

"weapon": [ "#object#", "#object#", "#object# #weaponizer#", "#fighting-moves#", "#clue-weapon#", "#fruit#", "#fruit# #weaponizer#"],
"weaponizer":["cannon", "fragments", "and a sheet of wax paper", "-inator"],
"fighting-moves": ["Hurricane Kick", "Turn Punch", "Rolling Attack", "Backstep Roll", "Vertical Roll", "Ground Shave Roll", "Spiral Arrow", "Axle Spin Knuckle", "Cannon Spike", "Spin Drive Smasher", "Lightning Kick", "Spinning Bird Kick", "Air Slasher", "Jackknife Maximum", "Yoga Fire", "Yoga Teleport", "Yoga Blast", "Yoga Inferno", "Hundred Hand Slap", "Sumo Headbutt", "Sumo Smash", "Super Killer Head Ram", "Sonic Boom", "Flash Kick", "Spin Back Knuckle", "Double Flash", "Shoryuken", "Hadoken", "Hurricane Kick", "Psycho Crusher", "Scissor Kick", "Head Stomp", "Devil Reverse", "Knee Press Nightmare", "Hadoken", "Shakunetsu Hadoken", "Shoryuken", "Hurricane Kick", "Tiger Uppercut", "Tiger Knee", "Tiger Genocide", "Mexican Typhoon", "Tomahawk Buster", "Condor Dive", "Double Typhoon", "Sky High Claw", "Rolling Crystal Flash", "Flying Barcelona Attack", "Izuna Drop", "Scarlet Terror", "Rolling Izuna Drop", "Spinning Piledriver", "Final Atomic Buster"],
"object": ["CD", "Christmas ornament", "acorn", "apple", "bag", "bag of cotton balls", "bag of popcorn", "bag of rubber bands", "ball of yarn", "balloon", "banana", "bananas", "bandana", "bangle bracelet", "bar of soap", "baseball", "baseball bat", "baseball hat", "basketball", "beaded bracelet", "beaded necklace", "bed", "beef", "bell", "belt", "blouse", "blowdryer", "bonesaw", "book", "book of jokes", "book of matches", "bookmark", "boom box", "bottle", "bottle cap", "bottle of glue", "bottle of honey", "bottle of ink", "bottle of lotion", "bottle of nail polish", "bottle of oil", "bottle of paint", "bottle of perfume", "bottle of pills", "bottle of soda", "bottle of sunscreen", "bottle of syrup", "bottle of water", "bouquet of flowers", "bow", "bow tie", "bowl", "box", "box of Q-tips", "box of baking soda", "box of chalk", "box of chocolates", "box of crayons", "box of markers", "box of tissues", "bracelet", "bread", "brocolli", "brush", "buckel", "can of beans", "can of chili", "can of peas", "can of whipped cream", "candle", "candlestick", "candy bar", "candy cane", "candy wrapper", "canteen", "canvas", "car", "card", "carrot", "carrots", "cars", "carton of ice cream", "cat", "catalogue", "chain", "chair", "chalk", "chapter book", "check book", "chenille stick", "chicken", "children's book", "chocolate", "class ring", "clay pot", "clock", "clothes", "clothes pin", "coffee mug", "coffee pot", "comb", "comic book", "computer", "conditioner", "container of pudding", "cookie jar", "cookie tin", "cork", "couch", "cow", "cowboy hat", "craft book", "credit card", "crow", "crowbar", "cucumber", "cup", "dagger", "deodorant ", "desk", "dictionary", "dog", "dolphin", "domino set", "door", "dove", "drawer", "drill press", "earser", "egg", "egg beater", "egg timer", "empty bottle", "fake flowers", "feather", "feather duster", "flag", "flashlight", "floor", "flowers", "flyswatter", "food", "football", "fork", "fridge", "frying pan", "game CD", "game cartridge", "garden spade", "giraffe", "glass", "glasses", "glow stick", "grid paper", "grocery list", "hair brush", "hair clip", "hair pin", "hair ribbon", "hair tie", "hammer", "hamster", "hand bag", "hand fan", "hand mirror", "handbasket", "handful of change", "handheld game system", "hanger", "harmonica", "helmet", "house", "ice cream stick", "ice cube", "ice pick", "incense holder", "ipod", "ipod charger", "jar of jam", "jar of peanut butter", "jar of pickles", "jigsaw puzzle", "key", "key chain", "keyboard", "keychain", "keys", "kitchen knife", "knife", "lace", "ladle", "lamp", "lamp shade", "laser pointer", "leg warmers", "lemon", "letter opener", "light", "light bulb", "lighter", "lime", "magnet", "magnifying glass", "map", "marble", "martini glass", "matchbook", "microphone", "milk", "miniature portrait", "mirror", "mobile phone", "model car", "money", "monitor", "mop", "mouse pad", "mp3 player", "multitool", "music CD", "nail", "nail clippers", "nail filer", "necktie", "needle", "notebook", "notepad", "novel", "ocarina", "orange", "outlet", "pack of cards", "package of crip and crunchy edibles", "pair of dice", "pair of earrings", "pair of glasses", "pair of handcuffs", "pair of knitting needles", "pair of rubber gloves", "pair of safety goggles", "pair of scissors", "pair of socks", "pair of sunglasses", "pair of tongs", "pair of water goggles", "panda", "pants", "paper", "paperclip", "pasta strainer", "pearl necklace", "pen", "pencil", "pencil holder", "pepper shaker", "perfume", "phone", "photo album", "picture frame", "piece of gum", "pillow", "pinecone", "plastic fork", "plush pony", "plush rabbit", "plush unicorn", "pocketknife", "pocketwatch", "pool stick", "pop can", "postage stamp", "puddle", "purse", "purse/bag", "quartz crystal", "quilt", "rabbit", "radio", "rat", "remote", "rhino", "ring", "rock", "roll of duct tape", "roll of gauze", "roll of masking tape", "roll of stickers", "roll of toilet paper", "rolling pin", "rope", "sand paper", "sandal", "sandglass", "scallop shell", "scarf", "scotch tape", "screw", "screwdriver", "seat belt", "shampoo", "shark", "sharpie", "shawl", "sheep", "sheet of paper", "shirt", "shirt button", "shoe lace", "shoes", "shopping bag", "shovel", "sidewalk", "sketch pad", "slipper", "socks", "sofa", "spatula", "speakers ", "spectacles", "spice bottle", "sponge", "spool of ribbon", "spool of string", "spool of thread", "spool of wire", "spoon", "spring", "squirrel", "squirt gun", "statuette", "steak knife", "straw", "street lights", "sun glasses", "sword", "table", "tea cup", "tea pot", "teddies", "television", "tennis ball", "tennis racket", "thermometer", "thimble", "thread", "tiger", "tire swing", "tissue box", "toe ring", "toilet", "toilet paper tube", "tomato", "toy boat", "toy car", "toy plane", "toy robot", "toy soldier", "toy top", "trash bag", "tree", "trucks", "tube of lip balm", "tube of lipstick", "turtle", "tv", "twezzers", "twister", "umbrella", "vase", "video games", "wallet", "washcloth", "wedding ring", "whale", "whip", "whistle", "white out", "window", "wine glass", "wireless control", "wishbone", "wooden spoon", "word search", "wrench", "wristwatch", "zebra", "zipper"],
"fruit": ["apple","apricot","avocado","banana","bell pepper","bilberry","blackberry","blackcurrant","blood orange","blueberry","boysenberry","breadfruit","canary melon","cantaloupe","cherimoya","cherry","chili pepper", "clementine", "cloudberry","coconut","cranberry","cucumber","currant","damson","date","dragonfruit","durian","eggplant","elderberry","feijoa","fig","goji berry","gooseberry","grape","grapefruit","guava","honeydew","huckleberry","jackfruit","jambul","jujube","kiwi fruit","kumquat","lemon","lime","loquat","lychee","mandarine","mango","mulberry","nectarine","nut","olive","orange","pamelo","papaya","passionfruit","peach","pear","persimmon","physalis","pineapple","plum","pomegranate","pomelo","purple mangosteen","quince","raisin","rambutan","raspberry","redcurrant","rock melon","salal berry","satsuma","star fruit","strawberry","tamarillo","tangerine","ugli fruit","watermelon"],
"clue-weapon": ["candlestick", "knife", "lead pipe", "dagger", "revolver", "rope", "wrench"]

With that, you’ve created your first Twitter Bot! This one is perhaps silly, but there’s nothing to preclude you from creating artistic or critical bots. Tracery is limited by its origin in interactive stories, thus it is not built to support complex logic, but it can still handily cover complex rules. Give it a try.


Creating a Second (or third, fourth, etc.) Twitter Account

Most people will want to create a new account for their Twitter bot.

I’ve found that the easiest way to do this is to open a window in privacy mode, use an email subaddress (i.e. plus address), and skip the onboarding.

In privacy mode, you don’t have to log out of your regular account (if you have one). In Chrome, this mode is reached with Ctrl+Shift+N. Remember that all your sessions are lost when you close privacy mode.

To create an account go to, then enter a name and an email address not linked with another Twitter account. If your typical email is already linked to an account, you don’t need to create a new address: most email providers support plus addressing for an alias to your regular email. For example, with Gmail, you can use, and emails sent there will arrive at

Click “Sign up” and click through the pages. Twitter give you various onboarding pages, but each screen has a subtle “Skip”, “Skip This Step”, or an option to uncheck the pre-selected options.

If you already tested Cheap Bots Done Quick with your regular account, you can authenticate the new Twitter account with CBDQ in a privacy mode window and copy-paste the Tracery definitions over.

One thought on “Your First Twitter Bot, in 20 minutes”

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s