Home > Articles > Home & Office Computing > The Web/Virtual Worlds/Social Networking

  • Print
  • + Share This
This chapter is from the book

Accessing MySpace User Data

MySpace Profile data is represented in OpenSocial by the opensocial.Person object. Essentially,

opensocial.Person = a MySpace Profile

The opensocial.Person object contains the methods shown in Table 2.1. In addition, the opensocial.Person object supports a wide range of data fields, such as a user's ID, Profile picture, or favorite movies. Table 2.2 presents all of the supported person fields along with their return types.

Table 2.1. opensocial.Person Methods*

Method

Purpose

getDisplayName()

Gets a text display name for this person; guaranteed to return a useful string

getField(key, opt_params)

Gets data for this person that is associated with the specified key

getId()

Gets an ID that can be permanently associated with this person

isOwner()

Returns true if this person object represents the owner of the current page

isViewer()

Returns true if this person object represents the currently logged-in user

Table 2.2. MySpace opensocial.Person Fields*

MySpace-Supported Person Field

Description

Return Type

opensocial.Person.Field.ABOUT_ME

A general statement about the person

String

opensocial.Person.Field.AGE

Person's age

Number

opensocial.Person.Field.BODY_TYPE

An object containing the person's body type; MySpace returns only opensocial.BodyType.Field.BUILD and opensocial.BodyType.Field.HEIGHT

opensocial.BodyType

opensocial.Person.Field.BOOKS **

Person's favorite books

Array of strings

opensocial.Person.Field.CHILDREN

Description of the person's children

String

opensocial.Person.Field.CURRENT_LOCATION

Person's current location; MySpace returns only opensocial.Address.Field.REGION, opensocial.Address.Field.COUNTRY, and opensocial.Address.Field.POSTAL_CODE

opensocial.Address

opensocial.Person.Field.DATE_OF_BIRTH

Person's date of birth

Date

opensocial.Person.Field.DRINKER

Person's drinking status (with the enum's key referencing opensocial.Enum.Drinker)

opensocial.Enum

opensocial.Person.Field.ETHNICITY

Person's ethnicity

String

opensocial.Person.Field.GENDER

Person's gender (with the enum's key referencing opensocial.Enum.Gender)

opensocial.Enum

opensocial.Person.Field.HAS_APP

Whether or not the person has added the app

Boolean

opensocial.Person.Field.HEROES **

Person's favorite heroes

Array of strings

opensocial.Person.Field.ID

MySpace user ID

String

opensocial.Person.Field.INTERESTS **

Person's interests, hobbies, or passions

Array of strings

opensocial.Person.Field.JOBS

Jobs the person has held; MySpace returns only opensocial.Organization.Field.NAME and opensocial.Organization.Field.TITLE

Array of opensocial.Organization

opensocial.Person.Field.LOOKING_FOR

Person's statement about whom or what he or she is looking for or what he or she is interested in meeting people for

opensocial.Enum

opensocial.Person.Field.MOVIES **

Person's favorite movies

Array of strings

opensocial.Person.Field.MUSIC **

Person's favorite music

Array of strings

opensocial.Person.Field.NAME

An object containing the person's name; MySpace returns only opensocial.Name.Field.UNSTRUCTURED

opensocial.Name

opensocial.Person.Field.NETWORK_PRESENCE

Person's current network status (with the enum's key referencing opensocial.Enum.Presence)

opensocial.Enum

opensocial.Person.Field.NICKNAME

Person's nickname

String

opensocial.Person.Field.PROFILE_SONG

Person's Profile song

opensocial.Url

opensocial.Person.Field.PROFILE_URL

Person's Profile URL

String (must be fully qualified)

opensocial.Person.Field.RELATIONSHIP_STATUS

Person's relationship status

String

opensocial.Person.Field.RELIGION

Person's religion or religious views

String

opensocial.Person.Field.SEXUAL_ORIENTATION

Person's sexual orientation

String

opensocial.Person.Field.SMOKER

Person's smoking status (with the enum's key referencing opensocial.Enum.Smoker)

opensocial.Enum

opensocial.Person.Field.STATUS

Person's status

String

opensocial.Person.Field.THUMBNAIL_URL

Person's photo thumbnail URL

String (must be fully qualified)

opensocial.Person.Field.TV_SHOWS

Person's favorite TV shows

Array of strings

opensocial.Person.Field.URLS

URLs related to the person or the person's Web pages or feeds; returns only the Profile URL, so it's better to use opensocial.Person.Field.PROFILE_URL instead

Array of opensocial.Url

MyOpenSpace.Person.Field.MEDIUM_IMAGE

Medium-sized version of the image returned by THUMBNAIL_URL; MySpace returns opensocial.Url.Field.ADDRESS and opensocial.Url.Field.TYPE. This field is not part of the OpenSocial spec and is a MySpace-specific extension.

opensocial.Url

MyOpenSpace.Person.Field.LARGE_IMAGE

Large version of the image returned by THUMBNAIL_URL; MySpace returns opensocial.Url.Field.ADDRESS and opensocial.Url.Field.TYPE. This field is not part of the OpenSocial spec and is a MySpace-specific extension.

opensocial.Url

Accessing Profile Information Using the opensocial.Person Object

The first thing we're going to add to our basic Tic-Tac-Toe app is the ability to get the default fields for our Viewer by fetching the corresponding opensocial.Person object using an opensocial.DataRequest. MySpace defines these default opensocial. Person.Field values for the Person object:

  • Profile URL, or opensocial.Person.Field.PROFILE_URL
  • Image URL, or opensocial.Person.Field.THUMBNAIL_URL
  • Display name, or opensocial.Person.Field.NAME
  • User ID, or opensocial.Person.Field.ID

These are the bare-minimum default fields that, as long as you have access to the Person object, will always be returned.

One thing to note is that all requests to the MySpace API are asynchronous, meaning you launch them as "fire and forget" requests. Typically you make a request and specify a callback function; when the server is done processing your request, it passes the results as a parameter into your callback function. One result of this is that you're probably going to want to put your data requests at the start of the code. That way the MySpace API can start processing your request as soon as possible, and your app won't be stuck waiting for data to come back.

Let's take a look at a function that does the following:

  1. Instantiates an opensocial.DataRequest object
  2. Calls newFetchPersonRequest to create a generic request object, passing in the VIEWER as a parameter
  3. Adds the request to the queue by calling add(), passing in a key to name the request

The following code shows this function:

/**
 * Makes the initial call for the Viewer's opensocial.Person
 * object and requests all fields supported by MySpace
 */
function getInitialData(){

   // Returns an opensocial.DataRequest object
   var req = opensocial.newDataRequest();

   // Create a request object, passing in the Viewer; this will
   // specify we want the opensocial.Person for the Viewer
   var viewer_req = req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER);

   // Add the request to the queue and give it a key
   req.add(viewer_req, "v");

   // Start processing the requests and specify the callback function
   req.send(getDataCallback);
}

The first line of the function simply returns an opensocial.DataRequest object. The DataRequest object is designed to take care of all your requesting needs. While developing our app, we'll make heavy use of it.

opensocial.IdSpec.PersonId.VIEWER is one of many enums you'll encounter in OpenSocial. In JavaScript this actually resolves into a string, and on MySpace specifically it is equal to the string VIEWER. You can use the string and enum interchangeably, but we recommend using the enum for two reasons:

  • If you mistype the enum, your mistake triggers a JavaScript error, but if you mistype the string, it isn't immediately obvious that something went wrong, so it is harder to debug.
  • The values to which the enums resolve aren't yet clearly outlined in the OpenSocial spec, so different containers might resolve enums to different strings.

We use opensocial.IdSpec.PersonId.VIEWER here to state that we want to fetch the Viewer's data. Had we wanted to fetch the Owner's data, we would have used opensocial.IdSpec.PersonId.OWNER.

newFetchPersonRequest takes the ID of the user you want to request as a parameter (in this case the Viewer) and returns an object. That object is actually unnamed by OpenSocial, and the documentation simply refers to it as a "request." This object is never used directly beyond how it's used here—passed into DataRequest's add() function.

Essentially, the DataRequest object creates "request" objects that are passed into its own add function. It may seem a little confusing, but remember—you'll never have to use that mysterious, unnamed "request" object directly, and all OpenSocial API calls follow this general pattern.

The add function takes that request and adds it to a queue that is stored in the DataRequest object. We also give the request a key and, in this case, the string "v". This key is used to identify the response of a specific request; we'll use this key later when we talk about how to parse responses.

The last line tells the container to start processing the request queue by calling send(). We pass the name of our callback function into send() as a parameter; when the server is done processing our request, it calls this function while passing in the response. You can see the flow of the OpenSocial data request and response pattern in Figure 2.2.

Figure 2.2

Figure 2.2 Basic request and response pattern for OpenSocial.

Getting More than Just the Default Profile Data

Fields beyond the default person fields typically follow a slightly different request pattern and may also require higher permission levels for access.

As an example of this, we'll be requesting our Viewer's status message (like a headline or shout-out), address, and gender. We've modified the function shown previously to now specify that we want this additional data:

/**
 * Makes the initial call for the Viewer's opensocial.Person
 * object and requests all fields supported by MySpace
 */
function getInitialData(){

   // Returns an opensocial.DataRequest object
   var req = opensocial.newDataRequest();

   // Used to specify what data is returned in the response
   var fields = [opensocial.Person.Field.CURRENT_LOCATION,
                  opensocial.Person.Field.GENDER,
                  opensocial.Person.Field.STATUS];

   // Create an empty object to use for passing in the parameters;
   // the parameters here are additional person fields from above
   var opt_params = {};

   // Add the list of fields to the parameters
opt_params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = fields;

   // Create a request object, passing in the Viewer; this will
   // specify we want the opensocial.Person for the Viewer
   var viewer_req =
      req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER,opt_params);

   // Add the request to the queue and give it a key
   req.add(viewer_req, "v");

   // Start processing the request and specify the callback function
   req.send(getDataCallback);
}

Let's take a look at what's changed. The first line is the same; we instantiate an opensocial.DataRequest object. In the next line we create an array of opensocial.Person.Field enums; this list corresponds to the specific Person fields we want from the API.

Next, an empty object is created called opt_params. This is another OpenSocial pattern that you'll see repeated in many places. Requests typically have some default action, and if you want to modify the default action, you need to supply some parameters to define what you want to do. You do this by adding certain properties to an object and passing that object into the request.

When the MySpace container is processing a request for Viewer or Owner data, it checks the parameters sent in for a property named profileDetail. If it finds such a property, it knows that additional fields were requested. So let's take a look at that line again:

// Add the list of fields to the parameters
opt_params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = fields;

On MySpace, opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS resolves to the string profileDetail. We're creating that property and setting it equal to the array of opensocial.Person.Field values we created earlier. The container now knows that additional fields were requested.

The rest of the function is the same as before—we create the request, add it to the queue, and send it off.

opensocial.DataResponse and opensocial.ResponseItem (aka, Using MySpace User Data)

The various person fields are returned in different ways, but there are essentially three types of responses:

  • A literal, such as a string or a number. For example, opensocial.Person.Field.STATUS returns a string.
  • An object. For example, opensocial.Person.Field.CURRENT_LOCATION returns an opensocial.Address object.
  • An enum. For example, opensocial.Person.Field.GENDER returns an opensocial.Enum enum object.

All responses from the API come in the form of an opensocial.DataResponse object. The DataResponse object contains some number of opensocial.ResponseItem objects; each ResponseItem corresponds to the requests we added to the DataRequest queue. For now, we just have the one request for the Viewer; we'll look at dealing with multiple requests and ResponseItem objects in the next chapter.

To get a particular ResponseItem object from an opensocial.DataResponse, you need to use a key. If you already provided an optional key, use that. Otherwise, you can use the default key created by the MySpace container.

/**
 * The callback method for the initial request
 * @param {opensocial.DataResponse} data
 */
function getDataCallback(data){

   // "v" was the key created in the request,
   // data is an object of type opensocial.DataResponse
   // data.get("v") returns an opensocial.ResponseItem
   // data.get("v").getData() will return the actual data,
   // in this case an opensocial.Person object
   viewer = data.get("v").getData();

   // Now let's do something with all that data
   printPerson();
}

Let's take a look at this function more closely. The first thing to notice is that it is the function we specified when we called send() in our previous request function.

// Start processing the request and specify the callback function
req.send(getDataCallback);

The function getDataCallback is executed when the server has processed our request and prepared a response. The first line in getDataCallback takes that DataResponse object and calls the get() function, passing in our key. Above we named our Viewer request "v"; here we use that key to get the ResponseItem that corresponds to that request.

The function call data.get("v") returns the ResponseItem object that contains the Viewer's opensocial.Person object; we get the Person by calling getData(). Now the variable viewer contains an object of type opensocial.Person, which in turn contains the details of the Viewer, specifically the four default fields plus the current location, gender, and status. Table 2.3 shows the methods available for the ResponseItem object.

Table 2.3. opensocial.ResponseItem Methods*

Method

Purpose

getData()

Gets the response data

getErrorCode()

If an error was generated by the request, returns the error code

getErrorMessage()

If an error was generated by the request, returns the error message

getOriginalDataRequest()

Returns the original data request

hadError()

Returns true if there was an error in fetching this data from the server

The next section of our code calls the function printPerson(), which is a helper function that we use to parse out the details of our Viewer and output them to the screen. Here we will parse out all three types of responses—enums, strings, and objects:

/**
 * Output the Viewer data onto the surface
 */
function printPerson(){
   if(null !== viewer){
      // You can set the src attribute of an
      // <img> tag directly with THUMBNAIL_URL

      document.getElementById("profile_image").src = viewer.getField(opensocial.Person.Field.THUMBNAIL_URL);

      // getDisplayName is a shortcut for
      // getField(opensocial.Person.Field.NICKNAME)
      document.getElementById("name").innerHTML = viewer.getDisplayName();

      // Get the Viewer's status
      var status = viewer.getField(opensocial.Person.Field.STATUS);
      if(status && status.length > 0){

         // If the status has been set, append it after the name
         document.getElementById("name").innerHTML += " \"" + status + "\"";
      }

      // Get the opensocial.Address object
      var location = viewer.getField(opensocial.Person.Field.CURRENT_LOCATION);

      // The Address object is used similarly to the Person object; both pass a
      // field into a getField function
      document.getElementById("location").innerHTML = location.getField(opensocial.Address.Field.REGION);

      // gender is an opensocial.Enum object
      var gender = viewer.getField(opensocial.Person.Field.GENDER);

      // getDisplayValue is defined by the specific container and can and
      // will differ between containers and is designed for displaying only
      document.getElementById("gender").innerHTML = gender.getDisplayValue();

      // The response of getKey is defined by OpenSocial and therefore
      // you can compare the result to some known value
      if(gender.getKey() === opensocial.Enum.Gender.FEMALE){
         document.getElementById("myinfo").style.backgroundColor =
            "#fcf"; // pink
      }
      else{
         document.getElementById("myinfo").style.backgroundColor = "#09f"; // blue
      }
   }
}

Let's break down this code. To access the data from the viewer variable, which is of type opensocial.Person, we'll typically need to use the getField() function. After we confirm that viewer isn't null, we call getField(), pass in the field we want as a parameter, and set that value to the src attribute of an image tag. The field we asked for, opensocial.Person.Field.THUMBNAIL_URL, is returned as a string, so we can just access it directly. That's really all there is to parsing out a Person field that is returned as a string. For details on the return type for every supported Person field, refer back to Table 2.2 in this chapter.

The next line uses a shortcut to retrieve the Viewer's display name. Another shortcut, getID(), exists to retrieve the Viewer's ID. All other fields are accessed using getField(), as you'll see in the next few lines. We could have used getField(opensocial.Person.Field.NICKNAME) to retrieve the display name, but the shortcut is cleaner.

Next, we parse out the Viewer's current location; this field is returned as an opensocial.Address object. You'll notice that the opensocial.Address object behaves similarly to the opensocial.Person object. Both have fields that describe the types of data you can retrieve, which in turn are fetched using the getField() function. Many of the objects in OpenSocial follow this pattern.

Finally, we parse out the gender, which is an opensocial.Enum object. There are two useful types of data in each opensocial.Enum: the display value and the key. The display value is retrieved using getDisplayValue() and is a string that is defined by each container as it sees fit. For example, the display value for the female gender, depending on the container, could be "female" or "It's a girl!" or even "http://example.com/girl.jpg." Because these display values can be different from container to container, the key is typically used when making comparisons as the key values are defined in the OpenSocial spec.

In our code, we output the display value to the surface but use the key to make a logical comparison; we set the background color to pink if the gender is female (i.e., it's equal to opensocial.Enum.Gender.FEMALE), or blue otherwise.

In the full code listing for the chapter, which you can find at http://code.google.com/p/opensocialtictactoe/source/browse/#svn/trunk/chapter2, we added a function that goes through each Person field and parses it. If you're wondering how to parse a particular field that wasn't covered here, take a look at the code and you should be able to find what you need.

  • + Share This
  • 🔖 Save To Your Account