This guide will help you build OpenSocial applications. It is meant for developers who have some general familiarity with the Gadgets API, and JavaScript in general, but provides links to other resources in places where you may need more information.
This document has been modified to reflect changes from the 0.6 update of the OpenSocial API. Sections are marked as being New! or Updated to help you identify coding practices that have changed since the last version.
A social gadget is simply a gadget that runs on a container that supports the OpenSocial JavaScript API.
To write a social application, you need the following:
The OpenSocial API focuses on people. It lets users share their activities with each other and access information about their friends. There are three primary areas of functionality in the OpenSocial API:
Many API calls are asynchronous as they may require a server request to retrieve or update information. Because of this, you need to pass in a callback function that will be executed once the data is returned from the server.
For detailed information, see the API Reference.
To use the OpenSocial API, add the following Requires section to your application:
<ModulePrefs title="Title of Your Application"> <Require feature="opensocial-0.6"/> </ModulePrefs>
Let's get started with a simple example that lists the names of your friends. To retrieve data, you create a DataRequest
by calling opensocial.newDataRequest(). You then call
DataRequest.add(request) once for each type of data you would like to retrieve.
After adding all of the individual requests, call DataRequest.send(callback).
The callback parameter is a function that will be executed once the server request has been
processed. This function takes one DataResponse parameter that has
the results of the request.
For example, if you want to get information about "friends", you would do something like this:
function onLoadFriends(dataResponse) { // do something with the dataResponse }
/**
* Request for friend information when the page loads.
*/
function getData() {
document.getElementById('message').innerHTML = 'Requesting friends...';
var req = opensocial.newDataRequest();
req.add(req.newFetchPersonRequest('VIEWER'), 'viewer');
req.add(req.newFetchPeopleRequest ('VIEWER_FRIENDS'), 'viewerFriends');
req.send(onLoadFriends);
};
The last parameter in the newFetch*Request() calls
("viewer", "viewerFriends" above) is a string key used to retrieve
the data in the response.
The OpenSocial API defines the following roles:
Within an application, usually the very first thing you want to do is to make the request. So in your JavaScript you would register an application onload handler by calling:
gadgets.util.registerOnLoadHandler(getData);
Let's suppose you did the example in the previous section. Now you
want to do something with your input, which is of the type opensocial.DataResponse.
The onLoadFriends() function below parses the DataResponse it
takes as a parameter, and displays the names of the viewer and
the viewer's friends:
/**
* Parses the response to the friend information request and generates
* html to list the friends by their display name.
*
* @param {Object} dataResponse Friend information that was requested.
*/
function onLoadFriends(dataResponse) {
var viewer = dataResponse.get('viewer').getData();
var html = 'Friends of ' + viewer.getDisplayName();
html += ':<br><ul>';
var viewerFriends = dataResponse.get('viewerFriends').getData();
viewerFriends.each(function(person) {
html += '<li>' + person.getDisplayName();
});
html += '</ul>';
document.getElementById('message').innerHTML = html;
};
The dataResponse parameter passed into the callback function is of type
DataResponse. Calling DataResponse.get(key) with the string key
you passed in to the newFetch*Request() returns a ResponseItem
containing the results of the request.
Calling dataResponse.get(key).getData() returns you the actual
response data for a successful request. Response data types associated
with common requests:
newFetchPersonRequest("VIEWER", key): Information
about the user who is currently viewing the application. Returns
an object of the type opensocial.Person.newFetchPeopleRequest("VIEWER_FRIENDS"', key):
Information about the friends of the viewer. Returns
a collection of objects of the type opensocial.Person.newFetchPersonRequest("OWNER", key): Information
about the user who is currently hosting the application. Returns
an object of the type opensocial.Person.newFetchPeopleRequest("OWNER_FRIENDS", key):
Information about the friends of the owner. Returns
a collection of objects of the type opensocial.Person.DataResponse.get(key).hasError() returns true if a given request
was unsuccessful.
Here is the complete code for the List Friends application discussed above:
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="List Friends Example">
<Require feature="opensocial-0.6"/>
</ModulePrefs>
<Content type="html">
<![CDATA[
<script type="text/javascript">
/**
* Request for friend information when the page loads.
*/
function getData() {
document.getElementById('message').innerHTML = 'Requesting friends...';
var req = opensocial.newDataRequest();
req.add(req.newFetchPersonRequest('VIEWER'), 'viewer');
req.add(req.newFetchPeopleRequest ('VIEWER_FRIENDS'), 'viewerFriends');
req.send(onLoadFriends);
};
/**
* Parses the response to the friend information request and generates
* html to list the friends along with their display name.
*
* @param {Object} dataResponse Friend information that was requested.
*/
function onLoadFriends(dataResponse) {
var viewer = dataResponse.get('viewer').getData();
var html = 'Friends of ' + viewer.getDisplayName();
html += ':<br><ul>';
var viewerFriends = dataResponse.get('viewerFriends').getData();
viewerFriends.each(function(person) {
html += '<li>' + person.getDisplayName() + '</li>';
});
html += '</ul>';
document.getElementById('message').innerHTML = html;
};
gadgets.util.registerOnLoadHandler(getData);
</script>
<div id="message"> </div>
]]>
</Content>
</Module>
The OpenSocial API supports saving and retrieving per-user, per-application data. In OpenSocial v0.5 and v0.6, per-application instance and global app data were also specified, though they has been deprecated and will be removed for 0.7.
This code snippet shows how to save data to the shared store:
function populateMyAppData() {
var req = opensocial.newDataRequest();
var data1 = Math.random() * 5;
var data2 = Math.random() * 100;
var data3 = new Date().getTime();
req.add(req.newUpdatePersonAppDataRequest("VIEWER", "AppField1", data1));
req.add(req.newUpdatePersonAppDataRequest("VIEWER", "AppField2", data2));
req.add(req.newUpdatePersonAppDataRequest("VIEWER", "AppField3", data3));
req.send(handlePopulateMyAppData);
};
Note that the data stored is always a string; for most purposes, it is practical to make this a JSON-encoded string.
You could retrieve the data as follows:
var req = opensocial.newDataRequest();
//Request the following three app fields
var fields = [ "AppField1", "AppField2", "AppField3" ];
req.add(req.newFetchPersonAppDataRequest("VIEWER", fields), "viewer_data");
req.send(handleRequestMyData);
Here is the complete code for the application, which illustrates how to make different kinds of common requests in the OpenSocial API:
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Sample Requests" >
<Require feature="opensocial-0.6"/>
</ModulePrefs>
<Content type="html">
<![CDATA[
<script type="text/javascript">
/************************************************************************
* Sample calls for the OpenSocial API
*
* These functions show some basic uses of the social API.
*
***********************************************************************/
var htmlout = "";
var me = null;
gadgets.util.registerOnLoadHandler(requestMe);
/************************************************************************
* How do I get my data?
*/
function requestMe() {
// Make a new DataRequest object. This is the base object you will
// create for all data requests
var req = opensocial.newDataRequest();
// Add a FETCH PERSON request object to the current DataRequest
req.add(req.newFetchPersonRequest("VIEWER"), "viewer");
req.send(handleRequestMe);
};
/************************************************************************
* How do I handle responses from fetch person requests?
*/
function handleRequestMe(data) {
// Note that we are getting the parameter we specified in the request
var viewer = data.get("viewer");
// Error handling
if (viewer.hadError()) {
//Handle error using viewer.getError()
console.log(viewer.getError());
return;
}
// If there was not an error, assign the global "me" variable
// Note the getData call to pull data out of the response object
me = viewer.getData();
requestFriends();
};
/************************************************************************
* How do I get my friends??
*/
function requestFriends() {
var req = opensocial.newDataRequest();
// Add a FETCH PEOPLE request object to the current DataRequest.
// The parameter passed to newFetchPeopleRequest can be one of
// VIEWER_FRIENDS or OWNER_FRIENDS as needed
req.add(req.newFetchPeopleRequest("VIEWER_FRIENDS"), "viewer_friends");
// Send the request, specifying the function that will recieve data
req.send(handleRequestFriends);
};
/************************************************************************
* How do I handle responses from fetch people requests?
*/
function handleRequestFriends(data) {
var myfriends = data.get("viewer_friends");
if (myfriends.hadError()) {
console.log(myfriends.getError());
return;
}
// Operate on each person that is returned. Note the getData() request
myfriends.getData().each(doSomethingWithPerson);
populateMyAppData();
};
/************************************************************************
* How do I operate on Person objects?
*/
function doSomethingWithPerson(person) {
htmlout += "This person's name: " + person.getDisplayName() + "<br />";
htmlout += "This person's picture: " + person.getField("picture") + "<br />";
};
/************************************************************************
* How do we set user data?
*/
function populateMyAppData() {
var req = opensocial.newDataRequest();
var data1 = Math.random() * 5;
var data2 = Math.random() * 100;
var data3 = new Date().getTime();
htmlout += "Setting AppField1 to " + data1 + "<br />";
req.add(req.newUpdatePersonAppDataRequest("VIEWER", "AppField1", data1)) + "<br />";
htmlout += "Setting AppField2 to " + data2 + "<br />";
req.add(req.newUpdatePersonAppDataRequest("VIEWER", "AppField2", data2)) + "<br />";
htmlout += "Setting AppField3 to " + data3 + "<br />";
req.add(req.newUpdatePersonAppDataRequest("VIEWER", "AppField3", data3)) + "<br />";
req.send(handlePopulateMyAppData, "update_appdata");
};
/************************************************************************
* How do I handle responses from update person app data requests?
*/
function handlePopulateMyAppData(data) {
if (data.hadError()) {
//Handle the error
console.log(data.getError());
}
requestMyData();
};
/************************************************************************
* How do I fetch app data?
*/
function requestMyData() {
var req = opensocial.newDataRequest();
//Request the following three app fields
var fields = [ "AppField1", "AppField2", "AppField3" ];
req.add(req.newFetchPersonAppDataRequest("VIEWER", fields), "viewer_data");
req.send(handleRequestMyData);
};
/************************************************************************
* How do I handle responses from app data requests?
*/
function handleRequestMyData(data) {
var mydata = data.get("viewer_data");
if (mydata.hadError()) {
console.log(mydata.getError());
return;
}
//Do something with the returned data - note the getData call
doSomethingWithMyData(mydata.getData());
};
/************************************************************************
* How do we operate on user data?
*/
function doSomethingWithMyData(data) {
//Data is indexed by user id, and represents an object where keys
//correspond with the app data fields.
var mydata = data[me.getId()];
var div = document.getElementById('content_div');
htmlout += "My AppField1 data is: " + mydata["AppField1"] + "<br />";
htmlout += "My AppField2 data is: " + mydata["AppField2"] + "<br />";
htmlout += "My AppField3 data is: " + mydata["AppField3"] + "<br />";
div.innerHTML = htmlout;
};
</script>
<div id="content_div"></div>
]]>
</Content>
</Module>
The OpenSocial API lets you share activities with your friends through an activity stream. An activity stream is a feed in which each entry represents an action performed by the user. An activity could be anything from modifying an application's state to writing an online review for a movie.
If you request HIGH activity priority, the app will ask the user for permission to post activities on behalf of the user if it doesn't already have permission. If you request LOW priority, then the call will do nothing if the app doesn't have permission to post.
As you can see in the following example, the activity stream API uses the same request-response approach discussed above. This example illustrates how to fetch, display, and add new activities to an activity stream:
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Activities" description="Sample code for reading and writing activity stream" >
<Require feature="opensocial-0.6"/>
</ModulePrefs>
<Content type="html">
<![CDATA[
<script type="text/javascript">
gadgets.util.registerOnLoadHandler(getActivities);
function getActivities() {
var req = opensocial.newDataRequest();
req.add(req.newFetchPersonRequest('VIEWER'), 'viewer');
req.add(req.newFetchActivitiesRequest('VIEWER'), 'viewerActivities');
req.add(req.newFetchActivitiesRequest('VIEWER_FRIENDS'), 'friendActivities');
req.send(showActivities);
}
function showActivities(dataResponse) {
var viewer = dataResponse.get('viewer').getData();
var viewerActivities = dataResponse.get('viewerActivities').getData()['activities'];
var friendActivities = dataResponse.get('friendActivities').getData()['activities'];
var htmlout = '';
htmlout += '<h2>Your activities:</h2><br>';
htmlout += getActivitiesHtml(viewerActivities);
htmlout += '<h2>Your friends\' activities:</h2><br>';
htmlout += getActivitiesHtml(friendActivities);
document.getElementById('read_activities').innerHTML = htmlout;
}
function getActivitiesHtml(stream) {
console.log(stream);
var htmlout = '';
stream.each(function(activity) {
var link = activity.getField('url');
if (link) {
htmlout += '<a href="' + link +'" target="_blank">'+ activity.getField('title') + '</a>';
} else {
htmlout += activity.getField('title');
}
htmlout += '<br>';
});
return htmlout;
}
function writeActivity() {
var streamFolder = 'sampleFolder';
var streamTitle = 'Sample Stream';
var stream_params = {'url': 'http://samplestream.com' };
var stream = opensocial.newStream(streamFolder, streamTitle, stream_params);
var title = document.getElementById('title').value;
var link = document.getElementById('link').value;
var activity_params = {'url' : link}
var activity = opensocial.newActivity(stream, title, activity_params)
opensocial.requestCreateActivity(activity, "HIGH", getActivities);
}
</script>
<div id="write_activities">
Title:<input id="title" /><br>
Link:<input id="link" /><br>
<input type="button" value="add activity" onclick="writeActivity();" />
</div>
<div id="read_activities">
</div>
]]>
</Content>
</Module>
The OpenSocial API gives applications the ability to interact with their container in the following ways:
The OpenSocial API includes a Surface class and an Environment class. You can use opensocial.requestNavigateTo to take your application from one page of a container to another (for example, to link the profile to the canvas page). This call takes a Surface object, which you get from an Environment object (opensocial.getEnvironment()). The environment's getSupportedSurfaces method tells you which surfaces the container supports, and getSurface tells you which one you are currently on. The getParams method returns all of the parameters passed in by the requestNavigateTo call if any were requested. The Surface class currently has two methods, getName and isPrimaryContent.
This excerpt shows how to use the API to navigate from one surface to another. It displays a list of links that the user can click to navigate to the container's available surfaces.
/**
* Create the list of links to the other surfaces
*/
function createLinks() {
//Get the environment, current surface and an array of the supported surfaces
var env = opensocial.getEnvironment();
var surfaces = env.getSupportedSurfaces();
var currentsurface = env.getSurface();
var text = [ "You are currently on the ",
currentsurface.getName(),
" surface. Other surfaces: " ].join("");
//Set up some DOM
var output = document.getElementById("output");
output.appendChild(document.createTextNode(text));
var ol = document.createElement("ol");
output.appendChild(ol);
//Iterate over each surface
for (var i=0,surface; surface=surfaces[i]; i++) {
//Make some DOM to present each link
var li = document.createElement("li");
var a = document.createElement("a");
ol.appendChild(li);
li.appendChild(a);
a.href = "javascript:void(0);";
//Put the name of the surface in the link
a.appendChild(document.createTextNode("Link to " + surface.getName()));
//Handle when the user clicks a link to the other server
a.onclick = getNavigateClosure(surface);
}
};
/**
* Returns a function that navigates to the supplied surface
*/
function getNavigateClosure(surface) {
return function() { opensocial.requestNavigateTo(surface); };
};
//Execute createLinks when the page is done loading
gadgets.util.registerOnLoadHandler(createLinks);
The Environment class includes a getDomain method, which tells you which site you are in (such as orkut.com or myspace.com). This allows your application to respond in different ways to different environments. However, we recommend that you use another method, hasCapability, for all functional changes. The hasCapability method takes a function name and tells you if that function is available in your current container. This lets a container add its own extensions to OpenSocial while still giving developers one common mechanism for accessing them. This container-specific extensibility also shows up in the supportsField method. If a container provider wants to add its own person or activity field, it can. The field only needs to be documented somewhere outside of the opensocial namespace and then developers can query the environment to see whether that specific field is supported.
This sample application changes its display depending on whether the user is in the profile or the canvas:
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="My Environment">
<Require feature="opensocial-0.6"/>
</ModulePrefs> <Content type="html">
<![CDATA[
<script type="text/javascript">
/**
* Request for friend information when the page loads.
*/
function getData() {
var req = opensocial.newDataRequest();
req.add(req.newFetchPersonRequest(opensocial.DataRequest.PersonId.VIEWER), 'viewer');
req.send(greetUser);
}
/**
* Change the display of the user greeting depending on whether the
* user is in the profile or the canvas.
*/
function greetUser(dataResponse) {
var viewer = dataResponse.get('viewer').getData();
// Determine whether the container supports the getEnvironment method
var isAble = opensocial.getEnvironment().hasCapability("opensocial.getEnvironment");
var html = '<h2>Greetings, ' + viewer.getDisplayName() + '!</h2>';
// If the container supports the getEnvironment method, determine whether the user
// is in the canvas or profile
if (isAble)
{
var myenv = opensocial.getEnvironment();
var surf = myenv.getSurface();
// If the user is in the canvas, display the canvas view of the greeting
if (surf.getName() == 'canvas')
{
showCanvasView(html);
}
// Otherwise, display the profile view of the greeting
else
{
// If the container supports the field THUMBNAIL_URL for PERSON objects, include it in the
// profile view greeting page
if (myenv.supportsField(opensocial.Environment.ObjectType.PERSON, opensocial.Person.Field.THUMBNAIL_URL))
{
var thumb = viewer.getField(opensocial.Person.Field.THUMBNAIL_URL);
html += "<img src=" + thumb + "/>";
}
// Display the greeting in the profile and include the user's thumbnail
document.getElementById('profile-div').innerHTML = html;
}
}
// Default: just display the greeting with no image
else {
document.getElementById('profile-div').innerHTML = html;
}
}
/** If the user is in canvas, change the display to take advantage of
* additional screen area
*/
function showCanvasView(str) {
var div = document.getElementById('canvas-div');
div.style.display="";
str += "<img src='http://gadget-doc-examples.googlecode.com/svn/trunk/my-canvas-photo.jpg' />";
div.innerHTML = html;
}
gadgets.util.registerOnLoadHandler(getData);
</script>
<div id="profile-div"> </div>
<div id="canvas-div" style="display:none; font-family:Tahoma; background-color: #FFC0CB; margin: 5px; height: 570px; text-align: center;"></div>
]]>
</Content>
</Module>
The opensocial.makeRequest() method is an enhancement to the current gadget API IG_Fetch... methods. The opensocial.makeRequest() method allows for POSTs as well as GETs, and you can specify whether you want your data fetch to be signed or even authenticated. Once containers implement this call, your external servers can be more secure.
The opensocial.makeRequest() method takes these parameters:
By default, makeRequest() uses the GET method to fetch data, and the default type for content is 'html' (where a web page's content is fetched as raw text). The other possible method is POST, and the other content types are 'xml' and 'feed'.
This example shows a very simple use of the API. It fetches the first 400 characters on www.google.com and outputs them to a <div>:
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Fetch">
<Require feature="opensocial-0.6"/>
</ModulePrefs>
<Content type="html">
<![CDATA[
<div id="content_div"></div>
<script type="text/javascript">
opensocial.makeRequest("http://www.google.com",
function(response) {
var html = response.substr(0,400);
document.getElementById('content_div').innerHTML = html;
}, {'method' : 'GET', 'contentType' : 'html'});
</script>
]]>
</Content>
</Module>
Note the parameters specified at the end of the makeRequest() call:
{'method' : 'GET', 'contentType' : 'html'}
As stated above, GET is the default method, and 'html' is the default contentType for makeRequest(). So strictly speaking, these parameters don't need to be included here, but they are shown for clarity. The parameters field becomes significant for the POST method and for the 'xml' and 'feed' content types.
This example shows how to use the 'xml' content type to process XML data. When you specify the 'xml' content type, makeRequest() retrieves the specified XML document as a DOM object. Once you have the object, you can operate on it using standard DOM JavaScript functions. For more discussion of this topic, see the Google Gadgets API Developers Guide.
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Fetch">
<Require feature="opensocial-0.6"/>
</ModulePrefs>
<Content type="html">
<![CDATA[
<div id="content_div"></div>
<script type="text/javascript">
opensocial.makeRequest("http://doc.examples.googlepages.com/breakfast-data.xml",
function(response) {
var title = response.getElementsByTagName("menu").item(0).getAttribute("title");
var html = "<h2>" + title + "</h2>";
// Get a list of the <food> element nodes in the file
var itemList = response.getElementsByTagName("food");
// Loop through all <food> nodes
for (var i = 0; i < itemList.length ; i++) {
// For each <food> node, get child nodes.
var nodeList = itemList.item(i).childNodes;
// Loop through child nodes. Extract data from the text nodes that are
// the children of the associated name and price element nodes.
for (var j = 0; j < nodeList.length ; j++) {
var node = nodeList.item(j);
if (node.nodeName == "name") {
var name = node.firstChild.nodeValue;
}
if (node.nodeName == "price") {
var price = node.firstChild.nodeValue;
}
}
html += name + " - ";
html += price + "<br />";
}
html += "</div>";
document.getElementById('content_div').innerHTML = html;
}, {'method' : 'POST', 'contentType' : 'xml', 'postData' : 'value1'});
</script>
]]>
</Content>
</Module>
The above example uses the POST method. Whether you use the GET method or POST method depends on the needs of your particular application; the method you pick is independent from the content type. Note that when you use the POST method, you must include the postData parameter, even if it has a dummy value. For example:
{'method' : 'POST', 'contentType' : 'xml', 'postData' : 'value1'}
You can use 'authenticationType' in the parameters field to indicate the content's authentication type. The possible values are 'signed', 'authenticated', or 'none', which is the default. For example:
{ 'authenticationType' : 'authenticated' }
When you use the 'feed' content type, makeRequest() fetches the content as an RSS or Atom feed and returns the core feed data as a JSON object. JSON (JavaScript Object Notation) is a simple way of describing data as JavaScript. For more discussion of this topic, see the Google Gadgets API Developers Guide.
For example:
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Fetch">
<Require feature="opensocial-0.6"/>
</ModulePrefs>
<Content type="html">
<![CDATA[
<div id="content_div"></div>
<script type="text/javascript">
opensocial.makeRequest("http://opensocialapis.blogspot.com/atom.xml",
function(feed) {
var html= "";
// Access the fields in the feed
html += "<div><b>" + feed.Title + "</b></div>";
html += "<div>" + feed.Description + "</div><br>";
document.getElementById('content_div').innerHTML = html;
}, {'method' : 'GET', 'contentType' : 'feed', 'numEntries' : '5', 'getSummaries' : 'true'});
</script>
]]>
</Content>
</Module>
Note the parameters:
{'method' : 'GET', 'contentType' : 'feed', 'numEntries' : '5', 'getSummaries' : 'true'}
For the feed content type, you can include the following parameters:
numEntries is the number of feed entries to retrieve from the feed.getSummaries indicates whether to retrieve the full text summaries for the entries in the feed. This defaults to false. You should only set this to true if you plan to use the data. The full summaries can be quite large and shouldn't be transferred needlessly. The OpenSocial API supports permission control in applications. When an application uses a data request to fetch a viewer from the server, it is only returned if that application has access. If the application does not have access, one of the standard error codes, opensocial.ResponseItem.Error.UNAUTHORIZED, is returned instead. An application can also check ahead of time for its access by using the new opensocial.hasPermission call. If access is denied, you can use opensocial.requestPermission to ask the viewer for the specified permission. Of course, some containers may always grant viewer access, and some may always deny, but this decision is up to the container.
This excerpt illustrates how to use the permission control API:
/**
* Request the VIEWER and OWNER objects
*/
function requestData() {
var req = opensocial.newDataRequest();
req.add(req.newFetchPersonRequest(opensocial.DataRequest.PersonId.OWNER), "owner");
// If we have permission to see the viewer's info, then add it to the request.
if (opensocial.hasPermission(opensocial.Permission.VIEWER)) {
req.add(req.newFetchPersonRequest(opensocial.DataRequest.PersonId.VIEWER), "viewer");
}
req.send(showData);
}
function showData(data) {
var viewer = data.get("viewer").getData();
var owner = data.get("owner").getData();
var ownerOutput = document.getElementById("owner-output");
var viewerOutput = document.getElementById("viewer-output");
showPerson(owner, ownerOutput);
if (opensocial.hasPermission(opensocial.Permission.VIEWER)) {
showPerson(viewer, viewerOutput);
}
}
function requestPermission() {
var reason = "To demonstrate permission capabilities in v0.6";
opensocial.requestPermission(opensocial.Permission.VIEWER, reason, requestData);
}
function showPerson(person, div) {
var name = person.getDisplayName();
var thumb = person.getField(opensocial.Person.Field.THUMBNAIL_URL);
var html = '<img src="' + thumb + '"/>' + name;
div.innerHTML = html;
}
//Execute requestData when the page is done loading
gadgets.util.registerOnLoadHandler(requestData);
To learn more about the OpenSocial API, here are some additional resources: