February 25th, 2009
I wanted a reliable way to find out a few things about my twitter account (for example which of the users I am following are not following me back) - unfortunately the third party apps out there are not always very reliable, do not exactly do what I want/as I want so I decided to check out how easy it is to hack up a more advanced query using a Ruby twitter API wrapper. It turned out that it couldn’t be easier!
There are several gems wrapping the Twitter API out there - I started to use the ‘twitter’ gem from John Nunemaker and I am perfectly happy with it so far. John did a great job supporting all the features offered by the API - it’s a different question that the API, like twitter itself, is quite minimalistic. For example I have not found a way to get all my followers/friends easily (drop me a comment if I am missing something) so I monkey-patched this into the module in a generic way:
- module Twitter
- class Base
- def all_entries(method, options = {})
- all_entries = []
- next_100 = self.send method, {:page => (current_page = 1)}.merge(options)
- while (next_100.size != 0) do
- all_entries << next_100
- next_100 = self.send method, {:page => (current_page += 1)}.merge(options)
- end
- all_entries.flatten
- end
- end
- end
for example you can call connection.all_entries(:friends) to get all of your friends, given that you set up a connection to your account (I found only a method which returns your first 100 friends - didn’t spend too much time with the documentation though - agin, drop me a message if I overlooked something).
I have added a bit of syntactic sugar to be able to call connection.all_friends instead of connection.all_entries(:friends):
- module Twitter
- class Base
- alias_method :throw_method_missing, :method_missing
- def method_missing(method_name, *args, &bloke)
- if (method_name.to_s =~ /^all_.+/)
- all_entries(method_name.to_s[/all_(.+)/,1], args[0] || {})
- else
- throw_method_missing(method_name, *args, &bloke)
- end
- end
- end
- end
Here we ensure that only method calls that start with all_ are handled by all_entries, the rest is throwing a method_missing since we are not interested in handling those messages.
Now it could not be easier to implement the function I originally intended to build: list of users who are not following back.
- class Array
- def names
- self.map{|u| u.screen_name}
- end
- end
- module Twitter
- class Base
- def not_following_back
- all_friends.names - all_followers.names
- end
- end
- end
That’s all there’s to it (I am not a big fan of monkey patching core classes btw ; but in this case, adding the names() method to the Array class just made the method I intended to originally implement much cleaner so I rolled with it). Note that since subtraction is a non-commutative operation, all_friends.names - all_followers.names is not necessarily the same as allfollowers.names - allfriends.names. This is how the final code looks like:
- require ‘rubygems’
- require ‘twitter’
- connection = Twitter::Base.new(‘yourname’, ‘yourpass’)
- class Array
- def names
- self.map{|u| u.screen_name}
- end
- end
- module Twitter
- class Base
- alias_method :throw_method_missing, :method_missing
- def method_missing(method_name, *args, &bloke)
- if (method_name.to_s =~ /^all_.+/)
- all_entries(method_name.to_s[/all_(.+)/,1], args[0] || {})
- else
- throw_method_missing(method_name, *args, &bloke)
- end
- end
- def all_entries(method, options = {})
- all_entries = []
- next_100 = self.send method, {:page => (current_page = 1)}.merge(options)
- while (next_100.size != 0) do
- all_entries << next_100
- next_100 = self.send method, {:page => (current_page += 1)}.merge(options)
- end
- all_entries.flatten
- end
- def not_following_back
- all_friends.names - all_followers.names
- end
- end
- end
- p connection.not_following_back
You can download/check out the code here - do not try to copy & paste it from the text as it will be b0rk3d.
In part 2 I’d like to set up a small Sinatra app showing the above users in a list - displaying their avatar, screen name and real name, plus a link to remove them if you decide so.

February 25th, 2009 at 8:14 pm
Nice patch. There is a relatively new API (/friends/ids/user.fmt) that lets you get all of your friends or followers in a single call but it only gives you the numeric ids so you still have to make additional calls to get any useful information. But you can use it to diff the list to narrow down what you have to get from the other calls.
Check out http://tweepdiff.com. It’s basically the same concept in a Sinatra app. I’m not using the gem mainly because I’m using Curl::Multi and memcache to try to speed things up, but I may use it for future functionality.
Brian
February 26th, 2009 at 1:18 am
Thanks for the heads up Brian
Seems I had to write this post to find out these possibilities.
Of course the other goal was to show how to extend the gem with functionality that is not there.
February 26th, 2009 at 1:58 am
Have you tried Twitter4r? http://twitter4r.rubyforge.org/
February 26th, 2009 at 3:25 pm
I’m pretty sure the code you’re looking for is friendids and followerids. You can get back the ids of all of your friends and followers in one query. You can do the same kind of array manipulation and then query again only on the ids you’re interested in. http://gist.github.com/71165
March 6th, 2009 at 8:54 pm
Actually all of this is part of the new Twitter API and the gem but you need to get it from github. Much cleaner and straightforward.
http://github.com/jnunemaker/twitter/blob/f2260a9857e8a45db01a4b18d34f6c4c4b2e4b8a/lib/twitter/base.rb
March 9th, 2009 at 12:21 pm
Now this is very interesting, impressive and never thought of. In simple words well done for providing creative information.
May 1st, 2009 at 10:05 am
So Twitter is awesome for Taking traffic to you website . It is very
simple to setup and its a fun positive way to keep in contact with
people. To get more followers on twitter check out this amazing
tool.
Twitter
Traffic Machine
November 24th, 2009 at 5:11 am
i love to Twitter my day to day activities to my friends and followers. Twitter is much better than blogging because it is direct to the point and does not require you to type so many unnecessary words.
1a
December 6th, 2009 at 10:00 am