Twitter API with JavaScript

Twitter API with JavaScript

Click Here for TL;DR

Recently I needed to use Twitter’s REST API for a project. I was building a web app with JavaScript using AngularJS framework. I am not a back end developer so my projects end up using a combination of BaaS (Back End As A Service) software like Firebase and utilizing node.js environment. So my question was “How do I use the Twitter API with JavaScript?”

Using Twitter API with JavaScript

On Twitter’s website they list some libraries for leveraging their API. Under javascript/node you can find @BoyCook’s Twitter JS Client. This is a useful library for using node.js to access Twitter’s API. What I wanted to do was walk you through setting up your node/express environment to utilize BoyCook’s Twitter JS Client so that you can access Twitter’s API effortlessly with your client side application.

First a brief run through of Twitter JS Client

Twitter JS Client has a dependency of OAuth and qs. OAuth for authentications and qs for building query strings for your URIs. That is all I will say about the functionality of Twitter JS Client because we want to use it first and foremost. Understanding it is a good idea but not what most are interested in. So… onto configuration.

configuration

First thing you need to do in order to access Twitter’s API is create a Twitter App. You can do that here. A check iag.me’s tutorial blog post on setting up your Twitter App.

Next, as you will notice in BoyCook’s README.md file you have some configuration setup you need to do. What isn’t mentioned is that this code will go inside the index.js file of your node app. We will talk more about that later.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
    //Callback functions
    var error = function (err, response, body) {
        console.log('ERROR [%s]', err);
    };
    var success = function (data) {
        console.log('Data [%s]', data);
    };

    var Twitter = require('twitter-node-client').Twitter;

    //Get this data from your twitter apps dashboard
    var config = {
        "consumerKey": "XXX",
        "consumerSecret": "XXX",
        "accessToken": "XXX",
        "accessTokenSecret": "XXX",
        "callBackUrl": "XXX"
    }

    var twitter = new Twitter(config);

    //Example calls

    twitter.getUserTimeline({ screen_name: 'BoyCook', count: '10'}, error, success);

    twitter.getMentionsTimeline({ count: '10'}, error, success);

    twitter.getHomeTimeline({ count: '10'}, error, success);

    twitter.getReTweetsOfMe({ count: '10'}, error, success);

    twitter.getTweet({ id: '1111111111'}, error, success);


    //
    // Get 10 tweets containing the hashtag haiku
    //

    twitter.getSearch({'q':'#haiku','count': 10}, error, success);

    //
    // Get 10 popular tweets with a positive attitude about a movie that is not scary
    //

    twitter.getSearch({'q':' movie -scary :) since:2013-12-27', 'count': 10, 'result\_type':'popular'}, error, success);

The first two variables are setting success and error callbacks that are used when getting a response from Twitter’s servers after you make a request. Next is including the Twitter.js dependency we mentioned earlier. Next is the config object. This is where you enter the information found in the app you created with your Twitter developer account. Lastly is the new instance of from your Twitter.js dependency, var twitter and some sample requests.

An Update to the Configuration

One of the things I like to do is change the error callback to something more readable. Changing var error to the following will do that.

1
2
3
var error = function (err, response, body) {
    console.log('ERROR [%s]', JSON.stringify(err));
};

Okay so now all you need is your entire node app 😛

Your Node Application

I am going to show you the file and then we will go through it’s parts. You can also see it as a Gist here

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
//importing Twitter JS Client dependancy
module.exports = require('./lib/Twitter');


// VARIBALES
var express = require('express');
var OAuth2 = require('oauth').OAuth2;
var https = require('https');
var app = express();
var bodyParser = require('body-parser');
var error = function (err, response, body) {
    console.log('ERROR [%s]', JSON.stringify(err));
};
var success = function (data) {
    console.log('Data [%s]', data);
};
var config = {
    "consumerKey": "XXX",
    "consumerSecret": "XXX",
    "accessToken": "XXX",
    "accessTokenSecret": "XXX"
};
var twitter = new module.exports.Twitter(config);
var port = process.env.PORT || 3000;
var server = app.listen(port, function () {
    console.log('Server running on port ' + port);
});

//TWITTER AUTHENICATION
var token = null;
var oauth2 = new OAuth2(config.consumerKey, config.consumerSecret, 'https://api.twitter.com/', null, 'oauth2/token', null);
oauth2.getOAuthAccessToken('', {
    'grant_type': 'client_credentials'
  }, function (e, access_token) {
        token = access_token;
});


//APP CONFIG
app.use( bodyParser.json() );       // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({     // to support URL-encoded bodies
  extended: true
}));

//public is the folder your angular application is in.
//This allows your angular app to handle routing when you hit the URL root (/)
app.use(express.static('public'));


//ENDPOINTS

//unauthenticated request
app.post('/twitter/user', function (req, res) {
    var username = req.body.username;
    var data = twitter.getUser({ screen_name: username}, function(error, response, body){
        res.send({
            "error" : error
        });
    }, function(data){
        res.send({
            result : {
                "userData" : data
            }
        });
    });

});

//authenticated request
app.post('/twitter/user/github', function (req, res) {
        var username = req.body.username;
        var options = {
            hostname: 'api.twitter.com',
                    //this path will search for tweets from specified user
                    //with "github" mentioned in them
            path: '/1.1/search/tweets.json?q=github%3A' + username,
            headers: {
                Authorization: 'Bearer ' + token
            }
        };

        https.get(options, function(result){
          var buffer = '';
          result.setEncoding('utf8');
          result.on('data', function(data){
            buffer += data;
          });
          result.on('end', function(){
            var tweets = JSON.parse(buffer);
            res.send(tweets);
          });
        });

});

Okay so some explanation is warranted here. We will be coming back to reference this file the rest of the article.

Setting Variables

I won’t mention the variables we brought up when talking about configuring BoyCook’s Twitter JS Client.

var express: this includes express which allows you to do routing with your application (it does much more then that, you can learn more by clicking here)

Fast, unopinionated, minimalist web framework for Node.js

var OAth2: this includes requirements for authentication against twitter.

var https: https media

var app: initiating express framework

var bodyParser: we use this for handling JSON request from the client

var port: setting port for app to run on

var server: starting app on specified port

Authenticating with Twitter

What we are doing here is setting up our Application Only Authentication

1
2
3
4
5
6
7
8
//TWITTER AUTHENICATION
var token = null;
var oauth2 = new OAuth2(config.consumerKey, config.consumerSecret, 'https://api.twitter.com/', null, 'oauth2/token', null);
oauth2.getOAuthAccessToken('', {
    'grant_type': 'client_credentials'
  }, function (e, access_token) {
        token = access_token;
});

You can learn more about it with this blog post.

Setting Up Your Endpoints

The first example is an unauthenticated request. This example is getting a Twitter User’s data. The node application will look for a post to the specified URI and then use the username found on the request body (req.body.username) as an argument to the Twitter JS Client method of getUser().

We will talk more about hitting these endpoints from your application in a bit.

In the getUser() callback function we respond, res.send() with either and error or the data from a successful request. How you structure this data is entirely up to you.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//unauthenticated request
app.post('/twitter/user', function (req, res) {
    var username = req.body.username;
    var data = twitter.getUser({ screen_name: username}, function(error, response, body){
        res.send({
            "error" : error
        });
    }, function(data){
        res.send({
            result : {
                "userData" : data
            }
        });
    });

});

The next example is an authenticated request. This example is getting posts for a specific user. This example does not use the Twitter JS Client at all and can be used as a template to create requests to Twitter’s API on your own.

You will notice quite a bit of extra code in the authenticated request verse the unauthenticated request. The first difference is that we are setting some http request options that are passed into our GET request. These are done to follow Twitter’s API requirements. You can read more about them here. The most important part on this options config is the headers where we are setting Authorizaion with the token from our OAuth request.

Another thing to notice is how we handle our response. The response for this request to Twitter’s REST API comes back in parts, so we need to handle them accordingly. What result.end() is doing for us is waiting until we have received the entire response before sending it to the client. You can read more about that here.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
app.post('/twitter/user/github', function (req, res) {
        var username = req.body.username;
        var options = {
            hostname: 'api.twitter.com',
                    //this path will search for tweets from specified user
                    //with "github" mentioned in them
            path: '/1.1/search/tweets.json?q=github%3A' + username,
            headers: {
                Authorization: 'Bearer ' + token
            }
        };

        https.get(options, function(result){
          var buffer = '';
          result.setEncoding('utf8');
          result.on('data', function(data){
            buffer += data;
          });
          result.on('end', function(){
            var tweets = JSON.parse(buffer);
            res.send(tweets);
          });
        });

});

Using Your New API with Your Angular App

Okay so the title of this article is twitter api with javascript, we got into some javascript with node but now for the front end.

Below is a very basic example of utilizing the twitter api with javascript using the API we just built. I will show you the code, then explain it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
var app = angular.module('myApp', []);

app.controller('myCtrl', function($scope, TwitterService){
  TwitterService.getUser('jacstecar')
    .then(function(data){
        //do work with data
    })
    .catch(function(error){
        console.error('there was an error retrieving data: ', error);
    })
});

app.factory('TwitterService', function($http, $q){
 
  var getUser = function(username){
    var d = $q.defer();
    $http.post('/twitter/user', {username : username})
      .success(function(data){
        return d.resolve(data);
      })
      .error(function(error){
        return d.reject(error);
      });
    return d.promise;
  };

  return {
    getUser : getUser
  }
});

The above example is as bare bones as it gets as I mentioned. We are using Angular’s $httpProvider to send a post to our endpoint. We are passing in an object with a username property that our API uses (req.body.username) to hit Twitter’s API.

Dependencies and Initializing Your App

Below is the package.json file that will download all the dependencies you need for your node/Angular application.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "name": "packageName",
  "description": "Your Description",
  "version": "0.0.1",
  "private": false,
  "main": "index.js",
  "dependencies": {
    "oauth": "^0.9.12",
    "twitter-node-client": "*",
    "qs": "^2.4.1",
    "body-parser": "^1.12.2",
    "express": "^4.12.3"
  },
  "engines": {
    "node": "0.10.x"
  }
}

Now to launch your application simply run

1
2
$npm install
$ node index.js

And navigate to http://localhost:3000

You can see the full project on my GitHub account. Twitter API with Node and Express

Here is a list of the methods available out of the box with BoyCooks Twitter JS Client that make it easy to use the twitter api with javascript:

getUserTimeline

getMentionsTimeline

getHomeTimeline

getReTweetsOfMe

getTweet

getUser

Hopefully this was helpful in teaching a few of you to use the Twitter API with Javascript for your web applications.

It is also important to mention that the responses I have set up in the sample application are for example, here is some documentation on proper handling of responses.

In The End

Inclue BoyCook’s Twitter JS Client.

View my use of it in a node and Angular application.

Start Using the Twitter API with JavaScript!

Pro Tip: Create and Update a NPM Package Your Own

You can create your own npm package. Simply create your project and a package.json file along with it.

When in the root directory of your project where your package.json file lives runt the following command:

1
$ npm publish ./

When you create a new version of your project and update the version number in your package.json you can run the following command to push that update out to the world:

1
2
$npm tag <package_name>@<version_number>
$npm publish

15 thoughts on “Twitter API with JavaScript

  1. Diego

    I cannot get your example to work, I downloaded the whoie project from github, but I don’t know where am I supposed to put each of the files, inside of the node folders structure.
    I have my node installed in:

    C:\Program Files\nodejs

    inside of that folder I have:
    ..\node_modules\npm and many others

    Do you have anything more elaborated on how to set up your twitter app( the one from github)?

    Also, can I use this web service from an html page in my XAMPP hytdocs folder? I mean… is it possible to consume the API that we turned on in node, from XAMPP, once you get node to listen in one port, since both are in localhost?

    Thanks in advance!

    Reply
    1. Jacob Post author

      Hi Diego,

      Sorry for the delayed response.

      The repository has been updated since this post, it actually has a working AngularJS app that is consuming our API.

      In regards to the first question, here is a step by step guide for installing/building the example app:

      1) clone or download the repository found here

      git clone https://github.com/jacobscarter/Twitter-API-with-Node-and-Express.git
      

      2) change directories into the folder of the repository you just cloned or downloaded

      cd ./Twitter-API-with-Node-and-Express
      

      3) Install all dependencies

      npm install
      

      4) Start the node server

      node index.js
      

      5) Navigate to http://localhost:3000

      You will now see your app and some example of using the API.

      There are more ways than just the step I listed above to get your app up and running, but the steps listed above are the most straight forward. I would start digging through the angular app and you will see how we are sending HTTP requests to our endpoints of our node API.

      Let me know if you have anymore questions.

      NOTE: You will also need to create a Twitter App to get the consumer and access tokens and secrets to put in your index.js file. See those instructions here.

      Thanks!

      Reply
  2. Victor

    Hey Jacob, I know this is going to be a very late question, but I’m trying to change your API to work with twitter searches, where I enter some keyword and I try to run getSearch instead of your getUser to get the list of relevant tweets. However I’m getting an error where twitter.getSearch is apparently not a function. I was wondering if you could provide any insight into that. Thank you.

    Regards,
    Victor

    Reply
        1. Jacob Post author

          Hi Indira,

          It looks like the npm package name has been changed to ‘twitter-node-client’ so the npm install will no longer work in my repo. I am updating GitHub and the blog post now.

          Thanks

          Reply
  3. Orion

    Hi Jacob

    This looks great, and works well out of the box for all those searches and what not.
    I am using this in with Ember.. which seems to be working alright.
    My question is whether you have any examples of using the Post functionality of the Twitter API?

    Cheers
    Orion

    Reply
    1. Jacob Post author

      Hi Orion,

      I’m not sure what you mean, I have examples making a POST HTTP request, or do you mean something else?

      Jacob Carter

      Reply
      1. Orion

        Hi Jacob
        Thanks for the reply, I’m meaning specifically to use the twitter.postTweet function
        It seems the GET functions work, but I can’t seem to find a way to use the POST
        Cheers
        Orion

        Reply
        1. Jacob Post author

          Hi Orion,

          Okay so you mean use this function of BoyCooks library to create a new tweet?

          1
          2
          3
          4
          5
          Twitter.prototype.postTweet = function (params, error, success) {
              var path = '/statuses/update.json';
              var url = this.baseUrl + path;
              this.doPost(url, params, error, success);
          };

          Here is a Gist of the things you would need to add to index.js and public/app.js

          Hope this helps!

          Reply
      1. Jacob Post author

        It look like ‘twitter-js-client’ has renamed to ‘twitter-node-client’. This may be causing some of the errors, I am updating my GitHub repo and this blog post now.

        Reply

Leave a Reply

Your email address will not be published. Required fields are marked *