Instagr.am Picture Previews with Ruby

In my previous post I discusses how to get image previews from TwitPic, yfrog and plixi. Getting preview pictures from instagr.am is slightly harder. It is worth the extra effort however as instagr.am is popular at the moment and the pictures tend to be better than the other services as people take more care with what they post.

Getting the picture preview url

Currently there is no official/supported API for this so I referred to mislav’s unofficial API documentation and ruby library. In order to get the picture preview URL you need an instagr.am page link:
http://instagr.am/p/BT7lU/
. You then make a GET request to the instagr.am API using the page link as a parameter and specifying an additional maxwidth parameter: http://instagr.am/api/v1/oembed/?url=http://instagr.am/p/BT7lU/&maxwidth=150.

This returns the following JSON:

{
	"provider_url": "http://instagr.am/", 
	"title": "Cupcake!", 
	"url": "http://distillery.s3.amazonaws.com/media/2011/01/31/ad710c1abd964cbd8f89e09cc7c76eab_5.jpg",
 	"author_name": "andrewnez", 
	"height": 150, 
	"width": 150, 
	"version": "1.0", 
	"author_url": "http://instagr.am/", 
	"provider_name": "Instagram", 
	"type": "photo"
}

The url field of this JSON document contains a direct link to the image preview:
instagr.am picture preview

You can get a link to a larger image by passing a larger value to the maxwidth parameter such as http://instagr.am/api/v1/oembed/?url=http://instagr.am/p/BT7lU/&maxwidth=650.

Here is the ruby code to do this:

def instagram_image_url(url)
    json = get_url(URI.parse("http://instagr.am/api/v1/oembed/?url=#{url}&maxwidth=200"))
    doc = JSON.parse(json)
    doc["url"]
end

# Plundered from https://github.com/mislav/instagram/blob/master/lib/instagram.rb
def get_url(url)
	response = Net::HTTP.start(url.host, url.port) { |http|
	  http.get url.request_uri, 'User-agent' => 'http://www.whoeveryourare.com'
	}

	if Net::HTTPSuccess === response
	  response.body
	else
	  response.error!
	end
end

Performance Issues when Querying the API

Querying the instagr.am API as you are processing a twitter stream can mean a lot of (probably slow) requests to external servers. If you want your webpage to respond quickly this isn’t ideal. A simple workaround is to use a redirection URL on your site. As you process the twitter stream you extract a unique ID for each picture. The redirection URL then takes that ID, makes the JSON request and redirects the browser to the appropriate picture.

This redirect code is pretty straight-forward, here is a sinatra based example

get "/" do
	instagram_preview_html("http://instagr.am/p/BT7lU/")
end

get "/instagram/:id" do
  redirect instagram_image_url(params[:id]), 301
end

def instagram_preview_html(url)
	id = url.split("/").last
	"<a href=\"#{url}\"><img src=\"/instagram/#{id}\" title=\"#{text}\"/></a>"
end

def instagram_image_url(id)
	url = "http://instagr.am/p/#{id}"
	json = get_url(URI.parse("http://instagr.am/api/v1/oembed/?url=#{url}&maxwidth=200"))
	doc = JSON.parse(json)
	doc["url"]
end

The techniques for other services with Restful APIs, such as Flickr are similar. It would be great if Instagr.am followed the lead of other picture services and made their pictures directly addressable and hackable based on their URLs without having to use the JSON API. Hopefully as their web presence grow they will do so.

Advertisements

One thought on “Instagr.am Picture Previews with Ruby

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