Dynamic Reporting – Integrating the Force.com Analytics and Streaming APIs

The Analytics API allows you to build web pages that show your report data however you desire, but how do you ensure your users have an up-to-the-second analysis? See how to use the Streaming API to make your data come alive!

Back in September, I explained how to use the Salesforce Analytics API on a Visualforce Page; this time, I’ll show you how to use the Force.com Streaming API to add life to your data.

Let’s say you’ve written a marvelous UI that leverages the Analytics API (or the REST API, or JavaScript Remoting) to present data in a brilliantly digestible format:

Now, this is a snapshot of your analysis – how do you know it’s still current? Enter the Streaming API – our page can subscribe for notifications on changes to the underlying data and prompt the user to rerun the report. Take a look at the page in action:

//www.youtube.com/watch?v=PHM4eycBDK0

Grab the source for the entire page here; I’ll walk through the changes to the static Analytics page from last time.

The Streaming API implements a publish/subscribe model. You (the developer) create a topic based on a SOQL query, and your client app can subscribe for notifications when the results of that query change. So, the first thing I did was to follow the instructions, in the Streaming API Developer’s Guide, on creating a PushTopic record for notifications on any change to Merchandise Name or Quantity fields – the raw data that feeds into my analysis.

This is the code I ran, in the ‘Execute Anonymous’ window of the Developer Console:

PushTopic pushTopic = new PushTopic();
pushTopic.Name = 'MerchandiseUpdates';
pushTopic.Query = 'SELECT Id, Name, Quantity__c FROM Merchandise__c';
pushTopic.ApiVersion = 29.0;
pushTopic.NotifyForOperationCreate = true;
pushTopic.NotifyForOperationUpdate = true;
pushTopic.NotifyForOperationUndelete = true;
pushTopic.NotifyForOperationDelete = true;
pushTopic.NotifyForFields = 'Referenced';
insert pushTopic;

I followed the instructions to test my PushTopic in Workbench. Updating a Merchandise record’s quantity correctly generates a notification:

The first thing my page needs to do is to include the CometD JavaScript libraries:

<apex:includeScript value="{!$Resource.cometd}"/>
<apex:includeScript value="{!$Resource.jquery_cometd}"/>
The following code, in the jQuery $(document).ready() handler, initializes the CometD library and subscribes for notifications on the MerchandiseUpdates topic:
// Initialize CometD
$.cometd.init({
    url: '/cometd/29.0/',
    requestHeaders: { Authorization: 'Bearer {!$Api.Session_ID}'}
});

// Subscribe to a topic. JSON-encoded update will be returned
// in the callback
$.cometd.subscribe('/topic/MerchandiseUpdates', function(message) {
    $('#output').append(JSON.stringify(message, null, '    ')+'\n\n');

    // Prompt user to rerun report
    $("#rerun").show();
});
The #rerun button click handler hides the button and runs the report again:
// Rerun report on click
$("#rerun").click(function(){
    $("#rerun").hide();
    runReport();
});

Why do I show a button rather than simply running the report automatically? Well, running a report is relatively expensive, computationally speaking; it’s wasteful to run the report on every data change, regardless of whether the user is watching or not. So, to be good multi-tenant citizens, we prompt the user to rerun the report.

Are you using the Analytics API yet? Let us know in the comments…

Leave your comments...

Dynamic Reporting – Integrating the Force.com Analytics and Streaming APIs