Bartleby The Twitterbot: Building a Twitter Bot with node.js and ttezel/twit

Posted on July 9, 2015

Bartleby, the Scrivener: A Story of Wall Street is a short story by Herman Melville, published in 1853. I will not spoil the plot of this great book here, instead I'll talk about Bartleby the Twitterbot.

Some time ago (not sure if on Twitter or this blog) I mentioned working on two projects that user RiveScript. Well, I had to put one of them aside as I run into an issue with mobile browsers and I am not really sure if I want the project to be “desktop only”. This first project was meant as an opportunity for me to learn working with RiveScript, so I came up with another easy project instead.

@bartleby_scrvnr is a Twitter bot built with node.js and uses the ttezel/twit Twitter client. @bartley_scrvnr responds to @ mentions with lines used by Bartleby in the book; these lines are not entirely random and do change based on the content of the tweet.

Now, there is more than enough tutorials for creating Twitter bots, (although you might want to read this if you want to create multiple Twitter bots and don't have enough phone numbers) but I wanted to write a little bit about an issue I run into myself; hopefully this post will be useful to some other people.

Problem: How do I make my twitterbot actually respond to a tweet, so there is a threaded conversation on Twitter?

Solution: Use in_reply_to_status_id!

Problem #2: It's not working!

Solution: Right. The issue here is that the ID of the tweet you are responding is too large for JavaScript, so you will have to use the string version – but don't actually supply it as in_reply_to_status_id_str!

If you're using the API client I mentioned above, your code should look something like this:

Note that I am actually pushing my responses to a queue, so I can both avoid hitting Twitter's API rate limits and also make the bot appear a bit more human-like as the Tweets are posted with a random delay.

stream.on('tweet', function (tweet) {
 tweetQueue.push({
   id: tweet.id\_str,
   text: '@' + tweet.user.screen\_name + ' ' + tweet.text
 });

//Inside a function that is run on setTimeout.

if (tweetQueue.length > 0){
  var newTweet = tweetQueue.shift();
  twitter.post('statuses/update',
  {
    status: newTweet.text,
    in\_reply\_to\_status\_id: newTweet.id
  }, function(err, data, response) {
    // …
  });

Notice that I'm actually matching in_reply_to_status_id with tweet.id_str.

And that's really it! Bartleby is still a work in progress as I'm improving the responses, but I already consider it a success as I'm finally getting familiar with RiveScript – and as a bonus I have a very nice skeleton project for more Twitter bots :-)