Build a Node.js Twitter bot

Twitter bots are fun, and quite simple to make. You have to be careful about what you program your bot to do so it doesn't get banned for spamming, but the basic code can be adapted for all kinds of things. Here's how I built a bot using Node.js to send people hugs or pugs.

If you want to follow along, you can either create a new directory and copy the code step by step, or fork my repo.

Setup

Firstly, you need to register your bot as an application with Twitter in order to access the API. Create a new Twitter account for your bot - don't use your personal one - otherwise Tweets will come from you and not the bot. It's also useful to have this separate in case you mess up and end up getting suspended, as this way you won't risk losing access to your personal account. Create an access token and make sure its access level is set to 'Read, write, and direct messages'.

If you don't already have Node.js installed, you'll need to do that next.

Now go to your project directory. If you're working from a fork of mine, just run npm install, then move onto the authentication section. If you started a new project, run npm init and follow the instructions to create your package.json. Then run npm install twode --save to install twode (the Twitter API client we're using). Your project directory should now contain a node_modules directory.

Authentication

Create a file in your project directory called auth.js to store your API authentication config, and add it to your .gitignore:

var config = {
  CONSUMER_KEY: 'YOUR UNIQUE CODE FROM THE API',
  CONSUMER_SECRET: 'YOUR UNIQUE CODE FROM THE API',
  ACCESS_TOKEN_KEY: 'YOUR UNIQUE CODE FROM THE API',
  ACCESS_TOKEN_SECRET: 'YOUR UNIQUE CODE FROM THE API'
};

We're going to use environment variables to avoid hard coding these values. You don't want them public otherwise anyone could control your Twitter bot.

To set the environment variables, add this loop to auth.js:

// Set API keys for dev environment.
for (var key in config) {
  process.env[key] = config[key];
  console.log('process.env.' + key + ' has been set to: ' + process.env[key]);
}

Then, from your project directory, run node auth.js and check the correct keys have been set. You only need to do this once.

Code

Now create a new file called bot.js. This is where you'll write the rest of your code.

We're using the twode module, so require that at the top of your bot.js file:

var twitter = require('twode');

To create the bot and feed it the correct authorization info, we're going to use the prototype pattern. This is the constructor function, which takes a Twitter handle and references the environment variables we set:

function Bot(handle) {
  this.handle = handle.charAt(0) === '@' ? handle : '@' + handle;
  this.twitter = new twitter({
    consumer_key: process.env.CONSUMER_KEY,
    consumer_secret: process.env.CONSUMER_SECRET,
    access_token_key: process.env.ACCESS_TOKEN_KEY,
    access_token_secret: process.env.ACCESS_TOKEN_SECRET
  });
}

From this point, the code is going to be specific to my bot, but it's easily adaptable to do other things.

I want my bot to either Tweet hugs or a pug picture, based on a random chance outcome. So let's store some pug pictures:

Bot.prototype.pugs = [
  'http://bit.ly/1boVVNH',
  'http://bit.ly/1aVWjl3',
  'http://bit.ly/Ik6yoi',
  'http://bit.ly/1aZrkng',
  'http://bit.ly/18oFYqv',
  'http://bit.ly/doqglS',
  'http://bit.ly/195gk56'
];

I want a 10% chance of responding with a pug picture, so let's write a function to determine whether a given response should be a pug or not:

Bot.prototype.isPug = function() {
  function getRandNum(min, max) {
    return Math.floor((Math.random() * max) + min);
  }

  return getRandNum(1, 10) > 9 ? true : false;
};

And a function to build the response:

Bot.prototype.getResponse = function(userHandle) {
  var response = '@' + userHandle;

  if (this.isPug()) {
    var pugPic = this.pugs[Math.floor(this.pugs.length * Math.random())];
    response += ' hugs over the internet can be tricky, but luckily, pugs are plentiful ' + pugPic;
  } else {
    response += ' HUGBOT SENDS HUGS'
  }

  return response;
};

The next function is where we listen for the stream of Tweets, filtering based on the bot's Twitter handle. This means that when someone mentions the bot, it will generate a response and post it as a Tweet.

Bot.prototype.run = function() {
  var bot = this;

  this.twitter.stream('statuses/filter', { track: this.handle }, function(stream) {

    console.log('Listening for Tweets...');

    stream.on('data', function(tweet) {
      var status = bot.getResponse(tweet.user.screen_name);

      bot.twitter.updateStatus(status, function(err) {
        if (err) return bot.handleError(err);
      });
    });
  });
};

We've referenced a handleError function here in the callback, to log any errors in case something goes wrong. Let's write that now:

Bot.prototype.handleError = function(error) {
  console.error('Status:', error.statusCode);
  console.error('Data:', error.data);
};

To make all of this work, all that's left to do is create an instance of the bot, passing its Twitter handle as a parameter, and call the run function:

var hugbot = new Bot('hugsorpugs');
hugbot.run();

We can now actually run it to see it working by typing node bot.js.

Next, you might want to learn how to deploy your bot on Heroku.