Kerry Buckley

What’s the simplest thing that could possibly go wrong?

API vs RSI

one comment

World’s-most-famous-twitterer Stephen Fry has a system for handling follow requests: you tweet using the #followmestephen hashtag, and he wades diligently through them, manually following people.

This seems an odd sort of thing to do – most people choose whom to follow based on whether they know them or like what they say, rather than on request – but I suppose when you have over a quarter of a million followers things work a little differently. It also creates lots of work , and looks like an ideal candidate for automation.

I thought I’d have a quick play with the Twitter API this morning (no doubt I’m not the only one), and cobbled together the script below, which you can also download as follow_me_stephen.rb (although if you’re not Mr Fry I’m not sure why you would want to). Save the file, and run using ruby follow_me_stephen.rb.

I wanted to avoid having too many dependencies, so I didn’t use the twitter gem, or the excellent httparty, but I was too lazy to figure out all the XPaths to handle the Atom version of the API. This means you need to have the JSON gem installed, which is as simple as sudo gem install json (omit the sudo on Windows).

The script’s pretty dumb, in that it grabs the whole set of search results every time, and blindly requests to follow everyone, regardless of whether you’re already following them.

#!/usr/bin/env ruby

require 'net/http'

begin
  require 'json'
rescue LoadError
  STDERR.puts <<EOF
 
 No JSON parser found. Please run the following command to install:
 
   sudo gem install json
 
 EOF
   raise
 end
 
 module FollowMeStephen
   def run
     auth_user, password = get_user_details
     requestors = fetch_requestors
     requestors.each do |user|
       follow user, auth_user, password
     end
   end
   
   private
   
   def get_user_details
     print 'Please enter your Twitter username: '
     auth_user = gets.chomp
     print 'Please enter your Twitter password: '
     password = gets.chomp
     return auth_user, password
   end
   
   def fetch_requestors
     requestors = []
     puts 'Searching for hashtag "followmestephen"...'
     query = '?q=%23followmestephen&rpp=150'
     while query do
       search = JSON.parse(get("/search.json#{query}"))
       puts "Received page #{search['page']}"
       requestors += search['results'].map {|r| r['from_user']}
       query = search['next_page']
     end
     requestors.uniq
   end
   
   def follow user, auth_user, password
     print "Following #{user}... "
     result = post "/friendships/create/#{user}.json", auth_user, password
     puts result
   end
   
   def get path
     Net::HTTP.get 'search.twitter.com', path
   end
   
   def post path, auth_user, password
     request = Net::HTTP::Post.new path
     request.basic_auth auth_user, password
     response = Net::HTTP.new('twitter.com').start {|http| http.request(request)}
     (response.kind_of? Net::HTTPSuccess) ? 'OK' : 'Failed'
   end
 end
 
 include FollowMeStephen
 run
 

Written by Kerry

March 15th, 2009 at 12:16 pm

Posted in Ruby

Tagged with , , ,

One Response to 'API vs RSI'

Subscribe to comments with RSS or TrackBack to 'API vs RSI'.

  1. Hello; I saw your comment on my blog and I couldn’t find an email for you. Here’s my reply:

    Uncle Bob’s rules are for Developers; I’m speaking of acceptance testing here.

    Having worked with UncleBob a little bit on his “Clean Code” book, I’m confident he doesn’t believe in BTUF.

    Matthew Heusser

    26 Mar 09 at 1:27 pm

Leave a Reply

You must be logged in to post a comment.