LinkedIn App

Overview

This article demonstrates LinkedIn social Network Applications.

LinkedIn Application

Application developer has to register application in LinkedIn developer site. Since Tizen Web Application is a Mobile Application, user has to provide some dummy redirect url to receive access token required for authentication. After successful registration, developer will receive api key and security key.

Authorization:

oAuth is a authentication protocol allows application to access user data. Today most of the web application using oauth protocol for developing social network apps. More information on LinkedIn Application authorization is found at authorization article. Below code is used to receive access token, which in turn used to get auth token. While requesting for access token, application has to pass api key, secret key and scope. More information on scope is found in the link



function LinkedIn()
{
	ar token = localStorage['LinkedIn_access_token'] ;
	if( token == null )
	{
		window.authWin = window.open("https://www.linkedin.com/uas/oauth2/authorization?response_type=code&client_id=jpud61ec2pbz&scope=r_fullprofile%20r_network%20w_messages%20rw_groups%20r_contactinfo%20rw_nus&state=DCEEFWF45453sdffef424&redirect_uri=http://localhost/linkedIn");
		onitorLinkedInURL() ;
	}
	else
	{
		$.mobile.changePage('#linkedMainPage');
	}
}

After receiving access token, developer has to request for access token which is used for all requests.

function monitorLinkedInURL() {
  window.int = self.setInterval(function () {
  window.authCount = window.authCount + 1;
  if (window.authWin && window.authWin.location) {
	var currentURL = window.authWin.location.href;
	var inCallback = currentURL.indexOf("http://localhost/linkedIn?code");
	url_code = currentURL 
	if (inCallback >= 0) {
		window.clearInterval(int)               
		window.authWin.close();
		handleLinkedInCode();                 
	}
  }
  if (window.authCount > 60) {
	window.authCount  =0;
	window.clearInterval(int)
	window.authWin.close();
  }
}, 50);

}

Home Page

Home update contains network updates from linkedIn User account which includes different types like Application updates, Company Follow updates, Joined a Group..etc for more information is found at link. Application can specify the count of updates in the request also. Below code is used to update Home Page in list as shown in screenshot.

function showFeeds(){
	var requestURL = 'https://api.linkedin.com/v1/people/~/network/updates?' + 'oauth2_access_token='+localStorage['LinkedIn_access_token']  ;
	$.ajax({
		type : "GET",		
		cache : true,
		url : requestURL,
		headers : {
			"x-li-format": "json",			
		},
		success : function(data) {
			console.log("received job data from server");
			var d = '<ul data-role="listview">' ;
			for(var i =0 ; i < data.values.length; i++){
				if( data.values[i].updateType == "JGRP")
				{
					d+=  '<li class="ui-li-has-multiline"><a href="#linkedContactPage">' ;
					if(data.values[i].updateContent.person.pictureUrl != null)
						d+= '<img src='+data.values[i].updateContent.person.pictureUrl +' alt="icon" class="ui-li-bigicon">';
					else
						d+= '<img src=icon.png alt="icon" class="ui-li-bigicon">';
					d+= data.values[i].updateContent.person.firstName + " "  + data.values[i].updateContent.person.lastName ;
					var group =  " joined the Group" ;
					for( var j =0 ; j <data.values[i].updateContent.person.memberGroups._total ; j++)
					{
						group+=  data.values[i].updateContent.person.memberGroups.values[j].name ;
						group+=' ';
					}

					d+= '<span class="ui-li-text-sub">' + group + '</span></a></li>' ;
				}
				else if( data.values[i].updateType == "CONN")
				{
					
				}
				else if( data.values[i].updateType == "MSFC")
				{
					/*code here*/
				}
			} 	
			$("#linkedin_content").empty();
			$("#linkedin_content").append(d).trigger("create").listview( );			

		},
		error : function(data, textStatus) {
			console.log("Failed to get job details") ;
		}
	});

}

Profile Page

User Profile Information is shown in this page which includes name, education, working experience and skill set

function showProfile(){
	$('#share').remove();
	var requestURL = 'https://api.linkedin.com/v1/people/~:(id,picture-url,first-name,last-name,industry,headline,location,current-status,num-connections,summary,positions,educations,volunteer,following,skills)?' + 'oauth2_access_token='+localStorage['LinkedIn_access_token']  ;
	$.ajax({
		type : "GET",		
		cache : true,
		url : requestURL,
		headers : {
			"x-li-format": "json",			
		},
		success : function(data) {
			console.log("received job data from server");
			var d = '<div> <table class="ui-tableBorder"> <tbody> <tr>' ;
			
				if( data.pictureUrl != null)
				d+='<td width="40%"><img src= "http://m.c.lnkd.licdn.com/mpr/mprx/0_SmdaARHbnzX4EiAgfuWjAMU6NthWHLKg77jlAMwVwBqZcTbj3eJGxJ0qsp8BwGlluSIrOOz8JP9n"  width="120px" height="120px" /></td>' ;
				else
					d+='<td width="40%"><img src=' + 'icon.png'+  'width="120px" height="120px" /></td>' ;
				d+= '<td width="60%"><span class="personTitle">' + data.firstName + ' ' +  data.lastName+ '</span></br> <span class="personInfo">' ;
				d+=data.headline + '</span><br> <span 	class="personInfo">' +data.location.name + '</span><br> ' ;
				d+= '<span class="personInfo">'+data.industry +'</span></td> </tr> </tbody> </table></div>' ;
				d+= '<div data-role="collapsible" data-collapsed="true" data-theme="b" data-content-theme="d"> <h2>Experience</h2>' ;
				d+= '<ul data-role="listview" data-theme="c" data-dividertheme="d" ">';
				for( var j=0; j < data.positions.values.length; j++)
				{
					d+= '<li> <div> <h3>' + data.positions.values[j].title+'</h3> <p>' + data.positions.values[j].company.name+'</p> <p>' ;
					d+= data.positions.values[j].startDate.month+'/'+ data.positions.values[j].startDate.year  ;
					var str = data.positions.values[j].isCurrent ;
					if( str == "true")
						d+= '- Present'+'</p>';
					else
						{
						if( data.positions.values[j].endDate != null)
							d+= '- '+ data.positions.values[j].endDate.month+'/'+ data.positions.values[j].endDate.year +'</p>' ;
						}
					d+= '<p>' + data.positions.values[j].summary + '</p> </div> </li>' ;

				}
				d+='</ul></div>';
				
				//Education
				d+= '<div data-role="collapsible" data-collapsed="true" data-theme="b" data-content-theme="d"> <h2>Education</h2>' ;
				d+= '<ul data-role="listview" data-theme="c" data-dividertheme="d" ">';
				for( var j=0; j < data.educations.values.length; j++)
				{
					d+= '<li> <div> <h3>' + data.educations.values[j].schoolName+'</h3> <p>' + data.educations.values[j].degree+'</p> <p>' ;
					d+= data.educations.values[j].startDate.year  ;
					d+= '- '+ data.educations.values[j].endDate.year +'</p>' ;
					d+= '</div> </li>' ;

				}
				d+='</ul></div>';	
				
				//Skills
				d+= '<div data-role="collapsible" data-collapsed="true" data-theme="b" data-content-theme="d"> <h2>Skills</h2>' ;
				d+= '<ul data-role="listview" data-theme="c" data-dividertheme="d" ">';
				for( var j=0; j < data.skills.values.length; j++)
				{
					d+= '<li> <div> <h3>' + data.skills.values[j].skill.name+'</h3>' ;
					d+= '</div> </li>' ;

				}
				d+='</ul></div>';	
				
			$("#linkedin_content").empty();
			$("#linkedin_content").append(d).trigger("create").listview( );			

		},
		error : function(data, textStatus) {
			console.log("Failed to get job details") ;
		}
	});

}

Contacts

Invitations

User can invite contact using email id. The below code posts the json request for sending invitation

function addFriends(){
	
	var requestURL = 'https://api.linkedin.com/v1/people/~/mailbox?' + 'oauth2_access_token='+localStorage['LinkedIn_access_token']  ;
	var email = $('#contact').val();
	$('#contact').val("");
	var postStr = '{ "recipients": {  "values": [ { "person": {  "_path": "/people/email='+ email +'" } ' ;
		postStr+= '}] }, "subject": "Invitation to connect.",  "body": "Say yes!", "item-content":{  "invitation-request":{  "connect-type":"friend"  }  } }' ;
		
		console.log("url"+ postStr ) ;
		$.ajax({
			type : "POST",		
			cache : true,
			data: postStr ,
			url : requestURL,
			headers : {
				"x-li-format": "json",		
				"Content-Type":"application/json",
			},
			success : function(data) {
				$("#notification").css({ display:"block"});
				$('#notification').notification('icon', './icon.png');
				$('#notification').notification('open');
				$('#notification').notification('text', 'Invitation has been sent');
			},
			
			error : function(data, textStatus) {
				$("#notification").css({ display:"block"});
				$('#notification').notification('icon', './icon.png');
				$('#notification').notification('open');
				$('#notification').notification('text', 'Invitation has failed');
			}
		});
}

function showPeople(){

	var that = this;

	var requestURL='https://api.linkedin.com/v1/people/~/connections?'+ 'oauth2_access_token='+localStorage['LinkedIn_access_token'] ;

	console.log("Friends List url"+ requestURL) ;
	$.ajax({
		type : "GET",		
		url : requestURL,
		headers : {
			"x-li-format": "json",			
		},
		success : function(data) {
			console.log("received data from server");
			var d = '<div id="share"> <table> <tbody> <tr>' ;
				d+='<td width="70%"><input type="text" id="contact"  /></td>' ;
				d+='<td width="30%"><div data-role="button" onclick="addFriends()">Invite</div></td></tr></tbody></table></div>';
			    d+= '<ul data-role="listview">' ;
			for(var i =0 ; i < data.values.length; i++){
				currentContent = data.values ;
				console.log("inside each data");
				d+=  '<li class="ui-li-has-multiline"><a href="#linkedContactPage">' ;
				if(data.values[i].pictureUrl != null)
					d+= '<img src='+data.values[i].pictureUrl +' alt="icon" class="ui-li-bigicon">';
				else
					d+= '<img src=icon.png alt="icon" class="ui-li-bigicon">';
				d+= data.values[i].firstName ;
				d+= '<span class="ui-li-text-sub">' + data.values[i].headline + '</span></a></li>' ;
			} 	
			$("#linkedin_content").empty();
			$("#linkedin_content").append(d).trigger("create").listview( );
		},
		error : function(data, textStatus) {
			console.log("Failed to get People status from server "+ textStatus);
		}
	});
}

Groups

Below code is used to retivie the list of groups user has been connected.

function showGroups(){

	var that = this;
	var requestURL = 'https://api.linkedin.com/v1/people/~/group-memberships:(group:(id,name,site-group-url,small-logo-url,relation-to-viewer:(membership-state)),allow-messages-from-members)?' + 'oauth2_access_token='+localStorage['LinkedIn_access_token']  ;
	$.ajax({
		type : "GET",		
		cache : true,
		url : requestURL,
		headers : {
			"x-li-format": "json",			
		},
		success : function(data) {
			console.log("received job data from server");
			var d = '<ul data-role="listview">' ;
			for(var i =0 ; i < data.values.length; i++){
				currentContent = data.values ;
				console.log("inside each data");
				d+=  '<li><a href="#linkedContactPage">' ;
				d+= data.values[i].group.name ;
				d+= '</a></li>' ;
			} 	
			$("#linkedin_content").empty();
			$("#linkedin_content").append(d).trigger("create").listview( );			

		},
		error : function(data, textStatus) {
			console.log("Failed to get job details") ;
		}
	});

}

Screenshots

File attachments: