All Posts in Code

September 2, 2014 - 29 comments

Exploring the Twitter API with Meteor.js

Exploring the Twitter API and Meteor.js

The Twitter API is thoughtfully designed, and the data set that it provides access to is incredibly rich.

I wanted a super quick, no-fuss way to retrieve, process, and display tweet data on the web, and have been obsessed with Meteor.js ever since I started using it on our pet project Songnotes. It's easier to set up an app and run a dev server than any other method I've encountered, and it keeps everything in JavaScript, meaning that I can display the data directly on the web with no intermediate hassle. Plus it just feels so cutting edge. Since I didn't find a straightforward tutorial on how to do this elsewhere on the web, I've outlined the steps I came to below.

Step 1: Create your Meteor app

If you've never tried Meteor before, the simplicity of installing it and creating your first app will blow your mind. You can follow the quick start, or try the tutorial on creating an example app first if you prefer.

Step 2: Obtain a Twitter access token

In order to access the API, Twitter requires an access token. There are a number of ways to get one depending on what you expect to be doing; I opted for the standard single-user developer token because it was easy to obtain and would give me all the access I'd need for the kind of data mining I want to do.

Step 3: Install a Twitter API client library

There are several different wrapper libraries to simplify access to the Twitter API  from Node (Meteor runs on a Node server, FYI) and twit seemed to be the most concise and straightforward to me, with a fairly large user base and frequent updates.

First enable NPM modules in your Meteor app

Running pure Node packages in a Meteor app requires first installing support for non-Meteor npm modules within your Meteor app:

meteor add meteorhacks:npm

Then add the specific package you need

Create a file called packages.json in the root of your app and add the package name and version number (1.1.19 at the time of this writing):

{
    "twit": "1.1.19"
}

And you're ready to go! Let's write some code.

Step 4: Do a test query

Open up myapp.js (or whatever the name of the main app file is that you created in Step 1), and edit the following section:

if (Meteor.isServer) {
  Meteor.startup(function () {
    // code to run on server at startup

  });
}

to look like this:

if (Meteor.isServer) {
  Meteor.startup(function () {
    // code to run on server at startup

    var Twit = Meteor.npmRequire('twit');

    var T = new Twit({
        consumer_key:         '...', // API key
        consumer_secret:      '...', // API secret
        access_token:         '...', 
        access_token_secret:  '...'
    });

    //  search twitter for all tweets containing the word 'banana'
    //  since Nov. 11, 2011
    T.get('search/tweets',
        {
            q: 'banana since:2011-11-11',
            count: 100
        },
        function(err, data, response) {
            console.log(data);
        }
    );

  });
}

filling in the '...' bits with the keys you obtained in Step 2.

It's important that sensitive information like certain API keys only be used within a Meteor.isServer block (or in a server-only file) in Meteor, otherwise your keys will be visible for all the world to see.

Now run your app by typing meteor on the command line from your app directory. If all went well, it should spit out a ton of json-structured content along the lines of

 { statuses: 
    [ { metadata: [Object],
        created_at: 'Mon Jun 23 04:06:56 +0000 2014',
        id: 480924945586069500,
        id_str: '480924945586069504',
        text: '@Nukes_Pringles banana',
        source: 'Twitter for iPhone',
        ...

Twitter is talking to us! Sweet. There are are more example queries to experiment with over at the twit github page, and in a future post I'll talk about what we might actually do with this data and how to display the parts we want on a web page.

Updated 1/27/2015 to use the latest version of Meteor, 1.0.3.1.