Google OpenSocial
Business Apps get Social
Google OpenSocial is a set of common APIs that let developers create applications that run across any OpenSocial-compatible site. As one of the initial OpenSocial "containers" or host sites, salesforce.com has been working closely with Google and our partners Theikos and Appirio to rollout an initial set of tools, code and demos on DFC to allow developers to build social apps for the enterprise using the Force.com platform and OpenSocial APIs. We've also open-sourced the Apex container code as a Google Code project so the entire developer community can contribute improvements to it over time. This extends the work Google Resource Center we've done over the past year with Google with their Enterprise, GData, Gears and Gadgets teams - this added capability will spark a whole new category of apps that leverage the Force.com and Google platforms.
The reference implementation is limited to friends of Opportunity, Contact and User, but so much more can be done with the framework provided, the best part is deciding what social knowledge problem you will solve with the example container code as a starting point.
Overview for Force.com Developers
The container developer kit consists of a few S-Controls and S-Control Snippets along with a single Apex Code Web Service class that implements the getFriends() logic at the database level.
You can think of this container as a Javascript framework that communicates with an Apex Code class to expose the social data to the opensocial API. The promise of learn once, write anywhere is carried into the Force.com platform.
Do you need to learn AJAX? No, not really, with just HTML and Javascript you can get your list of friends and activities and display them in a simple S-Control based app. You can put this app anywhere that an S-Control will display.
Do you need to learn Apex Code, no not really, simply install this Apex Code in your Developer or Sandbox edition and try it out with a social gadget app of your own creation.
There is a sample List Friends app included in the source code distribution
Selected Sources
Here is an example of the api as a developer would see it. There are a few things to note, first it is an asynchronous api,
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);
and here is the response handler for our simple list friends app
function onLoadFriends(dataResponse) {
viewer = dataResponse.get('viewer').getData();
var html = 'Friends of ' + viewer.getField('name');
html += ':<br><ul>';
var viewerFriends = dataResponse.get('viewerFriends').getData();
viewerFriends.each(function(person) {
html += '<li>' + person.getField('name') ;
var url = person.getField('pictureUrl');
if (!url) {
url = "http://img3.orkut.com/img/i_nophoto128.gif";
}
html += '<img src="' + url + '" width="100">';
});
html += '</ul>';
document.getElementById('message').innerHTML = html;
};
Including the Apex Container
Besides the get friends functions that you will learn by studying the new API, you will include the single S-Control Snippet into your Social app as you build the S-Control. Here is the Snippet
{!INCLUDE($SControl.Opensocial_Apex_Snippet)} <!-- defines the apex container -->
This snippet contains the required framework to translate the OpenSocial API into the Force.com AJAX
Container source code
Building the container was the most fun part of the project, and it would not have been possible without the power of the Force.com platform. I used the reference container from Google along with our AJAX toolkit to invoke a new Apex Code web service that delivered data from a custom junction object which I created for this project. The new object is, as you may guess, Friend__c and holds a few key fields allowing me to relate friends to other users or contacts, as well as an object, Opportunity that i also added. You can add more objects as you extend this container to meet unique needs of your Social App
Here are a few selected source methods from the main container class, and just a bit of the code that invokes the Friends web service so that you can get an idea of how simple it was to match this opensocial framework with a simple Force.com web service.
opensocial.ApexPerson = function(sobj, opt_fields, opt_isViewer, opt_isOwner) {
this.sobject = sobj; // the sobject from the getFriends() Apex Code web service
this.id = sobj.Id;
if(!this.id && sobj.User__c)
this.id = sobj.User__c;
if(!this.id && sobj.Contact__c)
this.id = sobj.Contact__c;
this.installedApps = [];
this.isViewerObject = true;
this.fields = opt_fields || {};
this.fields.name = sobj.Display_Name__c;
this.fields.email = sobj.Email__c;
this.fields.id = this.id;
this.fields.pictureUrl = sobj.Photo__c;
for(var j in sobj) {
if(typeof(sobj[j])!='function')
this.fields[j] = sobj[j];
}
this.fields[opensocial.Person.Field.ID] = sobj.id;
this.isViewer = opt_isViewer || false;
this.isOwner = opt_isOwner || false;
};
Here is an excerpt which shows the actual call to the Web Service.
case opensocial.DataRequest.RequestType.FETCH_PERSON :
var personId = request.parameters.id;
// for Force.com viewer is owner
if (personId == opensocial.DataRequest.PersonId.VIEWER ||
personId == opensocial.DataRequest.PersonId.OWNER) {
// ajax to the friends webservice running against your customer database
// contacts and users in salesforce become your friends
var apex = sforce.apex.execute('Friends', 'getMe', [] );
var person = new opensocial.ApexPerson(apex[0],null,true,true);
// todo fill in the appFields data at this time, or later?
this.viewer = person;
this.owner = person;
requestedValue = this.viewer;
Apex Code Web Service
Here is just a small part of the Apex Code class that will give you a feel for how friendships and other valuable social relations can be retrieved from the Force.com platform with a simple Apex Web Service
WebService static List<Friend__c> getFriends() {
List <Friend__c> fl = [select id,
f.Contact__r.Photo__c, f.Contact__r.Salutation, f.Contact__r.Name,
f.Contact__r.FirstName, f.Contact__r.LastName,
f.Contact__c, f.Contact__r.Email,
f.User__r.Photo__c, f.User__r.Name, f.User__r.Email
From Friend__c f
where f.ownerid = :UserInfo.getUserId()
or f.User__c = :UserInfo.getUserId()
limit 100];
List <Friend__c> ret = new List<Friend__c>();
for( Friend__c f:fl) {
if(f.Contact__r!=null) { ret.add( contactToFriend( f.Contact__r) ); }
if(f.User__r!=null) { ret.add( userToFriend( f.User__r) ); }
}
return ret;
}
I Want to get started
- The project is online, check out the entry on Google Code
- You will also need, access to Force.com platform. If you do not have a Developer Edition account, signup for free.
more updates as we are able, this is just the beginning. What will you build ?
--Ron Hess (Ron Hess) 11:15, 2 November 2007 (PDT)