Twitter API - Working with profile images

Tuesday, May 13, 2008

Twitter provides a fantastic API which has allowed many developers (Inkitecture included) to create flexible apps and bots leveraging their framework. That being said, limitations do exist with their API.

The Problem: Finding Twitter Profile Images

One of these limitations is with how Twitter handles profile images. Twitter uses Amazon's S3 storage service as a medium for storing images. This results in image URL's that look like this:
http://s3.amazonaws.com/twitter_production/profile_images/54032789/Picture_3_bigger.png
                                                          ^^^Problem here  ^^^And here

For the developer, this means there is no easy way to guess a user's profile image URL. This information can be easily obtained through a RSS API call, but Twitter now limits these to 50/hour which effectively prohibits any Twitter-based application with a large user base.


The Work-Around: Leverage the User's Twitter Account

Using the user's Twitter account to grab profile images is a security concern because you don't want to be storing user account details with any session exposure or in any persistent manner.

The workaround in ruby is to grab the profile images right after authenticating the user. This eliminates the need for caching the user client or password in session and dumps it from memory quickly. API calls can be further reduced by storing profile image URLS in a DB table, updating them only every week or so.

Here's the code. This happens right after authentication, and then the twitter_user_client is promptly dumped, just like my 10th grade prom date:

def self.update_debtor_images(twitter_username, twitter_user_client)

your_debtor_balances = Balance.find_all_by_you(twitter_username)

debtors_with_images = User.find_all_tweeters_in_balances(your_debtor_balances)

#add session user to the array (update your image)
u = User.find_by_name(twitter_username)
debtors_with_images << style="color: rgb(51, 102, 255);">#image replacement criteria: older than 1 week OR doesn't exist
a_week_ago = Time.now - 60*60*24*7 #seconds * minutes * hours * days

#okay, now go through the list of users and update if needed
debtors_with_images.each do |debtor|
#if they don't have a populated image, or the image url is a week old...
if (!debtor.image_url || debtor.updated_at < style="color: rgb(51, 102, 255);">#get image location from twitter
begin
debtor.image_url = twitter_user_client.user(debtor.name.gsub(/@/, ""), :info).profile_image_url
debtor.save!
rescue Exception => e
end

end
end

end

Questions are always welcome :D

Posted by Drew McKinney at 9:53 AM  

0 comments:

Post a Comment