Andy in the Cloud

From BBC Basic to Force.com and beyond…


17 Comments

Introducing the LittleBits Connector for Salesforce

As those of you know that follow my brickinthecloud.com blog, i love using API’s in the cloud to connect not only applications, but devices. Salesforce themselves also share this passion, just take a look at their Internet of Things page to see how it can improve your business and the work Reid Carlberg is doing.

LittleBitsWithEV3When Salesforce sent me a LittleBits Cloud Starter Kit as Christmas present i once again set about connecting it to my favourite cloud platform! This blog introduces two new GitHub repos and a brand new installable package to allow you to take full advantage of the snap-not-solder that LittleBits electronics brings with the Salesforce clicks-not-code design model! So if your not an electronics whiz or coder, you really don’t have any excuses for not getting involved! LittleBits provides over 60 snap together components, to build automated fish feeders, to home security systems and practically anything else you can imagine!

cloud_diagram2The heart of the kit is a small computer module, powered by a USB cable (i plugged mine into my external phone battery pack!). It boots from an SD card and uses an onboard USB Wifi adapter to connect itself to the internet (once you’ve connected it to your wifi). After that you send commands to connected outputs to it via a mobile site or set of LittleBits Cloud API’s provided. So far i have focused on sending commands to the outputs (in my case i connected the servo motor), however as i write this i’m teaming up with Cory Cowgill who has also starting working with his kit from an inputs perspective (e.g. pressing on a button on the device).

Everyone in the Salesforce MVP community was lucky enough to get one of these kits and i wanted to make sure everyone could experience it with the cloud platform we love so much! Sadly right now the clicks-not-code solution IFTTT  (If-This-Then-That) used for controlling LittleBits devices does not fully support Salesforce (there is only a Salesforce Chatter plugin). Borrowing an approach i’ve been using for my Declarative Rollup Summary Tool, i set about building a declarative based tool that would allow the Salesforce admin to connect updates to any standard or custom object record to a LittleBits device!

The result is the LittleBits Connector!

LittleBitsTrigger

Once you have assembled and connected your LittleBits device, go to the Settings page under LittleBits Cloud Control and take note of your Access Token and Device ID. As you can see in the screenshot above enter these in the LittleBits Device section or in the LittleBits API custom setting.

The Trigger section needs only the Record ID of the record you want to monitor and have your device respond to when changes are made. Simply list the field API names (separated by a comma) of those you want the tool to monitor. Next fill in the LittleBits Output section with either literal values (on the left) and/or dynamic values driven by values from the record itself. This gives you quite a lot of flexibility to use Formula Fields for example to calculate the percentage.

Controlling a LittleBits cloud device is quite simple, define the duration of the output (how long to apply a voltage) and the amount of voltage as a percentage. Depending on the output module you’ve fitted, light or motor, the effects differ but the principle is the same. In the motor case, i set mine to Turn mode (see below). Then by applying a duration of 100,000 and a percent the motor turns to a specific point each time. Making it ideal for building pointing devices!

With the help of my wifes crafting skills we set about on a joint Christmas project to build a pointing device that would show the Probability of a given Opportunity in realtime. Though the tool I ended up building can effectively be used with any standard or custom object. I also wanted to use only the modules in the LittleBits Cloud Start Kit. So with Salesforce Org and the tool the Internet of Things is in your hands!

Here is a video of our creation in action…

If you want to have a go yourself follow these steps…

Building your own Opportunity Probability Indicator Device #clicksnotcode

If clicks are more your thing than coding, fear not and follow these simple steps!

  1. Purchase a LittleBits Cloud Connector and follow the onscreen instructions once you have created your LittleBits account here. Complete the tutorial to confirm its connected.
  2. Build the device modules configuration as shown in the picture below. On the servo module, there is a tiny switch, use the small screw driver provided to push it to the down position, to put the servo in “turn” mode.
    LittleBitsDevice
  3. Next the fun bit, construct your pointing device! I’d love to see tweets of everyones crafting skills!
    pointingdevice
  4. Install the latest LittleBits Connector either via clicking the package install links or as code, see GitHub README. The first time you go to the LittleBits Trigger tab, you maybe asked to complete the post install step to configure the Metadata API needed by the tool to deploy the Apex Triggers, complete this step as instructed on screen.
  5. Click New on the LittleBits Trigger tab, complete the LittleBits Trigger record as described above, but of course using a record Id from an Opportunity record in your org then click Save.
  6. Click the Manage Object Trigger button to automatically deploy a small Apex Trigger to pass on updates made to the records to the LittleBits Connector engine.
  7. In Salesforce or Salesforce1 Mobile for that matter, update your Opportunity Stage (which updates the Probability). This results in an Apex Job which typically fires fairly promptly and you should see your device respond! If you don’t see anything change on your device confirm its working via the LittleBits Cloud Control test page, next go to the Setup menu check the jobs are completing without error via the Apex Jobs page.

Using the LittleBits Cloud API from Apex

The above tool was built around an Apex wrapper i have started to build around the LittleBits Cloud API, which is a REST API. With a little more time and help from fellow LittleBits fan Cory, we will update it to support not only controlling devices, but also allow them to feedback to Salesforce. In the meantime if you want to code your own solution directly you can install the library here.

The code is quite simply for now, you can read more about it in the README file.

new LittleBits().getDevice().output(80, 10000);

Whats next?

Well i’m quite addicted to this new device, my Lego EV3 robot might be justified in feeling a little left out, but fear not, i’ll find a way to combine them i’m sure! Next up for the LittleBits Connector is subscribing to output from the device back to Salesforce, possibly calling out to a headless Flow, to keep that clicks not code feel going!


6 Comments

Calling Salesforce API’s from Ant Script – Querying Records

Back in June last year i wrote a blog entitled Look ma, no hands!, its main focus was how to leverage the then new ability to install and uninstall packages via the Metadata API. However there was another goal, that is i wanted to invoke Salesforce API’s using only native Ant script and 100% Java based Apache Ant tasks, so no Java coding or native curl executable invocations. Making the resulting script platform neutral and easier to manage.

In this blog i’d like to talk a little bit more about how it was done and highlight the excellent <http> Ant task from Missing Link (so named since surprisingly Ant has yet to provide a core task for HTTP comms). In addition i wanted share how i was able to recently extend this approach. While working with one of FinancialForce.com‘s new up and coming DevOps team members Brad Slater (also see Object Model Tool).

The goal once again was keeping it 100% Ant, this time invoking the Salesforce REST API to perform queries.

 		<!-- Query -->
 		<runQuery 
 			sessionId="${sessionId}" 
 			serverUrl="${serverUrl}" 
 			queryResult="accounts"
 			query="SELECT Id, Name FROM Account LIMIT 1"/>

As before the new Ant tasks are defined in single XML file, ant-salesforce.xml, you can download the updated version with the new <query> task and easily <import> into your own Ant scripts.

Ant provides an excellent way to encapsulate complex script in components it calls Tasks. You can implement these in Java or Ant script itself, using the <macrodef> Ant task. The following shows how the Salesforce <login> task was built for last years blog. You can see both the <http> and <xmltask> tasks in action.

	<!-- Login into Salesforce and return the session Id and serverUrl -->
	<macrodef name="login">
		<attribute name="username" description="Salesforce user name."/>
		<attribute name="password" description="Salesforce password."/>
		<attribute name="serverurl" description="Server Url property."/>
		<attribute name="sessionId" description="Session Id property."/>
		<sequential>
			<!-- Obtain Session Id via Login SOAP service -->
		    <http url="https://login.salesforce.com/services/Soap/c/29.0" method="POST" failonunexpected="false" entityProperty="loginResponse" statusProperty="loginResponseStatus">
		    	<headers>
		    		<header name="Content-Type" value="text/xml"/>
		    		<header name="SOAPAction" value="login"/>
		    	</headers>
		    	<entity>
		    		<![CDATA[
				    	<env:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
				    	    <env:Body>
				    	        <sf:login xmlns:sf='urn:enterprise.soap.sforce.com'>
				    	            <sf:username>@{username}</sf:username>
				    	            <sf:password>@{password}</sf:password>
				    	        </sf:login>
				    	    </env:Body>
				    	</env:Envelope>
		    		]]>
		    	</entity>
		    </http>
			<!-- Parse response -->
			<xmltask destbuffer="loginResponseBuffer">
				<insert path="/">${loginResponse}</insert>
			</xmltask>
			<if>
				<!-- Success? -->
				<equals arg1="${loginResponseStatus}" arg2="200"/>
				<then>
					<!-- Parse sessionId and serverUrl -->
					<xmltask sourcebuffer="loginResponseBuffer" failWithoutMatch="true">
						<copy path="/*[local-name()='Envelope']/*[local-name()='Body']/:loginResponse/:result/:sessionId/text()" property="@{sessionId}"/>
						<copy path="/*[local-name()='Envelope']/*[local-name()='Body']/:loginResponse/:result/:serverUrl/text()" property="@{serverUrl}"/>
					</xmltask>
				</then>
				<else>
					<!-- Parse login error message and fail build -->
					<xmltask sourcebuffer="loginResponseBuffer" failWithoutMatch="true">
						<copy path="/*[local-name()='Envelope']/*[local-name()='Body']/*[local-name()='Fault']/*[local-name()='faultstring']/text()" property="faultString"/>
					</xmltask>
					<fail message="${faultString}"/>
				</else>
			</if>
		</sequential>
	</macrodef>

The <query> Task further leverages the <http> task to make a call to the Salesforce REST API query end point.

	<!-- Provides access to the Salesforce REST API for a SOQL query -->
	<macrodef name="runQuery" description="Run database query">
		<attribute name="sessionId" description="Salesforce user name."/>
		<attribute name="serverUrl" description="Salesforce url."/>
		<attribute name="query" description="Salesforce password."/>
		<attribute name="queryResult" description="Query result property name"/>
		<sequential>
			<!-- Extract host/instance name from the serverUrl returned from the login response -->
			<propertyregex property="host"
              input="${serverUrl}"
              regexp="^((http[s]?|ftp):\/)?\/?([^:\/\s]+)((\/\w+)*\/)([\w\-\.]+[^#?\s]+)(.*)?(#[\w\-]+)?$"
              select="\3"
              casesensitive="false" />			
			<!-- Execute Apex via REST API /query resource -->
		    <http url="https://${host}/services/data/v29.0/query" method="GET" entityProperty="queryResultResponse" statusProperty="loginResponseStatus" printrequestheaders="false" printresponseheaders="false">
		    	<headers>
		    		<header name="Authorization" value="Bearer ${sessionId}"/>
		    	</headers>
		    	<query>
		    		<parameter name="q" value="@{query}"/>
		    	</query>
		    </http>		
		    <property name="@{queryResult}" value="${queryResultResponse}"/>
		</sequential>
	</macrodef>

When put together the two Tasks work very well together, allowing you to login and pass the resulting Session Id to the query  task, then parse the results according to your needs with a small peace of inline JavaScript to parse the resulting JSON. The user of these tasks is blissfully unaware of some of the more advanced Ant script approaches used to implement them, which is how things should be when providing good Ant tasks.

<project name="demo" basedir="." default="demo">

    <!-- Import login properties -->
    <property file="${basedir}/build.properties"/>    
    <!-- Import new Salesforce tasks -->
    <import file="${basedir}/lib/ant-salesforce.xml"/>
    
    <!-- Query task demo -->	
    <target name="demo">
    
    	<!-- Login -->
 		<login 
 			username="${sf.username}" 
 			password="${sf.password}" 
 			serverurl="serverUrl" 
 			sessionId="sessionId"/>
 			
 		<!-- Query -->
 		<runQuery 
 			sessionId="${sessionId}" 
 			serverUrl="${serverUrl}" 
 			queryResult="accounts"
 			query="SELECT Id, Name FROM Account LIMIT 1"/>
 		
 		<!-- Parse JSON result via JavaScript eval -->
 		<script language="javascript">
			var response = eval('('+project.getProperty('accounts')+')');
			project.setProperty('Name', response.records[0].Name);
			project.setProperty('Id', response.records[0].Id);
		</script>
		
		<!-- Dump results -->
		<echo message="Queried Account '${Name}' with Id ${Id}"/>
		
    </target>   
     
</project>

Here is a more complex example processing more than one record via an Ant marco for each record.

 		<!-- Query -->
 		<runQuery 
 			sessionId="${sessionId}" 
 			serverUrl="${serverUrl}" 
 			queryResult="accounts"
 			query="SELECT Id, Name FROM Account"/>

		<!-- Ant marco called for each Account retrieved -->
	    <macrodef name="echo.account">
	    	<attribute name="id"/>
	    	<attribute name="name"/>
	    	<sequential>
				<!-- Process for each account -->
		    	<echo message="Queried Account '@{name}' with Id @{id}"/>
	    	</sequential>		    	
	    </macrodef> 		
 		
 		<!-- Parse JSON result via JavaScript eval and call above Ant macro -->
 		<script language="javascript">
			var response = eval('('+project.getProperty('accounts')+')');
			for(var idx in response.records)
			{
				var processRecord = project.createTask("echo.account");
                processRecord.setDynamicAttribute("id", response.records[idx].Id);
                processRecord.setDynamicAttribute("name", response.records[idx].Name);
                processRecord.execute();
			}
		</script>

Ant is not just for build systems or developers, it can be used quite effectively for many automation tasks. You could create an Ant script that polls for certain activity in your Salesforce org and invokes some application or more complex process for example. Ant has a huge array of tasks and massive community support, its a good skills to learn for cross platform scripting and i’ve frankly found very little it can do these days.

So you may be wondering, why ever use a Java based Ant task or process again to implement your complex Ant and Salesforce integrations? Well…. you may still want to go down the Java coding route if your needs are more complex or if your not comfortable with Ant scripting. Indeed in the case above, the project morphed into something much more complex and we ended up in Java after all. As always choose your tools for the job according to time, resources, skills and complexity. Hopefully this blog has given you another option in your tool belt to consider!


15 Comments

Super ListView Viewer using Winter’15 ListView API

Salesforce continues its drive to push out great platform API’s, while Winter’15 was a little lighter than usual, the List View API did catch my eye! It’s available currently in SOAP and REST flavours, sadly as yet no Apex, though I’ve seen Salesforce follow up in later releases with Apex support, so fingers crossed! This omission didn’t stop me exploring the REST variant via Visualforce and JQuery!

I’ve written a few applications that leverage List Views to provide a readily available filter criteria for various uses. One approach used the StandardSetController in Apex (via the setFilterId method) and another by reading the object definition (using Metadata API), parsing the List View definition and building my own SOQL query! This later strategy can now be replaced with the new List View API, as amongst giving you the List View definition and the records behind it, you also get hold of the SOQL query Salesforce uses as well!

The REST API version provides the following resources to call..

  • /services/data/v32.0/sobjects/Account/listviews – Lists the List Views associated with the object and their Id’s (click the link to try it out in Developer Workbench!). Documentation here.
    listviewlistviews
  • /services/data/v32.0/sobjects/Account/listviews/{Id}/describe – Returns the definition of the List View and the SOQL! Documentation here.
    listviewdescribe
  • /services/data/v32.0/sobjects/Account/listviews/{Id}/results – Returns the column definitions of the List View and the records it returns. Documentation here.
    listviewresults

While exploring the SOQL used by ListViews, i noticed something i had not seen before in the SOQL syntax, the USING SCOPE clause, also new to Winter’15. Recently View Accounts and My Accounts views leverage this new clause…

SELECT name, site, billingstate, phone, tolabel(type), 
  owner.alias, id, createddate, lastmodifieddate, systemmodstamp 
FROM Account 
USING SCOPE mru 
ORDER BY Name ASC NULLS FIRST, Id ASC NULLS FIRST

The above shows ‘mru’ and the following example shows ‘mine’…

SELECT name, site, billingstate, phone, tolabel(type), 
  owner.alias, id, createddate, lastmodifieddate, systemmodstamp 
FROM Account 
USING SCOPE mine 
ORDER BY Name ASC NULLS FIRST, Id ASC NULLS FIRST

The documentation is a bit weak presently on the other values, this knowledge base article, lists Everything, Mine, Queue, Delegated, MyTerritory, MyTeamTerritory or Team, but not MRU at present.

So to give these API’s a better shake down i decided to flex my JavaScript side this time, knowing that its possible to call these API’s from the Visualforce Domain without issue, its a matter of making a JavaScript call and interpreting the results. Thus Super ListView Viewer was born! With a little help from the frankly amazing JQuery plugin known as DataTable, which replicates as far as I can see the standard List View UI and then some!

This page allows you to select any object and if it has associated List View’s view them!

screenshot

JQuery provices some excellent AJAX support, this code reads the SOQL query and displays it on the page…

// List View describe to take a look at the SOQL!
$.ajax({
	url : '/services/data/v32.0/sobjects/' + objectName + '/listviews/' + listViewId + '/describe', 
	headers : { 'Authorization' : 'Bearer {!$Api.Session_ID}' },
	datatype : 'json', 
	success : function(data, textStatus, jqXHR) {					
		$('#soql').text(data.query);
	}
});

This code builds a regular HTML table and then in a single line turns it into the amazing DataTable, I was quite amazed when i added this library, seriously cool!

// Call the List View API to get the results (also includes column definitions)
$.ajax({
	url : '/services/data/v32.0/sobjects/' + objectName + '/listviews/' + listViewId + '/results', 
	headers : { 'Authorization' : 'Bearer {!$Api.Session_ID}' },
	datatype : 'json', 
	success : function(data, textStatus, jqXHR) {					

		// Clear current List View info
		$('#listview').empty();

		// Create the table and add columns
		var table = $('<table></table>');
		var thead = $('<thead></thead>');
		var theadtr = $('<tr></tr>');					
		table.appendTo('#listview');					
		table.append(thead);
		thead.append(theadtr);
		$.each(data.columns, function(index, column) {
			if(!column.hidden)
				theadtr.append($('<th>' + column.label + '</th>'));
		});

		// Add the rows
		var tbody = $('<tbody></tbody>');
		table.append(tbody);
		$.each(data.records, function(rowIndex, record) {
			var tbodytr = $('<tr></tr>');					
			tbody.append(tbodytr);
			$.each(record.columns, function(colIndex, column) {
				if(!data.columns[colIndex].hidden)
					tbodytr.append($('<td>' +
					 (record.columns[colIndex].value!=null ? 
					  record.columns[colIndex].value : '') + '</td>'));
			});
		});

		// Enhance this boring old HTML table with JQuery DataTable!
		var dataTable = table.DataTable();
	    }
	});
});

You can find the full source code for this here. Of course if you had need to call this API from Apex, you can make an outbound HTTP callout, after having set up the Remote Site to allow Salesforce to call itself…

Enjoy!