Using the Gravatar API: Announcing Your Presence

Grava What?

Gravatar is a social presence site that specializes in storing a profile and associated avatar for you. Unlike sites such as Facebook, Linked-In, and others, Gravatar doesn’t promote sharing of things. It has one simple goal, and that’s to store avatars and profile information in a central place for you use in other applications or Web sites.

Discus, for example, can be set up to use your Gravatar picture, so that when you make a post using any Web site that uses Discus for its comments, your photo and user name are automatically filled in, even if your not actually a member of that site.

Before you can start to write code that uses Gravatar you’ll need a wordpress.com blogging account. If you already have one, just click the WordPress sign-in button at http://en.gravatar.com/.

Grav1
Figure 1: Gravatar’s main page

If you don’t have a WordPress account, still click the sign-in button, but when you get to the page to enter your sign-in details, look just below the form and you’ll see a link to “Create an Account.”

To just use Gravatar in an external application, you don’t actually need a Gravatar account. All you need is the email address registered with Gravatar of the person who’s account you wish to display. For this post, however, I’m going to demonstrate using the service by using my own account, and I’ll assume you also have an account you can use to program against.

Let’s Create Some Code

For this post, I’m going to use a standard WebForms ASP.NET application to demonstrate using Gravatar. I’m using WebForms purely for simplicity; for whichever platform you use, the process is the same.

Fire up Visual Studio, and start a “Web application.”

Grav2
Figure 2: An empty Web application using WebForms

Add a “Web Form” called ‘Index’ to your project. Your Solution Explorer should look something like what’s shown in Figure 3.

Grav3
Figure 3: Solution Explorer for our Gravatar Project

Make sure that your ASPX code for the page looks as follows:

<%@ Page Language="C#" AutoEventWireup="true"
         CodeBehind="Index.aspx.cs"
         Inherits="GravatarTest.Index" %>

<!DOCTYPE html>

<html >
<head runat="server">
   <title>Gravatar Test Page</title>
</head>
<body>
   <form id="form1" runat="server">
   <div>
      <asp:button runat="server" id="btnGetGravatar"
                  text="Get Gravatar"/>
      <asp:image runat="server" id="gravatarImage"
                 width="200" height="200"/>
   </div>
   </form>
</body>
</html>

If you’ve called your page by a different name, remember to NOT change the first line, and only replace everything from the ‘DOCTYPE’ onwards.

If you switch to design view for your page, you should see something similar to the following:

Grav4
Figure 4: Our page in design mode

To get an avatar image from Gravatar for any given email address, you have to perform the following steps:

  1. Convert the email address to all lower case.
  2. Trim off any leading or trailing whitespace.
  3. Calculate an MD5 hash of the email address.
  4. Make a HTTP get request to Gravatar with the calculated hash (or use the hash to create a string for an image tag).

Double-click the button in design view, and then add the following code to the button click handler in your page behind code.

protected void btnGetGravatar_Click(object sender, EventArgs e)
{
   string gravatarEmail = "shawty_ds@yahoo.com";

   gravatarEmail = gravatarEmail.ToLower().Trim();

   string hash = GetMD5Hash(gravatarEmail);

   gravatarImage.ImageUrl =
      String.Format("http://www.gravatar.com/avatar/{0}?s=200", hash);
}

You’ll also need the “GetMD5Hash” function and various using statements. Your entire code behind should look something similar to the following:

using System;
using System.Security.Cryptography;
using System.Text;

namespace GravatarTest
{
   public partial class Index : System.Web.UI.Page
   {
      protected void Page_Load(object sender, EventArgs e)
      {

      }

      protected void btnGetGravatar_Click(object sender, EventArgs e)
      {
         string gravatarEmail = "shawty_ds@yahoo.com";

         gravatarEmail = gravatarEmail.ToLower().Trim();

         string hash = GetMD5Hash(gravatarEmail);

         gravatarImage.ImageUrl =
            String.Format("http://www.gravatar.com/avatar/{0}?s=200", hash);
      }

      private string GetMD5Hash(string input)
      {
         MD5CryptoServiceProvider mD5CryptoServiceProvider =
            new MD5CryptoServiceProvider();
         byte[] bytes = Encoding.UTF8.GetBytes(input);
         bytes = mD5CryptoServiceProvider.ComputeHash(bytes);
         StringBuilder stringBuilder = new StringBuilder();
         byte[] numArray = bytes;
         for (int i = 0; i < (int)numArray.Length; i++)
         {
            byte num = numArray[i];
            stringBuilder.Append(num.ToString("x2").ToLower());
         }
         return stringBuilder.ToString();
      }

   }
}

Change the “gravatarEmail” string to whatever the email of your Gravatar account is and, all being well, if you press F5 to run the Web page, then click the button; you should see your Gravatar profile picture appear.

Grav5
Figure 5: My browser showing my Gravatar Avatar

The URL to construct to retrieve your avatar image couldn’t be simpler. It’s “http://www.gravatar.com/avatar/” followed by the MD5 hash calculated, as described above.

You don’t need to authenticate, have an API token, or any complicated OAuth schemes. You simply make a regular GET call to the URL and get an image as a response.

If you need to make a secure call from an HTTPS page, you simply just change “www.gravatar.com” to “secure.gravatar.com” and use HTTPS as the scheme.

Following the hash, there are a couple of useful parameters you can add. ‘S’, or ‘size’, allows you to set the pixel size of the returned image. I’ve used it in the code above so the image size matches the size of the ASP.NET image container I created. You can have a maximum size of 2048.

The ‘d’ parameter lets you set a default behaviour if an avatar hash is not found. If you make ‘d=404’, Gravatar will return a 404 error if an image doesn’t exist.

If you set ‘d=<alternate image url>’, the specified image will be used. You can also use the following:

  • d=mm: Mystery Man
  • d=identicon: Geometric pattern calculated from the provided hash
  • d=monsterid: Mini monster picture based on the provided hash
  • d=wavatar: Image similar to a mini monster, but all cool and new wave
  • d=retro: An ‘OlkSkool’ 8 bit graphic representation of the provided hash
  • d=blank: A simple blank image

Providing the d parameter will automatically substitute the image as required if no hash can be looked up. So, even if the email you work with is not registered, it’s still possible to get some kind of image.

Getting Profile Information

Gravatar can handle more than just an avatar image. If you’ve filled in the various bits that you can change on your Gravatar account, you also can make a call to “http://www.gravatar.com/”, followed by the hash calculated for your email. You’ll get a mini profile page; for example, mine’s at http://www.gravatar.com/10fdb34b4e4b80878ed512813e495bfd.

Grav6
Figure 6: My Gravatar mini profile

Although this might be great if you just want to display a simple popup/iframe that’s already populated, you can simply, just by adding ‘.json’ to the end of the request, get all the information on that page returned as a JSON object.

Grav7
Figure 7: My Gravatar profile returned as JSON

Representing the different objects returned by Gravatar is not particularly difficult. The main ‘entry’, for example, can be represented as follows:

using System.Collections.Generic;

namespace GravatarTest
{
   public class GravatarEntry
   {
      public int Id { get; set; }
      public string Hash { get; set; }
      public string RequestHash { get; set; }
      public string ProfileUrl { get; set; }
      public string PreferredUsername { get; set; }
      public string ThumbnailUrl { get; set; }
      public List<PhotoEntry> Photos { get; set; }
      public NameEntry Name { get; set; }
      public string DisplayName { get; set; }
      public string AboutMe { get; set; }
      public string CurrentLocation { get; set; }
      public List<EmailEntry> Emails { get; set; }
      public List<ImEntry> Ims { get; set; }
      public List<AccountEntry> Accounts { get; set; }
      public List<UrlEntry> Urls { get; set; }

   }
}

The various sub objects are all just as simple.

PhotoEntry.cs

namespace GravatarTest
{
   public class PhotoEntry
   {
      public string Value { get; set; }
      public string Type { get; set; }
   }
}

NameEntry.cs

namespace GravatarTest
{
   public class NameEntry
   {
      public string GivenName { get; set; }
      public string FamilyName { get; set; }
      public string Formatted { get; set; }
   }
}

EmailEntry.cs

namespace GravatarTest
{
   public class EmailEntry
   {
      public bool Primary { get; set; }
      public string Value { get; set; }
   }
}

ImEntry.cs

namespace GravatarTest
{
   public class ImEntry
   {
      public string Type { get; set; }
      public string Value { get; set; }
   }
}

AccountEntry.cs

namespace GravatarTest
{
   public class AccountEntry
   {
      public string Domain { get; set; }
      public string Display { get; set; }
      public string Url { get; set; }
      public string Userid { get; set; }
      public string Username { get; set; }
      public bool Verified { get; set; }
      public string Shortname { get; set; }
   }
}

UrlEntry.cs

namespace GravatarTest
{
   public class UrlEntry
   {
      public string Value { get; set; }
      public string Title { get; set; }
   }
}

Once you have all the various structures needed, you simply can just use the HTTP web client to grab the JSON from Gravatar, then parse it into your classes using JSON.NET. For example, add the following method to your code behind.

public static string GetData(string url)
{
   string resultContent;

   using (var client = new HttpClient())
   {
      client.BaseAddress = new Uri(url);
      client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent",
         quot;Mozilla/5.0 (Windows NT 6.2; WOW64; rv:19.0)
         Gecko/20100101 Firefox/19.0");
      var result = client.GetAsync(url).Result;
      resultContent = result.Content.ReadAsStringAsync().Result;

      var code = result.StatusCode;

      switch (code)
      {
         case HttpStatusCode.InternalServerError:
            throw new ApplicationException("Server 500 Error
               while posting to: " + url);

         case HttpStatusCode.NotFound:
            throw new ApplicationException("Server 404 Error " +
               url + " was not a valid resource");
      }
   }

   return resultContent;
}

And use NuGet to add Json.Net to your project. Before you can parse the entry returned, you need to make one more class, called GravatarProfiles.cs. The reason for this is because the Gravatar API, even though it’s returning only one object, it returns it as an array of GravatarEntries. To allow Json.Net to parse the object correctly, we have to make sure that we are able to structure things so that Json.Net can work with it.

GravatarProfiles.cs should look something like the following:

using System.Collections.Generic;

namespace GravatarTest
{
   public class GravatarProfiles
   {
      public List<GravatarEntry> Entry { get; set; }
   }
}

Once that’s in place, it’s as simple as this:

string gravatarProfileJson =
   GetData(String.Format("http://en.gravatar.com/{0}.json", hash))
GravatarProfiles gravatarProfiles =
   JsonConvert.DeserializeObject<GravatarProfiles>(gravatarProfileJson);

to get the Gravatar Profile into your code.

Grav8
Figure 8: Visual Studio Debugger showing our profile in .NET objects

From this point on, you can extract the details and add them to labels, data repeaters, or anything else you want to use to display them.

Found a strange API you’ve never seen in .NET before, or want to know if there’s a .NET way of doing something? Drop me a comment in the Comments section below and I’ll try to cover it in a future post.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read