Jaggery (What is it?) is a nice platform for creating web sites and mobile applications. I’ve been using it to develop a portal application for WSO2 partners to use. In that application, I use Salesforce as the data store for profile information about our partners, so I thought I’d show how simple it is to connect Jaggery to Salesforce with some example code.
Getting Credentials
First off, I create a little include file that contains the credential information for salesforce. That way I can share the app, without sharing my credential information. Here’s what the file looks like (appropriately anonymized):
salesforcecredentials.jag
<%
// Salesforce logon credentials
var salesforce_username = "jonathan@wso2.com";
var salesforce_password = "mypassword";
var salesforce_security_token = "mysecuritytoken";
var salesforce_url = "mysalesforceurl"
%>
The username and password are assigned when you establish your salesforce account. In Salesforce/Setup/My Personal Information there is a tab labeled “Reset My Security Token”. This will send the security token to your email address and you can paste it into the above structure. The url is found when at Salesforce/Setup/App Setup/Develop/API. Select Generate Enterprise WSDL, save the resulting file, and scroll all the way to the bottom where you will see a <service> named SforceService, and with a soap:address with the url for your organization. Copy and paste that into the structure above. I’m one of our Salesforce administrators, if any of the above directions don’t match what you see ask your administrator for help.
Now you have all the information you need to connect so Salesforce, so lets’ see how to log in.
Logging in
I put the login function in it’s own import file so I can reuse it on any page that requires connecting to salesforce. Here’s the code first, then I’ll walk through how it works.
salesforcelogin.jag:
<%
include("salesforcecredentials.jag");
var ws = require(’ws’);
var salesforce = new ws.WSRequest();
// declare the Salesforce typical namespaces
var ns = new Namespace("urn:enterprise.soap.sforce.com");
var sf = new Namespace("urn:sobject.enterprise.soap.sforce.com");
// Login to salesforce.com, set up session, url, and options for subsequent calls
function salesforceLogin() {
try {
// URL from the enterprise WSDL generated for us by Salesforce.com
var options = new Array();
options.useSOAP = 1.1;
salesforce.open(options, salesforce_url, false);
salesforce.send(
<tns:login xmlns:tns="urn:enterprise.soap.sforce.com">
<username>{salesforce_username}</username>
<password>{salesforce_password}{salesforce_security_token}</password>
</tns:login>
);
var loginResponse = salesforce.responseE4X;
var sessionId = loginResponse.ns::result.ns::sessionId.toString();
var serverUrl = loginResponse.ns::result.ns::serverUrl.toString();
options.SOAPHeaders = [
<tns:SessionHeader xmlns:tns="urn:enterprise.soap.sforce.com">
<sessionId>{sessionId}</sessionId>
</tns:SessionHeader>
];
return {
sessionId : sessionId,
serverUrl : serverUrl,
options : options
}
} catch (e) {
return {error: e};
}
}
Jaggery allows you to declare and add modules, in this case I’m using the WSRequest object and so must declare it using the “require” function. This gives me an object that is similar to the common XMLHTTP browser object but is specifically designed to make communicating in SOAP easier. I’ll new up one of these objects called salesforce which we’ll use for communicating.
Note that I’ve declared salesforce globally, as well as declaring a couple of XML Namespace objects, we’ll talk about that a bit more later. I can use these no only for logging in, but in subsequent calls to salesforce. The login I’ve encapsulated as a function that can be called when a login is required.
The first step is very simple, open the connection to salesforce, using SOAP 1.1 option and the URL we got from the Enterprise WSDL. We’ll construct a payload requesting a login session and send it. This part is pretty cool, as it makes use of E4X, which is supported by this implementation.
E4X, or Ecmascript For XML, adds XML as a native data type within Javascript, making querying and especially constructing XML a real snap! You can see the basic syntax here – just write plain old XML, and use curly braces to insert values into it. Here’s where we insert the username, password, and append the security token to the password field. Couldn’t be simpler right? Well the end result is pretty easy, but I manually trolled through the WSDL and the schemas embedded in it to discover the structures expected by the service – especially where the namespaces appear. That can be a chore, and is the hardest part IMO of connecting to the service in this lean, write-the-message-yourself model.
Once you get the response back, handily parsed into an E4X XML object, it’s fairly easy to extract the necessary values. In E4X you can navigate the XML tree structure easily using “.” notation, just like a hierarchy of Javascript Object properties. However, there is a special syntax for namespaces, and the Salesforce return is full of them. The notation requires that you declare a prefix (see the top of the example), and then use that prefix along with the awkward “::” to qualify the name. I create this by printing out the whole return and writing each step of the query at a time to ensure I’m getting down to the right place. If you’re new to E4X, but familiar with similar technologies like XPath, I recommend a quick read of the tips and tricks I wrote for the WSO2 Mashup Server documentation: E4X Quick Start Guide.
With the logon information in hand, in the form of a session id and a url for the service that will actually serve up my data, I can create some more E4X that represents the SOAP header required by subsequent calls to Salesforce. I stick these prebuilt headers, the session id and the server url in a convenient object that subsequent calls can make. Now we’re ready to actually get some data out of Salesforce!
Performing a Query
Here’s a function to look up information about a Salesforce Contact given an email address. I’ve just included a few key fields, but you can add others at will – look up the field names in the WSDL, or even easier, in the Salesforce “Customize Object” editor.
<%
include("salesforcelogin.jag");
function contactDetails(email) {
try {
var contact = {
email : email
};
var login = salesforceLogin();
// Find the requested Contact account in Salesforce.
salesforce.open(login.options,login.serverUrl, false);
salesforce.send(
<tns:query xmlns:tns="urn:enterprise.soap.sforce.com">
<queryString>SELECT Id, FirstName, LastName, AccountId FROM Contact WHERE email=’{email}’</queryString>
</tns:query>
);
var queryResponse = salesforce.responseE4X;
contact.id = queryResponse.ns::result.ns::records.sf::Id.toString();
contact.first = queryResponse.ns::result.ns::records.sf::FirstName.toString();
contact.last = queryResponse.ns::result.ns::records.sf::LastName.toString();
contact.accountid = queryResponse.ns::result.ns::records.sf::AccountId.toString();
return contact;
} catch (e) {
return {error: e};
}
}
print(contactDetails("jonathan@wso2.com"));
%>
This should all look pretty familiar at this point – login, send a SQL query to find the requested data, and pull it out into a contact object. In this case I’ll just print the results, which will return a JSON string from this page.
Setting values
One more example, pushing data back into Salesforce: the same login, open, send is all the same, but the payload indicates an update operation:
<tns:update xmlns:tns="urn:enterprise.soap.sforce.com">
<tns:sObjects xsi:type="sf:Contact"
http://www.w3.org/2001/XMLSchema-instance"
xmlns:sf="urn:sobject.enterprise.soap.sforce.com">
<sf:Id>{contactId}</sf:Id>
<Assistant>{assistantName}</Assistant>
<Title>{title}</Title>
</tns:sObjects>
</tns:update>
Conclusion
I hope this post shows several useful aspects of Jaggery:
- Specifically connecting with Salesforce
- Using the WSRequest object to connect to SOAP services
- How to leverage E4X to make constructing and querying XML easy and intuitive
- Using import to promote reusable code fragments and simple data structures across pages
Now that I know it’s this easy to build interfaces to simple Salesforce data, I can imagine may other ways to leverage the vital data stored there across our organization. I’m sure you can come up with some great ideas as well!
Please let me know if you have any comments or corrections – the above is based on the Jaggery 0.9 release.
Javascript everywhere
















Posts (RSS)