Creating an Application using LinkedIn Platform in 3 Easy Steps! 4


The LinkedIn API has all sorts of juicy goodness to it, but the authentication and structure take some learning. LinkedIn has created a JS API called Connect to help you get around those things, so that you can focus on the logic and presentation of your application without spending too much time considering the back end.

I made an internal presentation covering this material at LinkedIn on 2/18, which is available in PDF format. This tutorial has also been integrated into the general JSAPI tutorials on the developer portal. That version has a lot less narration and is just about getting the code written and working.

Everyone loves activity streams, so to illustrate the application development process I’m going to walk through the steps needed to create an interactive LinkedIn application. StreamIn’ has a profile badge for the logged in member, a stream of the status updates from members in their network, and the ability to like/unlike particular items.

A note on this tutorial – there is detailed documentation for the JSAPI on the LinkedIn Developer Portal – there are links in the text appropriate, but detailed options aren’t covered here to keep the tutorial reasonably sized. It’s a lot more fun to get started in a framework if you’ve built something from start to finish, and that’s what we’ll do here.

Getting Started

To get started on our exercise, we need a shell for the application.  Here we have a basic layout, with places for the badge and stream to be inserted.

<div id="header"><h1>StreamIN'</h1></div>
  <div id="wrapper">
    <div id="profile">
	    <div id="badge">
	    Profile info goes here!
	    </div>
    </div>
    <div id="stream">
        Stream stuff goes here!
    </div>
    <br clear="both">
    <div id="footer">
    <div id="nav"> [ << ] <a href="Step1.html">[ >> ]</a></div>
</div>

We’ll start with this and build the application in stages.

Step 0: Check out the Console

The Connect framework does all of the authentication work for you, and loads the things you need in order to get things working in your application.  There are various ways to present login options for the member, and you can explore them using the new JSAPI Console.  At the very least you’ll want to explore the Login options (Login Button, Login Button with Events, Login Button Label). The console is an incredibly useful tool!  Take a few moments now to look around and see what it has to offer.  You can even edit the Code section and click “Run” to see how the Results change.

Step 1: Get the Profile

In order to show the user’s profile, we’ll need to do a few things.

  • Import the framework
  • Add a login button
  • Add an API call to get the profile data and display it

I know, that seems like a lot of sub-steps, but it’s really very easy.

Import the Framework

The first thing we need to do when using Connect is get the framework in our page.  In the <head> of the document, we’ll add a small script to grab the framework.  To do this you need to get a LinkedIn API key – if you don’t have one, go ahead and get one and then come back – it doesn’t take long and it’s much more fun to play along than just read about what I did.

Here’s your code. Use your own api_key. “authorize:true” tells the framework to authorize the member if they’ve visited your application before, rather than logging in each time.

<script type="text/javascript" src="http://platform.linkedin.com/in.js">
   api_key: API_KEY
   authorize: true
</script>

Add a Login Button

Let’s add the button at the bottom of the page.  Here’s the code.  No really, this is all there is!  The data-onAuth variable tells the framework to fire the loadData function when the member has been authorized.

<script type="IN/Login" data-onAuth="loadData"></script>

Load the User’s Profile

Here’s the meat of the step – now the framework is in place, so it’s possible to make calls on behalf of the member. When the member has been authorized the loadData() function will be called. This function calls the Profile method. We need a couple of extra fields from that call, so we use .fields to tell the call what to request.  And the .result sets a callback to perform as soon as the call returns.  You can put an anonymous function there (as I have here) or give it the name of another function to process your returned data.

The callback in this case just pulls the user’s information from the result and builds a profile badge, inserting it in the badge <div>.

function loadData() {
// we pass field selectors as a single parameter (array of strings)
IN.API.Profile("me")
   .fields(["id", "firstName", "lastName", "pictureUrl","headline"])
   .result(function(result) {
      profile = result.values[0];
      profHTML = "<p><a href=\"" + profile.publicProfileUrl + "\">";
      profHTML +=  "<img align=\"left\" src=\"" + profile.pictureUrl + "\"></a>";
      profHTML +=  "<a href=\"" + profile.publicProfileUrl + "\">";
      profHTML +=  "<h2>" + profile.firstName + " " + profile.lastName + "</a> </h2>";
      profHTML += "<span>" + profile.headline + "</span>";
$("#badge").html(profHTML);
});
}

This is how that renders – and you can look at the code for this step.

Step 2: Add Share Stream

The member is authorized and we can see their information. The next thing the application needs to do is grab all of the status updates in their network stream and insert the information into the application.

This can be done using the NetworkUpdates function. To restrict the type of update to “STAT” (Status) updates, .params is used. For simplicity we’re using another inline function, which iterates over the updates and builds individual stream items for each one, then injects the html into the stream <div>.

There also needs to be a call to getUpdateStream() in the loadData() function so it gets called after the profile is loaded.

function getUpdateStream() {  
	IN.API.NetworkUpdates()
	.params({type:"STAT"})
	.result(function(result) {
	    var streamHTML = "";
		for (var update in result.values) {
			var thisupdate = result.values[update]
		
			// Build each individual stream update item
			person = thisupdate.updateContent.person
			var thisHTML = "<div class=streamitem>";
			
			// Person's picture,  linked name, and status
			thisHTML += "<img align=\"left\" class=img_border height=\"50\" src=\"" + person.pictureUrl + "\"></a>"; 
			thisHTML += "<a href=\"" + person.publicProfileUrl + "\">";
			thisHTML += "<span class=updater>" + person.firstName + " " + person.lastName + "</span></a>";			
			thisHTML += "<p class=update>" + activateLinks(person.currentStatus) + "</p>"
			thisHTML += "</div>";
			streamHTML += thisHTML
		}
		$("#stream").html(streamHTML);
	});
}

And now we have this. Code is here.

Step 3: Adding Interaction

Reading from the API is all well and good, but it’s pretty hard to make a compelling application if the member can’t do anything with it. Status updates can always be “liked”, so let’s add some like/unlike action to StreamIn’.

This part is a little more complicated. getUpdateStream() needs to be extended to add Like/Unlike buttons, and those buttons have to perform the appropriate action when pressed.

The Connect calls for these buttons are a little trickier. Since there is no Like/Unlike convenience method in Connect, we’ll pass through a raw call to the backend API. For this call, the method needs to be “PUT”, and the body is simply “true” or “false”. There’s an “alert” here to tell the user something happened, and then the stream is reloaded and redisplayed.

Here’s getUpdateStream again, with the newly added code in bold. The first section simply adds a button to the stream item – if the user has not yet liked the item, a Like button is shown. Otherwise, there’s an Unlike button.
The other two functions are event handlers for clicks on these buttons.


function getUpdateStream() {  
	IN.API.NetworkUpdates()
	.params({type:"SHAR"})
	.result(function(result) {
	    var streamHTML = "";
		for (var update in result.values) {
			var thisupdate = result.values[update]
		
			// Build each individual stream update item
			person = thisupdate.updateContent.person
			var thisHTML = "<div class=streamitem>";
			
			// Person's picture,  linked name, and status
			thisHTML += "<div class=updateperson>" ;
			thisHTML += "<img class=img_border align=\"left\" height=\"50\" src=\"" + person.pictureUrl + "\"></a>"; 
			thisHTML += "<a href=\"" + person.publicProfileUrl + "\">";
			thisHTML += "<span class=updater>" + person.firstName + " " + person.lastName + "</a></span>";	
			thisHTML += "<p class=update>" + activateLinks(person.currentShare.comment) + "</p></div>";
						
			// Present a like button
			if (! thisupdate.isLiked) {
				thisHTML += "<div id=button><button class=\"likebutton ui-corner-all\" id=\"" + 
                                thisupdate.updateKey + "\"><img src=\"Thumbs_up.png\"> Like</button></div>"
			} else {
				thisHTML += "<div id=button><button class=\"unlikebutton ui-corner-all\" id=\"" +
                                thisupdate.updateKey + "\"><img src=\"Thumbs_down.png\"> Unlike</button></div>"
			}	
			thisHTML += "</div>";
			
			// Slap this onto the HTML we're building
			streamHTML += thisHTML;
		}
		$("#stream").html(streamHTML);
	});
	
	$( ".likebutton" ).live("click", function() {
		   likeURL = "/people/~/network/updates/key=" + $(this).attr("id") + "/is-liked"
		   IN.API.Raw(likeURL)
			.method("PUT")
			.body("true")
			.result(function(result) {
				alert ("Liked");
				getUpdateStream();
			})
	});	
	
	$( ".unlikebutton" ).live("click", function() {
		   likeURL = "/people/~/network/updates/key=" + $(this).attr("id") + "/is-liked"
		   IN.API.Raw(likeURL)
			.method("PUT")
			.body("false")
			.result(function(result) {
				alert ("Unliked");
				getUpdateStream();
			})
	});	
}

So that’s it. The code for Streamin’ code is here. Now that you’ve gotten an app up and running, check out the docs and see what you can build!