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.

The past year has seen an explosion in the growth of social-networking sites like Facebook. People have jumped at the opportunity to find existing friends, make new ones and spend time communicating and participating in group activities on-line. Facebook might be the best-known site, but LinkedIn, Ning, Hi5, Orkut and others also have become popular.

As we might expect in a competitive marketplace, each of these sites has tried to offer unique features to encourage new people to sign up. During the summer of 2007, Facebook unveiled one of the most interesting and powerful of these features in its developer platform—basically, a way to integrate third-party Web applications into Facebook.

This API has led to a torrent of applications being developed for Facebook. It's not clear whether anyone is making money off these applications or whether there are any that people find truly useful (rather than frivolous). But, there are plenty of indications that Facebook's API is an important milestone for social-networking applications and for Web applications in general. For the first time, we have a Web site that is providing an open platform for application development.

In response to the popularity of Facebook's developer API, a number of competitors announced they would be supporting a similar API, known as OpenSocial. Applications written for OpenSocial should work equally well on all compliant social networks. Thus, instead of writing one application for MySpace and another for Ning, you can write the application once and deploy it on many different networks. The exception, at least for now, is Facebook; whether Facebook decides to join the OpenSocial consortium or provide a compatibility layer remains to be seen.

The OpenSocial specification was spearheaded by Google and is based on the specification known as Google Gadgets, part of the personalized iGoogle page for some time. Last month, we looked at how to build a simple Google Gadget, which packages HTML and JavaScript into an XML wrapper.

This month, we look at how to take our simple Google Gadget and turn it into an OpenSocial-compliant application. We begin to see the pros and cons of the OpenSocial standard and consider ways to make use of its capabilities.

Making the Gadget Social

As we saw last month, the simplest possible “Hello, world” Google Gadget looks like the following:

<?xml version="1.0" encoding="UTF-8" ?>
  <ModulePrefs title="Hello world" />
  <Content type="html">
       Hello, world!


The gadget comes as an XML file, with a Module section and a Content section. The Module section allows us to specify gadget-specific preferences, using the ModulePrefs tag. The Content section, as you might expect, contains the HTML and JavaScript that will be displayed and executed for the user.

We can turn a simple gadget into an OpenSocial gadget by adding a new Require tag within our Module tag:

<?xml version="1.0" encoding="UTF-8" ?>
    <ModulePrefs title="Hello world" />
    <Require feature="opensocial-0.6" />
    <Content type="html">
         Hello, world!

The Require tag indicates that our gadget is implementing the OpenSocial standard, version 0.6. (A new version undoubtedly will be released by the time this column is printed. The initial version, 0.5, was superseded by 0.6 in late December 2007.) Other than that single line, this is the same “Hello, world” widget we installed on our iGoogle page last month. In theory, we can go ahead and install this application on the social-networking site (OpenSocial container) of our choice, and it'll work just fine.

Adding Social Functionality

“Hello, world” is boring enough as a standalone program; using it as an example of a social-networking API seems almost silly. For a gadget to become a fully fledged OpenSocial application, it needs to demonstrate an ability to interact with other people. More precisely, a socially aware application should be able to find out something about me and my friends, as well as what I (and my friends) do.

The OpenSocial API addresses this by offering three types of functionality:

  • People and relationships: get information about you, your friends and the various pieces of data associated with those friends. The Person class provides access to this information.

  • Activities: social-networking sites are interesting because they let you interact with your friends in a variety of activities. These activities can range from exchanging messages to answering questions in an on-line poll to keeping up to date on the latest sports scores. OpenSocial sees an activity as a collection of actions within a particular container. The Activity class provides access to this data.

  • Persistence: OpenSocial makes it possible for an application to store information between sessions. One of the most interesting aspects of this persistence API is the fact that storage is handled by the OpenSocial container, not by the application. There is no Persistence class for handling such data. Rather, the data is read and written by invoking methods on the overall opensocial object. Note that the persistence layer lets applications store data globally, as well as on a per-user or per-application instance basis, as needed.

Interactions with these three objects, as well as with the OpenSocial API in general, is done via method calls on the opensocial object. Typically, methods execute asynchronously, with a callback method specified as one of the invocation parameters. For example, we can get information about the person currently running (viewing) our application by creating a new OpenSocial data request and indicating what request we want to make:

var req = opensocial.newDataRequest();


We then send the request to our container:


The response parameter is a function; as soon as the request returns a response, that function will be invoked. Moreover, when the response function is invoked, it will be passed a single parameter that contains the results from our method call.

We can send multiple queries within a single data-request object; all we have to do is invoke req.add multiple times. As you can see from the above line of code, invoking req.newFetchPersonRequest required that we both indicate what we want to request, and that we give it a symbolic name (viewer). This naming allows us to pull apart different types of response data within a single object.

You might be wondering what stops the viewer from being able to retrieve arbitrary data from the OpenSocial container. The answer is that OpenSocial defines two basic types of people: the viewer and the owner. The former, as we have seen, refers to the person who is running and viewing the operation—and might even refer to no one at all, if our system permits anonymous browsing. The owner, by contrast, must be a defined person on the system, and may very well refer to the same person as the viewer. But at least in theory, OpenSocial will provide only limited information to viewers about owners with whom they have no relationship.


Geek Guide
The DevOps Toolbox

Tools and Technologies for Scale and Reliability
by Linux Journal Editor Bill Childers

Get your free copy today

Sponsored by IBM

8 Signs You're Beyond Cron

Scheduling Crontabs With an Enterprise Scheduler
On Demand
Moderated by Linux Journal Contributor Mike Diehl

Sign up and watch now

Sponsored by Skybot