Login


Programmatically Creating a Tiny URL from bit.ly

By Jonathan Wood on 3/4/2011
Language: C#
Technology: .NET
Platform: Windows
License: CPOL
Views: 1,310,637
Web Development » Web Services and APIs » General » Programmatically Creating a Tiny URL from bit.ly

Demo Program Screenshot

Download Source Code Download Source Code

Introduction

URL-shortening sites are very common these days. These sites take a regular URL and produce a smaller URL. The smaller URL, or tiny URL, points to the site that generated it. When this URL is requested, the site then uses information embedded in the tiny URL to look up the original URL, and then redirects to that original URL.

Tiny URLs have been made popular by sites like Twitter, which limit the number of characters that can appear in a message. One of the more common URL-shortening sites is bit.ly, which was used by Twitter before they created their own URL-shortening site, t.co.

The TinyUrl Class

Listing 1 shows my TinyUrl class. This class allows an application to programmatically take a regular URL and produce a tiny URL. The tiny URL is obtained by querying the bit.ly application programming interface (API).

The TinyUrl class contains a single public method, GetTinyUrl(), which is static and returns the tiny version of the specified URL.

Note that this code will not work as-is. bit.ly requires a login key in order to generate the tiny URL. To get this code to work, you'll need to go to bit.ly and register for your own login information. Plug that login information into the private _apiLogin and _apiKey constants, and you should be ready to go.

GetTinyUrl() starts by constructing a request that includes the login information and original URL. To keep the integrity of this request URL, the URL being shortened is URL-encoded using the UrlEncode() method. Note that .NET provides it's own UrlEncode() method; however, it is not normally referenced from a WinForms application. If your application is a web application and/or you are referencing the required libraries, you can eliminate the UrlEncode() and IsSafeUrlCharacter() methods and use the UrlEncode() method that is part of the .NET Framework. The GetTinyUrl() then loads the response into an XmlDocument instance.

Next, it calls the helper method ReadValue() to read the status_code and status_text values from the returned XML data. status_code contains the status of the request. If the status is "200", the request was successful and state_text contains the tiny URL.

Listing 1: The TinyUrl Class

public class TinyUrl
{
    // bit.ly API Key
    // TODO: Go to http://bit.ly/ to get your API login and key
    private const string _apiLogin = "******";
    private const string _apiKey = "******";

    /// <summary>
    /// Returns a tiny bit.ly tiny URL for the given URL.
    /// </summary>
    /// <param name="url">The URL to be shortened</param>
    /// <returns>The tiny URL</returns>
    public static string GetTinyUrl(string url)
    {
        // Request tiny URL via bit.ly API
        XmlDocument doc = new XmlDocument();
        doc.Load(String.Format("http://api.bit.ly/v3/shorten?login={0}&apiKey={1}&longUrl={2}&format=xml",
            _apiLogin, _apiKey, UrlEncode(url)));

        // Test for error response
        string status_code = ReadValue(doc, "/response/status_code");
        string status_txt = ReadValue(doc, "/response/status_txt");
        if (status_code != "200" || status_txt != "OK")
            throw new Exception(String.Format("bit.ly response indicates error ({0} {1})",
                status_code, status_txt));

        // Return tiny URL
        return ReadValue(doc, "/response/data/url");
    }

    protected static string ReadValue(XmlDocument doc, string xpath)
    {
        XmlNode node = doc.SelectSingleNode(xpath);
        if (node == null)
            throw new Exception(String.Format("bit.ly response missing expected path (\"{0}\")", xpath));
        return node.InnerText.Trim();
    }

    protected static string UrlEncode(string s)
    {
        StringBuilder builder = new StringBuilder();
        foreach (char c in s)
        {
            if (IsSafeUrlCharacter(c))
                builder.Append(c);
            else if (c == ' ')
                builder.Append('+');
            else
                builder.AppendFormat("%{0:X2}", (int)c);
        }
        return builder.ToString();
    }

    protected static bool IsSafeUrlCharacter(char c)
    {
        if ((c >= 'a' && c <= 'z') ||
            (c >= 'A' && c <= 'Z') ||
            (c >= '0' && c <= '9'))
            return true;

        if (c == '(' ||
            c == ')' ||
            c == '*' ||
            c == '-' ||
            c == '.' ||
            c == '_' ||
            c == '!')
            return true;

        return false;
    }
}

Note that when you successfully call GetTinyUrl(), the bit.ly website searches to see if there is already an entry for that URL and, if so, returns the existing tiny URL. Otherwise, it creates a new entry and returns a tiny URL that references that new entry.

In case it isn't obvious, there is no way to generate the tiny URL without calling into the bit.ly (or similar) website. Or, at least, if you did generate the tiny URL on your own, it wouldn't work. There must be a corresponding entry on the site that the tiny URL refers to.

Conclusion

I originally used this code to automatically create Twitter tweets that contained URLs. Unfortunately, that code will need to be rewritten as Twitter's old interface has been replaced with a more flexible and secure one, that is also far more complex to write to.

However, the tiny URL part of the code still works fine and I can think of other possible uses for this code. Perhaps you can too.

End-User License

Use of this article and any related source code or other files is governed by the terms and conditions of The Code Project Open License.

Author Information

Jonathan Wood

I'm a software/website developer working out of the greater Salt Lake City area in Utah. I've developed many websites including Black Belt Coder, Insider Articles, and others.