BizTalk Integrations with Salesforce.com, Part 2

This is a follow up to my original post on setting up SalesForce.com with a custom API to call from BizTalk and leverage some new functionality like the SandBox feature. This time we will focus on setting up BizTalk to call the Web Service we configured earlier.

The source code can be downloaded here.

SalesForce.com Security

Before we start you’ll need the security token that SFDC should have emailed you. You can request it again from the Setup/[My Personal Information]/[Reset your security token].

image
image

We’ll need this to request a SessionID or access token from SFDC before the web service call. Richard Seroter already came up with a solution to this so we’ll just reuse that here.

You’ll also need to download the Enterprise WSDL from force.com.

1.  Logon to SDFC

2.  Navigate to Setup, Develop & API and click on [Generate Enterprise WSDL]

image
image

3.  Save this with the WSDL we generated from the previous post.

4.  Create a Helpers project and add a web reference to using the Enterprise WSDL we just downloaded.

5. Add a class with the following:

///

/// For more information see: http://bit.ly/jKmt73

///

[Serializable]

public

class

ForceToken

{

private

static

DateTime _sessionDate = DateTime.Now;

private

static

string

_sessionId =

string

.Empty;

public

static

string

SessionId

{

get {

return

GetSession(); }

}

private

static

string

GetSession()

{

DateTime now = DateTime.Now;

TimeSpan diff = now.Subtract(_sessionDate);

if

(_sessionId ==

string

.Empty || (diff.Minutes > 60))

{

//TODO lock object during update

//refresh token

System.Diagnostics.EventLog.WriteEntry(

"Utilities"

,

"Salesforce.com Session Refresh"

);

string

uname =

"shaycarl@synthesisconsulting.net"

;

string

password =

"rocktard"

;

string

securityToken =

"vGjbtdjuA7nUCVQSjNYC4SvK4"

;

SFSvcRef.SforceService proxy =

new

SFSvcRef.SforceService();

proxy.Url =

"https://www.salesforce.com/services/Soap/c/20.0"

;

SFSvcRef.LoginResult result = proxy.login(uname, password + securityToken);

System.Diagnostics.EventLog.WriteEntry(

"Utilities"

,

"Salesforce.com Session Refresh completed with id: "

+ result.sessionId);

_sessionId = result.sessionId;

}

return

_sessionId;

}

}

In BizTalk we’re going to call this method from an expression shape. As you can see the tokens expire so we’ll request a new one every hour.

This is where you’ll paste in your security token, username and password. 

BizTalk Orchestration

Next we’ll create an orchestration that calls our custom SFDC API. We’ll cheat a little and just use the messages as defined in the WSDL.

The orchestration will be bound to a receive port (FILE), it’ll call the ForceToken.GetSession() method above, figure out what action is required (update, insert etc) and finally call our API.

1.  To get started we first need to import the custom API WSDL. To do this right click your project and select [Add Generated Item] then choose [Consume WCF Service] and give it the WSDL for our custom API.

image
image

This will create all our schemas, multipart messages, port types and generate a Bindings file that we can use to create our WCF-Custom send port.

image
image

2.  Add an Orchestration to the project and setup a configured receive port and an activating receive shape. This message will just be an XmlDocument so we can generically handle all the API functions.

3.  Next add an expression shape where we’ll call out to get our SessionID. We’re also going to need the root element to determine what API we need to call.

root = xpath(msgIn,

"string(local-name(/*))"

);

sessionId = Sfdc.Helper.ForceToken.SessionId;

4.   Drag on a Decide shape and setup the following branches.

image
image

// Get Branch

root ==

"GetContact"

// Insert Branch

root ==

"AddContact"

// Update Branch

root ==

"UpdateContact"

5.  For each branch we’ll instantiate the appropriate API message and setup the Header with the SessionID.

msgGetContact.parameters = msgIn;

msgGetContact(WCF.Headers) =

""

+ sessionId

+

""

;

This will be the same for each branch except for the Add function. To add a contact we first need to retrieve the AccountID based on the AccountName provided. To achieve this we’ll construct a GetAccountId message, call the API and map the response plus our original request to the InsertContact API message.

msgAddAcct = msgIn;

xmlDoc.LoadXml(

"

"

);

msgGetAcctId.parameters = xmlDoc;

msgGetAcctId.parameters.accountName = msgAddAcct.AccountName;

msgGetAcctId(WCF.Headers) =

""

+ sessionId

+

""

;

image
image

Input Messages

Once you’ve got all this together you should be able to call the SFDC API and start adding contacts. The messages you submit to BizTalk would look something like this:

Insert a contact

<

ns0:AddContact

xmlns:ns0

="http://Sfdc.Bts.AddContact"

>

<

GlobalId

>

Bts1101

GlobalId

>

<

AccountName

>

Synthesis Consulting, Inc

AccountName

>

<

LastName

>

Browning

LastName

>

ns0:AddContact

>

Note: This is a custom message as we need the AccountName not the AccountID

Retrieve a contact

Bts1101

Update a contact

<

ns0:UpdateContact

xmlns:ns0

="http://soap.sforce.com/schemas/class/BtsWebService"

>

<

ns0:globalId

>

Bts1001

ns0:globalId

>

<

ns0:lName

>

Colt

ns0:lName

>

ns0:UpdateContact

>

With the exception of the SessionID it’s all pretty straight forward and even that isn’t terribly difficult. After about an hours work we got our SalesForce.com instance setup with a custom API and developed an integration solution (albeit a very simple solution) using BizTalk, pretty sweet.

Apart from Seroter Steef-Jan Wiggers has a few good posts on integrating with SalesForce.com using BizTalk & MSMQ that is probably worth checking out.