> This article is also available in HTML at: http://www.vincentbruijn.nl/articles/____p_____i____/
> For a full index of articles, see: http://www.vincentbruijn.nl/llms.txt

# π

- **Date**: 2016-05-10
- **Author**: Vincent Bruijn
- **Description**: Technical description of a Twitter bot tweeting pi decimals written by Vincent Bruijn, Yet Another Visual Artist
- **Keywords**: π-day, pi-day, pie day, twitter bot, pi decimals, creative coding, code art

---

Twitter bots are all around. I love them. I made some, and I follow a lot of them. Some time after π-day (or pi-day) last March (it's March 14th every year), I came upon the idea to create a Twitter bot that posts irregularly decimals of π. It starts, of course, with π and a lot of its decimals...

```javascript
module.exports = '3.141592653589793238462643383279502884197169399';
```


First off I had to find some π decimals. Searching around the internet I found 1,000,001 decimals of π as a string. I added them to a JavaScript file called `pi.js`. It could have been named `π.js` too, probably.

Then we need to init the project, and give it a name and a license. I decided to add the [WTFPL](http://www.wtfpl.net/), since I don't give a f•¶k about the copyright on the code.

```
$ npm init
```

That's a starting point. I wanted it to be a piece of code that can tweet by itself, so we also need the [twitter](https://www.npmjs.com/package/twitter) NodeJS package, since I wanted the project to be written in JavaScript.

```
$ npm install --save twitter
```

This is all just basic setup. And in order to be able to tweet around by code, you'll need some authentication keys from Twitter to get along. The best tool for this is [twurl](https://github.com/twitter/twurl). It's a bit of a hassle to get it going, I mean, Twitter doesn't make it _that_ easy for you to create a piece of software that can talk to it. But once you got your keys all set, it's just a matter of including the right keys.

There are several ways to keep these keys outside of your GIT repository, of which I use the simplest, but still a bit error prone, method: just have a `config.js` file that you add to your `.gitignore`. This method is _not_ very portable, I know, but in my situation I don't need to share the code too much anyway.

```javascript
module.exports = {
  consumer_key: 'qweasdzxc',
  consumer_secret: 'ertdfgcvb',
  access_token_key: 'tyughjbnm',
  access_token_secret: 'poilkjmnb',
};
```

That all being set up, will get us to the resulting code, which is only 20 SLOC:

```javascript
#!/usr/bin/env node

var Twitter = require('twitter');
var BIG_PI = require('./pi');
const config = require('./config');

var client = new Twitter({
  consumer_key: config.consumer_key,
  consumer_secret: config.consumer_secret,
  access_token_key: config.access_token_key,
  access_token_secret: config.access_token_secret,
});

var tweetLength = 140;
var index = 0;
var offset = index * tweetLength;

var tweet = BIG_PI.substr(offset, tweetLength);

client.post('statuses/update', { status: tweet }, function () {
  console.log(arguments);
});
```

The only thing that's lacking in this code, is the logic that tracks the index. The easiest way to do that, is to add a file to the project in which you store the value for the index. This way, any time your bot fails, it is able to continue where it was. During runtime you're able to hold it in memory, but since you won't be tweeting continously, your code has time enough to persist is to the file anyway.

The steps to take to create a text based Twitter bot in general are these

- Create a Twitter account with a nice name
- Within your Twitter account, you will have to set up an application that can access your account
- Use `twurl` to generate access keys to Twitter for that account
- Initialize your project with `npm init`
- Add at least the `twitter` dependency

What to keep in mind when creating a bot is this:

- What's the interval you want it to tweet?
- Should your code persist any state in order to continue after failure?
- If the code needs any I/O, which of that can be cached during runtime?
- Or which of it can be done in idle time? (i.e. while not tweeting)
