Logging in to Salesforce from ColdFusion

by

We have been working the last few months on an experiment with Salesforce.com. The code is some of our first to be written almost purely using CFScript and Hibernate. One of our challenges was communicating with Salesforce, in particular, their fairly new REST API. Their API documentation is pretty good, but the one area that was somewhat lacking at the time was how to log in. Once we figured it out, the solution was rather simple, it just took a little while to find the right combination of parameters.

We hope to eventually release our entire CFC for talking with Salesforce, which has a lot of convenience methods to get, set, upsert, and describe Salesforce objects, but for now, here is our code to log in and get an object.

public boolean function logIn() {
	if (variables.token EQ '' OR arguments.force) {
		local.http = new Http(url=variables.salesforceInstance & '/services/oauth2/token',method='post');
		local.http.addParam(type='formField',name='grant_type',		value='password');
		local.http.addParam(type='formField',name='client_id',		value=variables.CLIENTID);
		local.http.addParam(type='formField',name='client_secret',	value=variables.CLIENTSECRET);
		local.http.addParam(type='formField',name='username',		value=variables.USERNAME);
		local.http.addParam(type='formField',name='password',		value=variables.PASSWORD);
		local.http.addParam(type='formField',name='format',		value='json');

		local.httpSendResult = local.http.send();
		local.httpResult = httpSendResult.getPrefix();

		if (StructKeyExists(local.httpResult, "responseHeader")
				&& StructKeyExists(local.httpResult.responseHeader, "status_code")
				&& local.httpResult.responseHeader.status_code EQ 200) {
			local.stringResult = gatherResponseString(local.httpResult);
			//variables.json is an in-house wrapper around 'org.json.simple.JSONValue'. DeserializeJSON may work for you as well
			local.json = variables.json.toObject(local.stringResult);
			variables.token = local.json.access_token;
		} else {
			variables.token = '';
			local.errorString = gatherResponseString(local.httpResult);
			if (StructKeyExists(local.httpResult, "ErrorDetail")) {
				local.errorString &= ", detail: " & local.httpResult.ErrorDetail;
			}
			throw (message='Unable to authenticate to SalesForce: ' & local.errorString, type='lampo.salesforce.loginerror');
		}
	}
}
public any function getObject(required string sfid, required string type, array fields) {
	local.url=variables.salesforceInstance & '/services/data/v' & variables.apiVersion &'/sobjects/'&arguments.type&'/' & arguments.sfid;

	if (NOT isNull(fields) AND ArrayLen(fields) GT 0) {
		local.url = local.url & '?fields=' & ArrayToList(fields);
	}

	return makeJsonGetCall(url=local.url,errorMessage='Unable to find ' & arguments.type & ' with sfid ' & arguments.sfid);
}

/*************** HELPER FUNCTIONS ********************/
private function gatherResponseString(required any httpresult) {
	if (IsBinary(httpResult.FileContent)) {
		return CharsetEncode(httpResult.FileContent, httpResult.CharSet);
	} else {
		return trim(httpResult.FileContent);
	}
}

private any function makeJsonGetCall(required string url, required string errorMessage) {
	local.httpResult = makeCall(arguments.url,'GET',{});

	if (local.httpResult.responseHeader.status_code EQ 200) {
		local.fromJson = variables.json.toObject(gatherResponseString(local.httpResult));
		return local.fromJson;
	} else {
		throw (message=arguments.errorMessage & ' (status: '& local.httpResult.responseHeader.status_code &')',type='lampo.salesforce.objectNotFound')	;
	}
}
private any function makeCall(required string url, required string method,required struct params) {
	local.http = new Http(url=arguments.url,method=arguments.method);
	for (paramType in params) {
		for (paramKey in params[paramType]) {
			if (paramType NEQ 'header' or paramType neq 'Authorization') {
				local.http.addParam(type=paramType,name=paramKey,value=params[paramType][paramKey]);
			}
		}
	}
	local.http.addParam(type='header',name='Authorization',value='OAuth ' & variables.token);
	local.httpSendResult = local.http.send().getPrefix();

	if (local.httpSendResult.responseHeader.status_code EQ 401) {
		throw (message = 'Unable to log into SalesForce: ' & local.httpSendResult.responseHeader.status_code & '('&gatherResponseString(local.httpSendResult)&')',detail=gatherResponseString(local.httpSendResult),type='lampo.salesforce.loginFailure');
	} else {
		return local.httpSendResult;
	}
}
Advertisements

4 Responses to “Logging in to Salesforce from ColdFusion”

  1. Mike Ciesiensky (@mikeciesiensky) Says:

    Hey, this is pretty cool. Thanks for sharing!

  2. Tom Nunamaker Says:

    Nice code.. I’m trying to figure out the salesforce stuff myself so this is great timing. I look forward to seeing more 🙂

  3. Tyler Norris Says:

    Hey guys, are you gonna release the full CFC soon? I’m stuck on upserting and would like to see some code. Thanks!

  4. Dan Watt Says:

    Tyler,

    Here is a GIST containing a somewhat stripped down version of our wrapper code. You do have to provide a JSON implementation to it (we use a wrapper around org.json.simple.JSONValue), and need to insert your Salesforce instance, client id, client secret, username and password.

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


%d bloggers like this: