Published in


Creating Your Own Whimsical Twitter Bot With Tracery

Inspired by a series of awesome Twitter bots that tweet seemingly random, but hilarious messages such as or , I set out to create some of my own. One that tweets random ideas for board games, and the other (that ties to a fiction project I’ve had in progress for some time) that tweets how the world ended. I didn’t want to spend too much time initially on the project, and someone recommended a site called , which does what its name implies, and is powered by , an open source Twitter bot library, meaning I could self-host when I was ready.


Using the site to create and self-host your bot is incredibly easy; you log in with the Twitter account for your bot and add a string of JSON that represents the bot. Here’s the early code for :

"origin": "You are #you_are# #doing# #with_what# in #in#",
"you_are": ["Dress makers", "Farmers", "Villagers", "Warriors", "Investigators", "Fire fighters", "Scientists", "Explorers", "Wine makers", "Writers", "Superheroes", "Wizards", "Ponies", "Corporations", "Factions", "Cattle Herders", "Civilizations", "Soldiers", "Knights", "Politicians", "Senators", "Generals","Clans","Vikings","Zombies","Cultists","Settlers","Sherlock Holmes","Meeples"],
"doing": ["Exploring", "Exploiting", "Growing", "Painting", "Eating", "Investigating", "Fighting", "Building", "Trading", "Delivering", "Terraforming", "Researching","Producing","Brewing","Protecting","Eating","Surviving","Escaping"],
"with_what": ["Crops", "Great Old Ones", "Disease", "Trains", "Money", "Territory", "Ships", "Sheep", "Packages", "Resources", "Spaceships", "Meeples","Cultists","Zombies","A Dragon","Detectives","Victory Points"],
"in": ["Renaissance Italy", "Medieval Europe", "The Far East", "Deep Space", "Germany", "North America", "The Deepest Ocean", "Wall Street", "The 1920s", "The Far Future", "Mars", "19th Century America", "Ancient Greece", "Ancient Rome", "Ancient Egypt","Dungeons","Scotland","Australia"]

that I won’t replicate here, but the syntax above is reasonably clear, the origin key contains the text with placeholders, and the other keys contain values that tracery randomly inserts into the placeholders. You might notice quickly that your bot might start committing grammar crimes, and while you can design your string to accommodate this, Tracery also has a series of to help. For example, for flexibility, I could remove the plural form of some of the text above, and instead use the .s modifier:

"origin": "You are #you_are.s# #doing# #with_what.s# in #in#",

When finished, you set how frequently the bot should tweet and click save.


For many bots and their creators, this may be enough, but I was interested in self-hosting my bots so I could do more with them, such as re-purpose the same data model for other bot platforms and ideas, allow others to contribute to the data model, plus other ideas I haven’t had yet. I opted to use node.js and Heroku for mine, but of course, many other options are available.


First, add the , , and NPM modules to your project. If you also decide to use Heroku, then you might find their tool useful.


I toyed with attempting to get all the bot vocabulary into one file, but ended up splitting it into three files for each list. I won’t reproduce them all here, but you can see them in I found the simplest way to add them as arrays was with a series of require statements:

let you_are = require('./you_are.json');
let doing = require('./doing.json');
let with_what = require('./with_what.json');
let in_place = require('./in.json');

Create Grammar

With the vocabulary in place, add it to Tracery, generate your tweet text, and add any modifiers from above:

const grammar = tracery.createGrammar({
"you_are": you_are,
"doing": doing,
"with_what": with_what,
"in": in_place,
"origin": ["You are #you_are# #doing# #with_what# in #in#"],
grammar.addModifiers(tracery.baseEngModifiers);const tweet = grammar.flatten('#origin#');

Send Tweet

With the text ready to broadcast to the world, create a Twitter client and post your witticisms to the world. Running locally, I use keys provided by the dotenv module and a .env file, but running on Heroku, it uses provided by the platform, but you can transition from one to the other without changing anything.

const T = new Twit(
consumer_key: process.env.TWITTER_CONSUMER_KEY,
consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
access_token: process.env.TWITTER_ACCESS_TOKEN,
access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET
T.post('statuses/update', {status: tweet + " #boardgames"}, (err, data, response) => {

Schedule Tweets

For now, I want the bot to tweet once a day, so I used the . It requires a shell script to run at each interval, so I created bin/run_bot.sh, which has one command:

#!/bin/bash node index.js


And that’s it! Once a day, my bot delivers wonderful words to all the boardgame fans of the internet, and I have a flexible code and vocabulary base for future features and other platforms.

Enjoy, and see you at the gaming table!

Originally published at .



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
Chris Chinchilla

I explain cool tech to the World. I am a Technical Writer and blogger. I have crazy projects in progress and will speak to anyone who listens.