넷로그로 가기

초 남음

Developer / Documentation / OpenSocial tutorial: OpenSocial REST API

When the JavaScript API isn't the best option

A reference of REST calls and URLs can be found on our OpenSocial REST documentation.

This is part 2 of our OpenSocial tutorial. While part 1 focused on building a gadget within Netlog using the OpenSocial JS API, we will now look at the OpenSocial REST API, which may be more suited for certain situations.

The most typical example would be porting an existing web site to an OpenSocial application. While this is trivially done by injecting an iframe in the DOM from your gadget XML, the difficulty comes when you want to add some 'social sauce' to it: reaching out of your iframe to your gadget to do OpenSocial JS calls is... well, messy at best. (Though Gadgets.rpc may get you some results)

No worries though: OpenSocial REST to the rescue! This provides us a way to do social calls using good old HTTP Requests (GET and POST mainly).

Authentication: 2-legged OAuth, 3-legged OAuth and security token

Authentication tackles the following issue: how does the container know that the social requests actually come from your application? Netlog obviously needs to know to what precise app it is 'talking' (e.g. for security).

When it comes to OpenSocial you will often encounter three different 'authentication strategies':

  • OAuth 3-legged - allows an application to get an access token from the container with which it can do calls 'on behalf of a user', after the user gave explicit permission. Typically used for external sites that still want to benefit from the user's identity on the container (i.e. his Netlog profile, friends ...).
  • OAuth 2-legged - similar to 3-legged, but now the application makes itself known to the container beforehand, meaning that we don't have to let the user go trough that entire explicit-authorisation-to-obtain-access-tokens dance all the time: the app identifies itself to Netlog, after which it can freely start doing requests.
  • Security token - by far the easiest one when integrating an application: no exchange of requests whatsoever to obtain an access token. Instead, a temporary security token is passed from the gadget to the application which can be sent along with each request to make it 'authenticated'.

The two OAuth cases are explained well in the OpenSocial wiki. Also, the three typical app cases are compared rather well over here.

We will cover the security token approach. We move on from the end of part 1: working within an iframe that was created in the gadget, and received the JS-generated security token as URL parameter (http://www.myExternalAppSite.com?st=xxxxxxx...).

Below we will show how to build a php class that can make social calls. Note that everything below should be easily transferable to other languages (e.g. ASP).

Preparation: catch language and security token on your end

Catching a URL parameter is best done on the server side, and immediately stored in the session. If you iFrame's src attribute would contain a GET parameter st=someToken in the URL, you would catch it in php as follows:

 $st = $_GET['st'];
 $language = $_GET['language'];
 

... Now the $st variable will contain the security token that will be a parameter in each of your REST calls (HTTP requests).

Also important to receive from the gadget is the language code (e.g. 'en' or 'nl'), as it defines the API URL to point our HTTP requests to:

 $baseUrl = 'http://' . $language . '.api.netlog.com/opensocial/social/rest';

Note: by default Netlog returns data in JSON format, with the requested information under node 'entry'. Send parameter view=xml along with your requests to receive responses in XML instead.

As said, the API works with regular HTTP GET, POST and PUT requests. Click here to see some rudimentary PHP functions one would use for that.

Let us build a class class.osrest.php that joins our opensocial REST calls together. This means the variables and functions will become attributes and methods in the examples below ($this->st, $this->baseUrl etc...).

Fetching viewer info

As you will see, each OpenSocial JS API call has its REST counterpart (indeed in the background those JS functions do AJAX requests using OpenSocial REST, you can follow this with firebug for example).

The following code does a GET request to fetch the viewer's basic profile info including his thumbnail picture location:

 function getViewer()
 {
 $specificPart = '/people/@me/@self'; 
 $params = array(
 'format' => 'json',
 'st' => $this->st,
 'fields' => 'thumbnailUrl'
 ); 
 $completeURL = $this->baseUrl . $specificPart . '?'. http_build_query($params);
 $rawResponse = $this->sendGETRequest($completeURL);
 $response = json_decode(stripslashes($rawResponse), true); 
 return $response['entry'];
 }

The @me in the specific part of the URL stands for the viewer. To fetch (publicly available) info of any other person you could replace it with a userid instead. The fields parameter makes the container return specific fields about the viewer, apart from the default userid, nickname, etc ... See the OpenSocial REST documentation for other parameters and their meaning.

Fetching the viewer's friends

The following code does a GET request to fetch the viewer's friends in json format. It is very similar to the previous call, except that we use @friends now.

Also we explicitly use the (earlier fetched) userid of the viewer in the specific part of the URL, but we may have just as well replaced that with @me.

function getViewerFriends($count = 10, $startIndex=0)
{
 $specificPart = '/people/'. $this->uid.'/@friends'; 
 $params = array(
 'format' => 'json',
 'st' => $this->st,
 'count' =>$count,
 'startIndex' => $startIndex,
 'fields' => 'nickname,thumbnailUrl' //,photos'
 ); 
 $completeURL = $this->baseUrl . $specificPart . '?'. http_build_query($params);
 $rawResponse = $this->sendGETRequest($completeURL);
 $response = json_decode(stripslashes($rawResponse), true); 
 return $response['entry']; 
}

Fetching the viewer's photos

The following code fetches URLs of the viewer's photos in normal format.

$this->debug('getting viewer photos...');
$specificPart = '/mediaitems/'. $this->uid.'/@self'; 
$params = array(
 'format' => 'json',
 'st' => $this->st,
 'albumId' => 0, //gets all of them independent of photo set
 //'count' => 10
 ); 
$completeURL = $this->baseUrl . $specificPart . '?'. http_build_query($params);
$rawResponse = $this->sendGETRequest($completeURL);
$response = json_decode(stripslashes($rawResponse), true); 
return $response['entry']; 

Posting an activity about the viewer

The following code will post an activity about the viewer, so this is a POST instead of a GET request. An activity is an action by the user that can be seen by all his friends, we also call these logs on Netlog. On the site, activity logs of your friends can be seen by clicking the Logs tab. The subtab with 'me' shows your own activities (useful for testing!). An activity consists of a title and a body. The (optional) body field may contain HTML tags like <img />, <a>, <br />...

Note the fix_unicode() function we apply to our parameters before sending them. This resolves some quirky behaviour from php's json_encode() function when it comes to special characters. Here is the definition of that function call:

/*
* these 2 functions fix some quirky behaviour with how json_encode() handles international characters
*/
function replace_unicode_escape_sequence($match) {
 return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UTF-16BE');
}
function fix_unicode($postbody)
{
 $result = preg_replace_callback('/\\\\u([0-9a-f])/i', 'replace_unicode_escape_sequence', $postbody);
 return $result;
}

... And this would be the actual postViewerActivity() function.

public function postViewerActivity($title, $body = '')
{
 $this->debug('posting activity...');
 $specificPart = '/activities/'. $this->uid.'/@self/@app?st=' . $this->st . '&format=json'; 
 //note: just sending params as 'title' and 'body' will result in empty logs, they need
 //to be in an array named activity!
 $activity = array(
 'title' => $title,
 'body' => $body, //note: this can contain HTML like <a>, <img /> and <br /> tags
 ); 
 $params = $activity;
 $completeURL = $this->baseUrl . $specificPart;
 $paramString = json_encode($params);
 $paramString = fix_unicode($paramString);
 $rawResponse = $this->sendPOSTRequest($completeURL, $paramString);
 $this->debug('response:' . $rawResponse);
 $response = json_decode(stripslashes($rawResponse), true); 
 return $response['entry']; 
}

The OpenSocial REST php class

Click here to view the OSRest class created with the examples above. Objects of class OsRest are instantiated with the security token and Netlog language. Based on these, at first the viewer information is fetched right away, and different methods to fetch the viewer friends, pictures, etc, happen by calling different methods of this object (which you may want to store in the session).

Usage example:

 require('class.osrest.php');
 $st = $_GET['st']; //to authenticate for our opensocial REST calls 
 $lan = $_GET['language']; //need this to construct the URL to send our API calls to! 
 $os = new osRest($st,$lan);
 $viewerFriends = $os->getViewerFriendS(); //will return array with viewer's friends
 $postResult = $os->postActivity('activity title', 'activity body'); // will post activity about viewer
Important note: the above class file is very rudimentary and for explanation purposes. Consider using the OpenSocial PHP client library for greater flexibility and the possibility to use 2-legged and 3-legged OAuth.