How To Get The Twitter API “GET users / lookup” Call To Work With OAuth In Ruby

6 Jan

I’m currently working a project that involves working with the Twitter API. The public Twitter API is pretty straight-forward to use, but after working with the OAuth API for the past few days, I was ready to tear my hair out! Luckily, I was able to get a more experienced developer friend to help me get the GET users/lookup Twitter REST API call to work (although it took him a few hours to figure this out as well). Here is how he did it:


We started out by trying out all the available Twitter OAuth ruby gems, and by far, the best one we found was the twitter_oauth gem. Unfortunately, this gem is missing the GET users / lookup call.

So, we used the available code in this gem to modify it to include the GET users / lookup call. We modified the Client class to the following:

# from the twitter oauth library https://github.com/moomerman/twitter_oauth
# added the users/lookup call and the rate_limit_status call

require 'oauth'
require 'json'
require 'mime/types'

module TwitterOAuth

  VERSION = '0.4.3'

  class Client

    def initialize(options = {})
      @consumer_key = options[:consumer_key]
      @consumer_secret = options[:consumer_secret]
      @token = options[:token]
      @secret = options[:secret]
      @proxy = options[:proxy]
    end

    def authorize(token, secret, options = {})
      request_token = OAuth::RequestToken.new(
        consumer, token, secret
      )
      @access_token = request_token.get_access_token(options)
      @token = @access_token.token
      @secret = @access_token.secret
      @access_token
    end

    def show(username)
      get("/users/show/#{username}.json")
    end

    # Returns the string "ok" in the requested format with a 200 OK HTTP status code.
    def test
      get("/help/test.json")
    end

    def request_token(options={})
      consumer.get_request_token(options)
    end

    def authentication_request_token(options={})
      consumer.options[:authorize_path] = '/oauth/authenticate'
      request_token(options)
    end

    #ADDED THE RATE LIMIT STATUS CALL
    def rate_limit_status
      get('/account/rate_limit_status.json')
    end

    #ADDED THE USERS_LOOKUP CALL HERE
    def users_lookup(screennames = [])
      return nil if screennames.length == 0
      names = screennames.join(',')
      get("/users/lookup.json?include_entities=false&screen_name=#{names}")
    end

    private

      def consumer
        @consumer ||= OAuth::Consumer.new(
          @consumer_key,
          @consumer_secret,
          { :site => 'http://api.twitter.com', :request_endpoint => @proxy }
        )
      end

      def access_token
        @access_token ||= OAuth::AccessToken.new(consumer, @token, @secret)
      end

      def get(path, headers={})
        headers.merge!("User-Agent" => "twitter_oauth gem v#{TwitterOAuth::VERSION}")
        oauth_response = access_token.get("/1#{path}", headers)
        JSON.parse(oauth_response.body)
      end

      def post(path, body='', headers={})
        headers.merge!("User-Agent" => "twitter_oauth gem v#{TwitterOAuth::VERSION}")
        oauth_response = access_token.post("/1#{path}", body, headers)
        JSON.parse(oauth_response.body)
      end

      def delete(path, headers={})
        headers.merge!("User-Agent" => "twitter_oauth gem v#{TwitterOAuth::VERSION}")
        oauth_response = access_token.delete("/1#{path}", headers)
        JSON.parse(oauth_response.body)
      end
  end
end

So now, to get the users data, it was simply a matter of passing the usernames to the new Client class as follows:

#this is our new twitter_oauth module with the client class (see above)
require_relative 'twitter_oauth'

class GetTwitterFollowersOauth

  CONSUMER_KEY     = 'YOUR CONSUMER KEY'
  CONSUMER_SECRET  = 'YOUR CONSUMER SECRET KEY'
  OAUTH_TOKEN = 'YOUR OAUTH TOKEN'
  OAUTH_TOKEN_SECRET = 'YOUR OAUTH TOKEN SECRET'

  def GetTwitterFollowersOauth.get_followers(usernames)

    client = TwitterOAuth::Client.new(
            :consumer_key => CONSUMER_KEY,
            :consumer_secret => CONSUMER_SECRET,
            :token => OAUTH_TOKEN,
            :secret => OAUTH_TOKEN_SECRET
    )

    begin
      #usernames is an array of twitter usernames you'd like to get data for
      #per Twitter API, you can get up to 100 usernames of data per call
      users = client.users_lookup(usernames)
    #you will likely get a ParseError at some point with this
    rescue JSON::ParserError
      puts 'Twitter oauth parse error!'
      users = client.users_lookup(usernames)
    #you might also encounter some other errors, like "connection reset by peer"
    rescue Exception => e
      p e
      users = client.users_lookup(usernames)
    end

    #this returns an array of user hashes filled with twitter info, including follower count
    return users
  end

end
Advertisements

2 Responses to “How To Get The Twitter API “GET users / lookup” Call To Work With OAuth In Ruby”

  1. Jack Quigney February 6, 2012 at 5:00 am #

    Why are you supplying your consumer key/secret? I guess I’m confused by how you would construct a twitter client for someone else. Say Jack authenticates using OAuth with your app – you have his OAuth token and secret then.

    How do you construct the twitter client in that instance? Use your consumer key/secret and his OAuth token/secret?

    • Natasha Murashev February 6, 2012 at 9:41 am #

      Hey Jack,

      I actually left out my personal consumer key. It is for you to fill in your own after you make an application via Twitter. @ https://dev.twitter.com/

      CONSUMER_KEY = ‘YOUR CONSUMER KEY’
      CONSUMER_SECRET = ‘YOUR CONSUMER SECRET KEY’
      OAUTH_TOKEN = ‘YOUR OAUTH TOKEN’
      OAUTH_TOKEN_SECRET = ‘YOUR OAUTH TOKEN SECRET’

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s