Tutorial: Post Update on LinkedIn via Scribe using Scala


To post an Update on LinkedIn via your application, that is being built with Play 2.3.x, follow these steps ( this post summarizes the work done step by step).

1) Create a LinkedIn app (if you do not have one already)

Click here – LinkedIn’s Developer Quick Start Guide and create an app. Enter all the details including Site URL. The Site URL could be something like http://www.example.com (but it should be a valid site URL). Also, select the rw_nus setting under the OAuth User Agreement section (otherwise you wont be able to post updates on LinkedIn).

Once you have saved this app, you will get API Key & Secret Key. Take a note of this API Key & Secret Key. We would use them in our code.

2) If you are using Play, then add the API Key, Secret Key & Context URL(Callback URL) in application.conf file.

linkedin.key=<your_key>
linkedin.secret=<your_secret_key>
contextURL="localhost:9000"

3) Download a LinkedIn login image from linkedin.png & save it in “public/images” folder of app

4) Add following dependency in build.sbt (or Build.scala for Play 2.1.x or older versions)

"org.scribe" % "scribe" % "1.3.5"

5) Add following to routes file in conf folder

GET  /linkedin/login     controllers.LinkedInAPIController.linkedinLogin
GET  /linkedin/callback  controllers.LinkedInAPIController.linkedinCallback


6) Let us now create LinkedInAPIController.scala to configure API Key, Secret Key and Callback URL . We would also use this scala file to request access token from LinkedIn & post an update on LinkedIn.

package controllers

import org.scribe.builder.ServiceBuilder
import org.scribe.builder.api.LinkedInApi
import org.scribe.model.OAuthRequest
import org.scribe.model.Response
import org.scribe.model.Token
import org.scribe.model.Verifier
import org.scribe.model.Verb
import org.scribe.oauth.OAuthService
import play.api.Logger
import play.api.Play
import play.api.mvc.Action
import play.api.mvc.Controller

object LinkedInAPIController extends Controller {

 val POST_SUCCESS = 201
 val apiKey: String = Play.current.configuration.getString("linkedin.key").get
 val apiSecret: String = Play.current.configuration.getString("linkedin.secret").get
 val server = Play.current.configuration.getString("contextURL").get
 var requestToken: Token = _

 /**
 * Get OAuthService Request
 */

 def getOAuthService: OAuthService = {
   new ServiceBuilder()
     .provider(classOf[LinkedInApi])
     .apiKey(apiKey)
     .apiSecret(apiSecret)
     .scope("rw_nus")
     .callback(server + "/linkedin/callback")
     .build();
 }

 def linkedinLogin: Action[play.api.mvc.AnyContent] = Action {
   try {
     requestToken = getOAuthService.getRequestToken
     val authUrl: String = getOAuthService.getAuthorizationUrl(requestToken)
     Redirect(authUrl)
     } catch {
       case ex: Exception => {
         Logger.error("Error During Login Through LinkedIn - " + ex)
         Ok(views.html.redirectMain("failure", server, "Cannot post message on LinkedIn"))
   }
  }
 }

 def linkedinCallback: Action[play.api.mvc.AnyContent] = Action { implicit request =>
   try {
     getVerifier(request.queryString) match {
       case None => Ok(views.html.redirectMain("failure", server, "Cannot post message on LinkedIn"))
       case Some(oauth_verifier) =>
         val verifier: Verifier = new Verifier(oauth_verifier)
         val accessToken: Token = getOAuthService.getAccessToken(requestToken, verifier);
         val oAuthRequest: OAuthRequest = new OAuthRequest(Verb.POST, "http://api.linkedin.com/v1/people/~/shares")

         // Posting message on LinkedIn
         val message = "Congratulations! You have posted your first message on LinkedIn via LinkedIn API of Scribe"
         val url = "http://www.knoldus.com/home.knol"
         val xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> \n" +
           "<share> \n" +
           " <comment>" + message +
           "</comment> \n" +
           "<content> \n" +
           "<submitted-url>" + url +
           "</submitted-url> \n" +
           "</content> \n" +
           "<visibility> \n" +
           "<code>anyone</code> \n" +
           "</visibility> \n" +
           "</share>\n"

         //add xml payload to request
         oAuthRequest.addPayload(xml)
         getOAuthService.signRequest(accessToken, oAuthRequest)
         oAuthRequest.addHeader("Content-Type", "text/xml")
         val response: Response = oAuthRequest.send
         response.getCode match {
           case POST_SUCCESS =>
             Ok(views.html.redirectMain("success", server, "Thanks for sharing it with others on LinkedIn"))
           case _ =>
             Ok(views.html.redirectMain("failure", server, "Cannot post message on LinkedIn"))
     }
   }
  } catch {
     case ex: Exception => {
       Ok(views.html.redirectMain("failure", server, "Cannot post message on LinkedIn"))
   }
  }
 }

 def getVerifier(queryString: Map[String, Seq[String]]): Option[String] = {
   val seq = queryString.get("oauth_verifier").getOrElse(Seq())
   seq.isEmpty match {
     case true => None
     case false => seq.headOption
   }
  }

}

7) Now let us create a template redirectMain.scala.html which would show status of clicking “Share on LinkedIn” link.

@(status:String, redirectUrl: String, response: String)

@main("Share on LinkedIn"){

  <script type="text/javascript">
    function close_win(redirectUrl) {
      window.opener.location=redirectUrl
      window.opener.focus();
      window.close();
   }
 $(function() {
   if ('@status' == "success") {
     alert("@response")
     close_win('@redirectUrl');
   } else {
     alert("@response")
     close_win('@redirectUrl');
  }
 });
 </script>

} 

So, this is how we can post updates on LinkedIn via Scribe using Scala & Play.

This entry was posted in Agile, JavaScript, Play Framework, Scala, Web and tagged , , , , , , , , . Bookmark the permalink.

2 Responses to Tutorial: Post Update on LinkedIn via Scribe using Scala

  1. Reblogged this on Play!ng with Scala and commented:

    LinkedIn via Scribe using Scala & Play.

  2. Yogesh says:

    Now Linkedin deprecated rw_nuns, instead of this used w_share check this for more info
    https://developer.linkedin.com/support/developer-program-transition

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s