Andrew Pilsch Blog

Making Twitter Bots w/ Cheap Bots Done Quick

Twitter bots, are great, right? Of course they are. People are talking about them at #cwcon in Findlay this weekend. I was talking about them with people at RSA. I run a few (here, here, and here). They are a really great way to get into the world of programmable rhetoric and to play around with some simple coding.

While a lot of people use Zach Whalen’s really amazing Google Sheets approach to running Twitter bots, I want to share a tool I have been using that generates tweets in a different way. While not better than Zach’s approach, it works a little differently and lets you produce some really neat content.

The platform I use for a few of my bots, especially @so_many_bees, is called Cheap Bots Done Quick and it is awesome. The project is by George Buckenham and uses Kate Compton’s extremely cool library Tracery. Tracery is powerful and Cheap Bots Done Quick makes bot hosting stupid easy. Together, I think they make a great platform for learning bot making and also teaching it to students.

I’m going to talk a little about what Tracery does before showing you how to host a bot using Cheap Bots Done Quick.

Tracery: Generative Grammars and You!

Tracery is a tool to parse a particularly written grammar to generate text (and images!) using a simple set of rules. But what does that mean?

Think of Tracery as a programmable Mad Libs. You remember Mad Libs? Where you would fill in the blanks with, say, a noun, a verb and an adjective, and end up with a sentence such as “My duck smoked red mayonnaise” and hilarity would ensue? Tracery works like that, substituting randomly selected values from rules you define into a predefined template.

This is different from Zach’s approach, which uses either a Markov chain algorithm to generate sentences based on a corpus or chooses pre-composed sentences from a list in a spreadsheet.

Let me give you an example.

Your First Tracery Grammar

Tracery grammars are written in a file format known as JSON (JavaScript Object Notation), which is a simple way to transport JavaScript data between processes (and humans) on the web. A Tracery grammar is a JSON data structure known as a hash. A hash is a data structure that associates a particular key with a particular value. In a hash, if I had a value foobar associated with the key a, when I asked for a from the hash (hash['a'] in JavaScript), the hash would give me foobar as the value.

Tracery requires one key/value pair defined in any grammar: the key origin is the start of the generation sequence. So a very simple Tracery grammar would look like this:

{
	"origin": "Hello world!"
}

The curly braces ({ and }) at the beginning and end of the code are how you indicate a hash in JSON. The name of the key (origin) goes before the colon and must be in quotes. The value associated with the key (Hello world!) goes after the colon. Any text must be in quotes (there are other things you can store at hash keys, but more on that below).

When we run our grammar, it will always return “Hello world!”. While we are generating sentences using computers (😱), this is not particularly interesting.

To make our grammar more exciting, let’s have it greet you by name:

{
	"origin": "Hello, #name#, welcome to Tracery!",
	"name": "dear reader"
}

In JSON, all entries in a data structure—such as our hash—have commas between them, so we have to put a comma after the line that contains origin.

When we run our grammar now, it will always return “Hello, dear reader, welcome to Tracery!”. Anything between pound signs (#) in Tracery is interpreted as a key in the grammar hash to substitute from. So when Tracery sees #name# in our grammar, it looks for a key name (the #s are thrown out) in the grammar, which we have defined, and substitutes its value.

This is still not very interesting, though, is it?

In JSON, there is a data structure called an array, which is a simpler kind of hash. Instead of having keys associated with values, the values all have keys referring to the numerical order in which the pieces occur. Basically, an array is like a line you have to wait in at the DMV: you don’t need to know everyone’s name in front of you, you just need to know how many people there are ahead of you.

When Tracery finds an array stored at a particular key, it randomly chooses one of the values from that array. This lets us use more than one value for a given key. To rewrite our grammar using an array, we could do this:

{
	"origin": "Hello, #name#, welcome to Tracery!",
	"name": ["Jane", "Jean", "June", "Jude"]
}

Brackets around a list of strings is how we write an array in JSON.

Now, when Tracery runs our grammar, it might produce “Hello, Jane, welcome to Tracery!” but it might also produce “Hello, June, welcome to Tracery!”. We can’t know for sure, because we have introduced some randomness into our grammar.

The power of Tracery lies in being able to nest rules, making more complicated sentences possible. For instance:

{
	"origin": "Hello, #name#, welcome to Tracery!",
	"name": ["#j-name#", "#a-name#", "#c-name#"],
	"j-name": ["Jane", "Jean", "June", "Jude"],
	"a-name": ["Allison", "Abigail", "Ava", "Alyssa"],
	"c-name": ["Charlotte", "Claire", "Cassandra", "Caroline"]
}

Here we are grouping names by first letter. You could add "#j-name" to the array stored at name more than once if you wanted to increase the probability of it occurring, for instance.

Take a look at Kate Compton’s Tracery tutorial for some even more advanced features, including how to modify text (capitalize, pluralize, etc.) and how to save values and branch your grammar based on those saved values.

Also, Compton has a groovy Tracery Editor, so you can start making grammars immediately! The key thing is that Tracery is amazingly powerful but with a simple and easy to master syntax.

Making a Bot with Tracery

Making a cool Tracery grammar for your bot can take some time, but, thankfully, once you have a grammar you are happy with, getting it posting on Twitter is simple.

1. Create a Twitter Account

To get started with Cheap Bots Done Quick, you will first need to create a Twitter account for your bot:

Image of Twitter's account creation screen with the information for "Test Bot" filled in.

Next, you will need to log into the account you have created. If you use a main Twitter account in your browser, consider using privacy mode (instructions for Safari, Chrome, and Firefox).

Before Going To Step 2: Be sure not to log into Cheap Bots Done Quick with your main account, or your new bot might start tweeting as you!

2. Authorize the App

Now that you are logged into your new bot’s Twitter account, go to Cheap Bots Done Quick and click “Sign In With Twitter”. You will be taken to a screen like the one below:

Image showing the screen Twitter uses to ask if you authorize the app to use your account

Click “Authorize App” to continue.

3. Enter / Test Your Tracery Grammar

In the Cheap Bots Done Quick editor, there is a textbox labelled “Tracery JSON”. Paste your grammar there, or start editing the one the app starts you off with. The app will check your JSON syntax and inform you of any errors as you go.

Below the textbox, you can see the output of your grammar. Press the refresh button to generate a new one. If you press the blue “Tweet” button, it will post the current output to Twitter.

When you are happy with your grammar, change the pulldown that says “Never” next to the phrase “post a tweet as” to how often you would like your bot to post (I usually post hourly).

You can also set it to reply to tweets generated using your Tracery grammar, either to tweets that match specific regular expressions or to all replies. For instance, you could write a regular expression to match certain words or phrases, and respond accordingly.

There are a lot of cool things you can do with this app!

Conclusion

That’s it! You just made a Twitter bot using a generative grammar!

While Tracery has a bit more of a learning curve than the tools Zach uses in his bot making tutorial, the power and sophistication of these grammars lets you produce some remarkably cool stuff, like @infinitedeserts, @thinkpiecebot, and @softlandscapes (which shows off Tracery’s SVG graphics capability).

Also, as an added bonus, if you do any JavaScript coding, you can use Tracery for content generation tasks beyond bot making. For instance, I used it to generate random Tiki drink descriptions for a menu app I use to offer cocktails to guests.

Have fun with Tracery and Cheap Bots Done Quick, and let me know what you come up with!

Back Home