TwitterBot

This post refers to work on the 4th of August which was day 51 of my #100daysofcode

Initialise a node application

npm init

Install the twitter modules

npm install twitter --save

Edit/create the index.js file:

nano index.js

Paste in the required details (obviously I am not putting my tokens in here or on Github).

var Twitter = require('twitter');
var client = new Twitter({
    consumer_key: ‘’,
    consumer_secret: ‘’,
    access_token_key: ‘’,
    access_token_secret: ‘’
});

Add an example call to the REST API:

client.get(‘favorites/list’, function(error, tweets, response) {
    if(error) throw error;
    console.log(tweets); // The favorites.
    console.log(response); // Raw response object.
});

This brings back a list of my favourites into the console.

Add in an example call to the Streaming API:

var stream = client.stream(‘statuses/filter’, {track: ‘javascript’});
stream.on(‘data’, function(event) {
    console.log(event && event.text);
});
stream.on(‘error’, function(error) {
    throw error;
});

This ticks away logging mentions of the word javascript.

I switch to using my Twitter ID (the numerical one not my handle):

var stream = client.stream(‘statuses/filter’, {follow:27426152});
stream.on(‘data’, function(event) {
console.log(event && event.text);
});
stream.on(‘error’, function(error) {
throw error;
});

This logs certain things I do into the console pretty quickly. Tweets and retweets are included but not if I favourite something.

So next I add the track and my ID together, but with javascript mis-spelt as javacsript. After a few random attempts I realise I didn’t restart the NodeJS script so I do that and voila!

var stream = client.stream(‘statuses/filter’, {follow:27426152,track:’javacsript’});
stream.on(‘data’, function(event) {
 console.log(event);
});
stream.on(‘error’, function(error) {
throw error;
});

By logging only the event I am able to see the JSON structure of a raw tweet. It uses ‘id’ to store a reference to the tweet so I use that to construct a new tweet which is a reply to my original tweet with the text “Sorry *javascript*” as its body.

var stream = client.stream(‘statuses/filter’, {follow:27426152,track:’javacsript’});
stream.on(‘data’, function(event) {
   console.log(event);
   client.post(‘statuses/update’, {status: ‘@nigeljohnwade Sorry, *javascript*’, in_reply_to_status_id: event.id});
});
stream.on(‘error’, function(error) {
throw error;
});

Now if I tweet javacsript I get an almost immediate reply from myself correcting me to javascript.

Me correcting myself by bot

Marvellous.

I am surprised what a very easy process this is. Admittedly the majority of the heavy lifting is being done by the twitter module, I don’t have to set up the API calls to twitter myself, but not reinventing the wheel etcetera…

However at this point the script exits as I have not supplied the status update with a callback.

var stream = client.stream('statuses/filter', {follow:27426152,track:'javacsript'});
stream.on('data', function(event) {
    console.log(event);
    client.post('statuses/update', 
{status: '@nigeljohnwade Sorry, *javascript*', in_reply_to_status_id: event.id},
    function(err, tweet){
     if(!err) console.log(tweet);
});
});

stream.on('error', function(error) {
throw error;
});

And now an error of understanding on my part becomes apparent. This is an infinite loop, I assume the original tweet content is included in the response so I have to quickly exit the bot script.

Hey look recursion!

So I step away for the minute and think about how I am going to test this without spamming my feed and having to urgently Ctrl^C my script.

Repo so far: https://github.com/nigeljohnwade/twitterbot

UPDATE:

I misunderstood the way that the streaming API filtering is working. By using:

{follow:27426152,track:'javacsript'}

I am assuming that these two criteria sum and that only tweets by mr that contain ‘javacsript’ are going to be actioned. But they are assessed as an OR operation. So effectively I am actioning every tweet I make, not just those that contain the mis-spelt word. I am pleased that it is not recursion anyway.

Back to the API docs and the module docs to rewrite the code…

Show your support

Clapping shows how much you appreciated Nigel Wade’s story.