At the Forge - Social Google Gadgets

How do we turn a Google Gadget into an OpenSocial application? An initial look at the OpenSocial API—what it includes, as well as what it doesn't.
Who Are Your Friends?

Perhaps the simplest type of application we can write with OpenSocial is one that shows the current user's friends. Better yet, because friends on a social-networking site typically upload their pictures, we even can display a list of the viewer's friends.

Last month, we saw how we can modify the HTML in which a Google Gadget—or an OpenSocial application—is running. Create an empty div, build up the HTML in a variable, and then set the div's innerHTML property to be that of the variable. For example:

html = "<p>Hello</p>";
div.innerHTML = html;

In order to display a list of the viewer's friends, we need to retrieve a list of those friends. We then can iterate over those friends, putting their thumbnail image URL in our html variable.

In order to retrieve a list of friends, we must do the following:

viewer_friends = opensocial.DataRequest.Group.VIEWER_FRIENDS;
req.add(req.newFetchPeopleRequest(viewer_friends, opt_params),

The above request contains a single query, which we call viewer_friends. (Don't be confused by the viewer_friends variable, which was introduced simply to make the lines easier to understand.)

When the method has finished executing asynchronously, it invokes our response function. We can define it like any other JavaScript function, and Google's documentation even indicates that you can use JavaScript libraries, such as Prototype or Dojo, inside an OpenSocial application.

Google already has included a number of useful JavaScript functions as part of its implementation of gadgets, meaning that a Ruby-like each method is available to us. That method, which typically is invoked on an array, takes a function as a parameter. The function is executed once for each element of the array, with each array element being passed to the function in turn. Thus, we can write our response method as follows:

function response(data) {
    var viewer_friends = data.get("viewer_friends").getData();
    viewer_friends.each(function(person) {
        var thumb =
        html += '<img src="' + thumb + '"/>';

    document.getElementById('main').innerHTML = html;

Our response method is invoked only after the request has been sent. Its data parameter is populated with the response to our query, which we can retrieve with its name (viewer_friends). We then use the getData() method on the resulting object to give us the data that interests us, namely an array of person objects.

Each person in OpenSocial has a few required properties, among them the URL of their personal thumbnail picture. You can see from the above example that we retrieve it by invoking the getField() method on a person, indicating which field we want by using a value provided by the OpenSocial framework. We can use several such values, including ID (for their unique ID), NAME (for their name) and even PROFILE_URL (for the person's home page URL on the system). Beyond those basic fields, a well-behaved OpenSocial application must query its container to make sure that it's available.

Does OpenSocial Work?

One of the biggest problems with OpenSocial is its inherent diversity and cross-platform functionality. Programmers who create desktop applications have discovered—often the hard way—that different operating systems have different conventions for how dialog boxes, or even menus, look and feel. These often-subtle design distinctions can play a major role in the usability of an application.

Thus, it'll be interesting to see what happens when OpenSocial applications are unveiled and are supposed to work cleanly on all systems. One of the Facebook platform's great advantages is the fact that it shoehorns application content into a standard look and feel. This is missing with OpenSocial, and although it encourages diversity, I'm far from convinced this will be good for end users.

Another, and more serious, issue with OpenSocial is that it is designed to let applications run in different contexts, not seamlessly join data from diverse social-networking systems. Yes, it's nice that software developers will be able to release their code on multiple platforms at the same time. But as a user as well as a developer, I'm interested in getting a comprehensive list of all my friends/contacts/links from all the social networks to which I belong.

Just a few weeks before I wrote these words, well-known blogger Robert Scoble was kicked off Facebook for downloading his contact list into another program. (His account was reinstated within a few days.) The notion that data should stay locked within one of these systems, rather than be freely downloadable and transferable by the people who entered and approved it, is disappointing.

If I create a forum application using OpenSocial, and I use the persistence API in order to store messages, it might work just fine. But, what if I want the forum to work across different networks, such that forum postings are persistent not only across users, but also across the different OpenSocial containers? That appears to be completely unsupported by the standard. And although such capabilities would seem to be against the interests of the various social-networking companies, it is most certainly in the interest of the individual users.

Of course, given that OpenSocial is nothing more than a specification and set of JavaScript libraries, there's still hope. Perhaps someone will create a JavaScript library that allows OpenSocial client applications to store and retrieve state on a remote server (that is, not on the OpenSocial container's server) in a format that can be unpacked and used across systems easily. Such a library might be difficult to create, particularly given the various user-visibility and privacy issues. But, it would be an additional step toward not just code portability, but data portability, that many people would like to see in OpenSocial.

I should note that I'm not the first or only person to raise some of these concerns. Tim O'Reilly, among others, has expressed his disappointment with the initial versions of OpenSocial (see Resources).