February 01, 2014

Siebel - Twitter Integration - Part 1: Authentication

This is post is second in series of Siebel Twitter Integration and will talk about logging in to twitter as an application.

Twitter has support two form of authentication, O-Auth Authentication and Application only authentication. For pulling tweets in Siebel we need Application only authentication, luckily which is technically easier than O-Auth and have more generous rate limits.






Before starting with Siebel configuration follow these steps:
  1. Create account on http://dev.twitter.com by agreeing to terms and conditions.
  2. Request to create your access token, and copy your Consumer Key and Consumer Secret.

Now copy paste following code to your repository, I prefer client side scripting as it easy to change.

StringToBase64 encoder

http://www.siebel-tech.com/2013/07/escript-base64-encoder/
This is piece of code is required for encoding the Client Key and Client Secret to Base64 before sending it to twitter. Developers at siebel-tech.com has done wonderful work in converting String to Base64, which saved me lot of time. Thanks Iain.

function StringToBase64(Inputs, Outputs)
{
  // *************************************************************************
  // Purpose: Encodes to a Base64 string
  // Author: Iain Ollerenshaw
  // Date: 30-Jul-2013
  //
  // Inputs: InString - string to be encoded
  // Outputs: Base64String - string in Base64
  //
  // Modification History
  //
  // Date          By                Details
  // 25-Jul-2013   Iain Ollerenshaw   Created
  // 2-Feb-2014    Jim  Updated
  // **************************************************************************

  try
  {

    // Define the Base64 codex
    var sCodex = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    var sOutput = "";
    var sInput = Inputs.GetProperty("InString");
    var iLen = sInput.length;
    // Parse input string
    var iPos = 0;
    while (iPos < iLen)
    {
      var sChr1 = sInput.charCodeAt(iPos);
      iPos++;
      var sChr2 = sInput.charCodeAt(iPos);
      iPos++;
      var sChr3 = sInput.charCodeAt(iPos);
      // Shift bytes
      var iEnc1 = sChr1 >> 2;
      var iEnc2 = ((sChr1 & 3) << 4) | (sChr2 >> 4);
      var iEnc3 = ((sChr2 & 15) << 2) | (sChr3 >> 6);
      var iEnc4 = sChr3 & 63;
      if (isNaN(sChr2))
      {
        iEnc3 = iEnc4 = 64;
      }
      else if (isNaN(sChr3))
      {
        iEnc4 = 64;
      }
      sOutput +=(sCodex.charAt(iEnc1) + sCodex.charAt(iEnc2)+ sCodex.charAt(iEnc3) + sCodex.charAt(iEnc4));
      iPos++;
    }
    Outputs.SetProperty("Base64String", sOutput);  }
  catch(e)
  {    throw(e);  }
}

Get Description / Set Description

This is a small piece of code which helps to get the description of any LOV value, I have used LOV as scratch pad to store access token in this example, I will explain to store an maintain these in custom Twitter dashboard. I thought of saving them in system preferences first, but it only has 100 char limit thus had to switch over to LOV Description column.

function GetDescription (sType,sName)
{
var boListOfVal = TheApplication().GetBusObject("List Of Values");
var bcListOfVal = boListOfVal.GetBusComp("List Of Values");
bcListOfVal.ClearToQuery();   
bcListOfVal.ActivateField("Description");
bcListOfVal.SetSearchSpec("Name",sName);
bcListOfVal.SetSearchSpec("Type",sType);
bcListOfVal.ExecuteQuery();
if(bcListOfVal.FirstRecord()){
return(bcListOfVal.GetFieldValue("Description"));
}else return("none");
}


function SetDescription (sType,sName,sDesc)
{
var boListOfVal = TheApplication().GetBusObject("List Of Values");
var bcListOfVal = boListOfVal.GetBusComp("List Of Values");
bcListOfVal.ClearToQuery();   
bcListOfVal.ActivateField("Description");
bcListOfVal.SetSearchSpec("Name",sName);
bcListOfVal.SetSearchSpec("Type",sType);
bcListOfVal.ExecuteQuery();
if(bcListOfVal.FirstRecord()){
bcListOfVal.SetFieldValue("Description",sDesc);
bcListOfVal.WriteRecord();
}
}
LOVs look like:

Main code for Twitter login is as follows:


//Get Consumer Key and consumer Secret from LOV Description
var sConsumerKey = GetDescription("TWITTER_TOKEN","ConsumerKey");
var sConsumerSecret = GetDescription("TWITTER_TOKEN","ConsumerSecret");

//Encode Key and Secret into Base64
var inp = TheApplication().NewPropertySet();
var op = TheApplication().NewPropertySet();
inp.SetProperty("InString",sConsumerKey + ":" + sConsumerSecret);
StringToBase64(inp,op);


//Use EAI HTTP Transport to call Twitter API to login.
var httpSvc= TheApplication().GetService("EAI HTTP Transport");
var httpIn = TheApplication().NewPropertySet();
httpIn.SetProperty("HTTPRequestURLTemplate","https://api.twitter.com/oauth2/token?grant_type=client_credentials");
httpIn.SetProperty("HTTPRequestMethod","POST");
httpIn.SetProperty("HTTPIsSecureConn","TRUE");
httpIn.SetProperty("HTTPContentType","application/x-www-form-urlencoded;charset=UTF-8");
httpIn.SetProperty("HDR.Authorization","Basic " + op.GetProperty("Base64String"));
httpIn.SetProperty("HDR.Accept-Encoding","identity");
httpIn.SetProperty("HDR.User-Agent","something");
httpSvc.InvokeMethod("SendReceive", httpIn, Outputs);


//Transcode the JSON response into UTF-8
var oTransService = TheApplication().GetService("Transcode Service");
var oTransOutputs = TheApplication().NewPropertySet();
Outputs.SetProperty("ConversionMode", "EncodingToString");
Outputs.SetProperty("TargetEncoding", "UTF-16");
Outputs.SetProperty("SourceEncoding", "UTF-8");
oTransService.InvokeMethod("Convert", Outputs, oTransOutputs);
var sResponse = oTransOutputs.GetValue();


//Convert the JSON response to property set
var oJSONConverter = TheApplication().GetService("EAI JSON Converter");
oJSONConverter.InvokeMethod("JSONToPropSet",oTransOutputs,Outputs);

//extract access_token and clip
var token = Outputs.GetChild(0).GetProperty("access_token");
token = token.substring(1,token.length-1);


//Save the token for future use
SetDescription("TWITTER_TOKEN","EncodedTokenCredentials",token);


This access token will be used in all the future communications with twitter as authorization code.
Post version: Draft :) keep checking for more updates on explanations over the HTTP transport.

6 comments :

  1. Nice article - and great to see my StringToBase64 code being put to good use! Thank you for including the source in full and giving credit - great blogging etiquette! I look forward to reading more of your articles. Oli (siebel-tech.com)

    ReplyDelete
    Replies
    1. Thanks Oli for stopping by. You deserve the credit, it saved me lot of time. Although there was a minor error, which I quickly rectified. Thanks for your effort.. stay tuned for the next post. - Jim

      Delete
  2. Hi Jim,

    Great article and what a help to all of us who are trying to get Siebel do Oauth. Thanks for the JSON converter as well.
    Could you please share the Post version which was in the draft as per you last comment.

    Many Thanks,
    Suraj

    ReplyDelete
    Replies
    1. Hi Suraj, Thanks for your comments,
      Sorry, I stopped this project a long back, I am planning to revisit it with different approach this year. -Jim

      Delete
  3. Hi Jim,

    I was able to do a GET/POST using the bearer token in step 2. Thanks again for this great article.

    Cheers

    ReplyDelete
  4. It is nice article. I am facing issue, during transcode process. And I am always getting error "Transcode Service Error". Any help would be great.

    ReplyDelete