How to shorten urls with bit.ly in Ruby on Rails.

First, let’s make a simple retweet link for our application. To keep our views a little cleaner, we’ll make a helper method in app/helpers/application_helper.rb:

        def twitter_url(resource, tweet_text="Check out this article from my-site.com:")
          tweet_url = root_url.chop + url_for(resource)
          "http://twitter.com/home?status=#{tweet_text} #{tweet_url}"
        end
    

This method just builds a url to twitter and supplies some default text which you may optionally override by passing a second argument. Call it in your view like this:

        <%= link_to "Retweet this post!", twitter_url(@post) %>
    

Now, this method works but it would be much better if we could use shortened urls. So let’s change things a bit in order to use bit.ly — twitter’s preferred url shortening service. Before we write any code…

  1. You’ll need to sign up for bit.ly.
  2. And grap your api key.

With that info on hand, we’re ready to interface with the bit.ly api. Let’s make another helper method also located in app/helpers/application_helper.rb:

        def shorten_with_bitly(url)
          # build url to bitly api
          user = "insert-your-username"
          apikey = "insert-your-api-key"
          version = "2.0.1"
          bitly_url = "http://api.bit.ly/shorten?version=#{version}&longUrl=#{url}&login=#{user}&apiKey=#{apikey}"

          # parse result and return shortened url
          buffer = open(bitly_url, "UserAgent" => "Ruby-ExpandLink").read
          result = JSON.parse(buffer)
          short_url = result['results'][url]['shortUrl']
        end
    

This method uses your credentials to build a url to interface with the bit.ly api. Bitly receives our request and returns a JSON object containing a shortened url. We’ll parse this object, grab the shortened url, and return it.

Finally, we need to change our initial twitter_url method to include url shortening:

        def twitter_url(resource, tweet_text="Check out this article from my-site.com:")
          tweet_url = root_url.chop + url_for(resource)
          tweet_url = shorten_with_bitly(tweet_url) if Rails.env.production?

          "http://twitter.com/home?status=#{tweet_text} #{tweet_url}"
        end
    

This is identical to our original method except we’ve added a new line which calls shorten_with_bitly. This line overwrites the tweet_url variable — replacing the long url with a shortened version. Finally, we’ll include a condition to ensure this only happens in production. This saves us from creating a bunch of useless bit.ly links that point to localhost urls.

Some final points.

  • The shorten_with_bitly method borrows heavily form a ruby snippet posted by Puneet Pandey. Pandey definitely deserves some credit here.
  • If you’re looking for a more robust way to interface with the bit.ly api, checkout this url shortening gem by Nasir Jamal. I’ve never used it but appears to be fully featured and well documented.

Tags: , ,

2 Comments

Your thoughts?

Preview