Saturday, January 29, 2011

Integrating Linkedin in your application with java

There are two ways to integrate linkedin in your application.

First one is manually handling every step like oauth authentication, generating signature etc......
Second one is to use Linkedin api java wrapper classes

We will use second method to integrate linkedin in our application.

Linkedin Provides us Linkedin api java wrapper classes for integrating linkedin.
http://developer.linkedin.com/thread/1275 


I am using linkedin-j-1.0.361-binary. There are some classes, interfaces ,,etc. which i have used in following example, for using them you have to add these jars in your class path. So don't forget this.

Here are steps to integrate linkind in 
1- first we need API key & Secret Key.....for getting these two keys you can refer to this page
 http://developer.linkedin.com/docs/DOC-1251.
In our example we will use terms oauth_consumer_key & secret_key for API key & Secret Key respectively...

2-After getting oauth_consumer_key & Secret Key we will first log in to the account which we want to access. Below is the code snippets with explaination....

LinkedInRequestToken requestToken=null;
LinkedInAccessToken accessToken = null;
private static LinkedInApiClient client=null;
private static LinkedInApiClientFactory factory =null;
String accessTokenValue="";
String tokenSecretValue="";
Person profile=null;

LinkedInOAuthService oauthService = LinkedInOAuthServiceFactory.getInstance().createLinkedInOAuthService(oauth_consumer_key, secret_key);

we need a call back url  in our log in process, because after getting log in, the login process of linkedin redirect  us to the call back url. We provide the url of our application as a call back url, so that after log in we can come back to our own application.

String callback="your call back url"; 
requestToken = oauthService.getOAuthRequestToken(callback);
session.setAttribute("requestToken", requestToken);                     

we set the request token in session because we will in need of this after redirecting to the application with the help of call back url. 

String authUrl = requestToken.getAuthorizationUrl();
res.sendRedirect(authUrl);                           

We send request to the authurl, it means to the log in page of linkedin. After inserting  valid credentials to the log in page, linkedin redirects us to the call back url(which i have mentioned earlier). As we are redirected to the call back url, linkedin embeds two parameters in the url. oauth_token & oauth_verifier. Now after coming back to our application we fetch these parameters from request.

String oauth_token=ParamUtil.getString(actionRequest, "oauth_token");
String oauth_verifier=ParamUtil.getString(actionRequest, "oauth_verifier");
requestToken = (LinkedInRequestToken)(session.getAttribute("requestToken"));           //request token is, one we have stored in session

accessToken = oauthService.getOAuthAccessToken(requestToken,oauth_verifier);

Now we have got accesstoken, which we will use in future to fetch results from linkedin. frankly speaking accesstoken is the only way so that linkedin will consider that a valid user is accessing the data. We can also store this access token in our database.

3-Actually log in process has been over. According to the linkedin point of view, a valid user is loggedin to the linkedin.(whose user name & password you have inserted during log in process). So now we will first fetch the user information who is logged in to the linkedin.

factory = LinkedInApiClientFactory.newInstance(oauth_consumer_key, secret_key);
client = factory.createLinkedInApiClient(accessTokenValue, tokenSecretValue);
accessTokenValue=accessToken.getToken();
tokenSecretValue=accessToken.getTokenSecret();
profile=client.getProfileForCurrentUser(EnumSet.of(ProfileField.FIRST_NAME,ProfileField.LAST_NAME,ProfileField.DATE_OF_BIRTH,ProfileField.HEADLINE,ProfileField.INDUSTRY,ProfileField.API_STANDARD_PROFILE_REQUEST,ProfileField.PICTURE_URL,ProfileField.PUBLIC_PROFILE_URL,ProfileField.CONNECTIONS,ProfileField.CURRENT_STATUS,ProfileField.SUMMARY,ProfileField.EDUCATIONS));

In getProfileForCurrentUser(Set<ProfileField> arg0) method we provide a set of those fields which we want to fetch for the loggedin user. Now we have an object of Person class, we can fetch user data with the help of different methods of Person class. as.....

String fName=profile.getFirstName();
String lName =profile.getLastName();

4-As you will open your account in www.linkedin.com you will first see you network updates along with your personal information. So now we are going to fetch network updates of the loggedin user. Below is the code snippet for this...............


Network network =null;
network = client.getNetworkUpdates(EnumSet.of(NetworkUpdateType.ANSWER_UPDATE,NetworkUpdateType.APPLICATION_UPDATE,NetworkUpdateType.CONNECTION_UPDATE,NetworkUpdateType.EXTENDED_PROFILE_UPDATE,NetworkUpdateType.GROUP_UPDATE,NetworkUpdateType.JOB_UPDATE,NetworkUpdateType.PICTURE_UPDATE,NetworkUpdateType.PROFILE_UPDATE,NetworkUpdateType.QUESTION_UPDATE,NetworkUpdateType.RECOMMENDATION_UPDATE,NetworkUpdateType.SHARED_ITEM));


we give an argument(Set) in getNetworkUpdates method. This set contains all the field which we want to include in our result. If you want to fetch only those network updates where someone in the network has updated his/her profile, you can use this code.

network = client.getNetworkUpdates(EnumSet.of(NetworkUpdateType.PROFILE_UPDATE),offset,count);
  
If you want to fetch only those network updates where someone in the network is connected with any other, you can use this code.

network = client.getNetworkUpdates(EnumSet.of(NetworkUpdateType.CONNECTION_UPDATE),offset,count);  
 
Now  we have all the network updates. We can display them seperatly(according to the network update type) or in a single way combindly. We can fetch our intended network updates by  checking the update type. Linkedin provides us a list of network update types & there meaning, you can find it here.
I am getting only to that update where someone in the netowrk of loggedin user is connected to any other(CONN). By going through this you can easily fetch results of other network update types.

Updates updates=network.getUpdates();
String ufName=null;
String ulName=null;
String tfName=null;
String tlName=null;
String updMsg=null;
java.util.List<com.google.code.linkedinapi.schema.Update> update=updates.getUpdateList();
 for(int i=0;i<update.size();i++)
{
        UpdateContent updateContent=update.get(i).getUpdateContent();
        updateType=update.get(i).getUpdateType().value();
        if(updateType.equals("CONN"))
        {
            String id=updateContent.getPerson().getId();
            Person profile2 =     client.getProfileById(id,EnumSet.of(ProfileField.FIRST_NAME,ProfileField.LAST_NAME,ProfileField.HEADLINE,ProfileField.INDUSTRY,ProfileField.API_STANDARD_PROFILE_REQUEST,ProfileField.PICTURE_URL,ProfileField.PUBLIC_PROFILE_URL,ProfileField.CURRENT_STATUS,ProfileField.SUMMARY));
            profile2.getPublicProfileUrl();
            updateContent.getPerson().getPictureUrl();
            ufName=updateContent.getPerson().getFirstName();
            ulName=updateContent.getPerson().getLastName();
            Connections connections=updateContent.getPerson().getConnections();
           List<Person> list=connections.getPersonList();
          for(int k=0;k<list.size();k++)
          {
             
tfName=list.get(k).getFirstName();
             
tlName=list.get(k).getLastName();
           }
           updMsg=" is now connected to ";
           System.out.println(ufName+" "+ulName+" "+updMsg+" "+tfName+ " "+tlName);
}