Streaming API Using JQuery – Salesforce

Push technology is a model of Internet-based communication in which information transfer is initiated from a server to the client. Also called the publish/subscribe model, this type of communication is the opposite of pull technology in which a request for information is made from a client to the server. The information that’s sent by the server is typically specified in advance. When using Streaming API, you specify the information the client receives by creating a PushTopic. The client then subscribes to the PushTopic channel to be notified of events that match the PushTopic criteria.

In push technology, the server pushes out information to the client after the client has subscribed to a channel of information. In order for the client to receive the information, the client must maintain a connection to the server. Streaming API uses the Bayeux protocol and CometD, so the client to server connection is maintained through long polling.

The Bayeux protocol and CometD both use long polling.

  1. Bayeux is a protocol for transporting asynchronous messages, primarily over HTTP.
  2. CometD is a scalable HTTP-based event routing bus that uses an AJAX push technology pattern known as Comet. It implements the Bayeux protocol.

There is nice jQuery plugin available on web which implements Bayeux protocol and CometD.

Navigate here for Salesforce documentation for Streaming API.

Common Terms used in Streaming API:

  • Event : Either the creation of a record or the update of a record. Each event may trigger a notification.
  • Notification : A message in response to an event. The notification is sent to a channel to which one or more clients are subscribed.
  • PushTopic : A record that you create. The essential element of a PushTopic is the SOQL query. The PushTopic defines a Streaming API channel.

Example used in this article :

I want notifications about all opportunity whose status is won.
First step to implement any streaming API is to create the Push Topic, which is going to subscribed by all the clients.

Create PushTopic:

To create PushTopic, we will need the developer console of the Salesforce and assume that the name of the topic is “WonOpportunity”.

PushTopic pushTopic = new PushTopic();
pushTopic.ApiVersion = 23.0;
pushTopic.Name = 'WonOpportunity';
pushTopic.Description = 'Notify if the Opportunity won';
pushTopic.NotifyForOperations = 'All';
pushTopic.NotifyForFields = 'Referenced';
pushtopic.Query = 'Select o.OwnerId, o.Name, o.IsWon, o.Id, o.Amount From Opportunity o WHERE o.IsWon = true';
insert pushTopic;
System.debug('Created new PushTopic: '+ pushTopic.Id);
Salesforce Streaming API - Create Push topic
Salesforce Streaming API – Create Push topic

Step 2:
Download the CometD compressed archive (.tgz) file from http://download.cometd.org/cometd-2.2.0-distribution.tar.gz

Step 3:
In the extracted folder you will find the war file at location “cometd-2.2.0/cometd-javascript/common/target”.

Unpack that war file using below DOS command in Windows and same command will work on shell also

cd cometd-2.2.0/cometd-javascript/common/target
jar xvf cometd-javascript-common-2.2.0.war org/cometd.js
Salesforce UnPack war file - Streaming API
Salesforce UnPack war file – Streaming API

If you will not follow the above step and if use different “cometd.js” file then you may get error “Uncaught ReferenceError: org is not defined”

Step 4:
Extract the following JavaScript files from “cometd-2.2.0-distribution.tar.gz

  • cometd-2.2.0/cometd-javascript/common/target/org/cometd.js (This file must be from war file)
  • cometd-2.2.0/cometd-javascript/jquery/src/main/webapp/jquery/jquery-1.5.1.js
  • cometd-2.2.0/cometd-javascript/jquery/src/main/webapp/jquery/json2.js
  • cometd-2.2.0/cometd-javascript/jquery/src/main/webapp/jquery/jquery.cometd.js

Step 5:
Create a Visualforce page with following code :

<apex:page >

<apex:includeScript value="{!URLFOR($Resource.SteamingAPI, 'StreaminAPI/JQueryComet/Cometd.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.SteamingAPI, 'StreaminAPI/jquery_1.5.2.min.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.SteamingAPI, 'StreaminAPI/JQueryComet/json2.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.SteamingAPI, 'StreaminAPI/JQueryComet/jquery.cometd.js')}"/>

<apex:includeScript value="{!URLFOR($Resource.SteamingAPI, 'StreaminAPI/Style/jquery-animate-css-rotate-scale.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.SteamingAPI, 'StreaminAPI/Style/jquery-css-transform.js')}"/>

<apex:stylesheet value="{!URLFOR($Resource.SteamingAPI, 'StreaminAPI/Style/style.css')}"/>

<div class="menu">
<!-- Place holder for notifications -->
</div>

	 <script type="text/javascript">
	    var $jq = jQuery.noConflict();

            $jq('.item').click(
                function(){
                    var $this = $jq(this);
                    expand($this);
                }
            );
            function expand($elem){
                var angle = 0;
                var t = setInterval(function () {
                    if(angle == 1440){
                        clearInterval(t);
                        return;
                    }
                    angle += 40;
                    $jq('.link',$elem).stop().animate({rotate: '+=-40deg'}, 0);
                },10);
                $elem.stop().animate({width:'500px'}, 1000)
                .find('.item_content').fadeIn(400);
            }

           function createEle(data)
           {
	           	var $itemDiv = $jq(document.createElement('div'));
	           	$itemDiv.addClass('item');

	           	var $anch =  $jq(document.createElement('a'));
	           	$anch.addClass('link');
	           	$anch.addClass('icon_alert');

	           	var $contentDiv = $jq(document.createElement('div'));
	           	$contentDiv.addClass('item_content');

	           	var $h2 = $jq(document.createElement('h2'));
	           	$h2.html('Won New Opportunity');
	           	$contentDiv.append($h2);

	           	$contentDiv.append('<br />Name : '+data.Name+' <br />	Amount : '+data.Amount+' <br /><a href="#"> Navigate to Opportunity </a>');

	           	$itemDiv.append($anch);
	           	$itemDiv.append($contentDiv);
	           	$jq(".menu").append($itemDiv);
	           	expand($itemDiv);
           }

           $jq(function() {
			 	 // Connect to the CometD endpoint

	            $jq.cometd.init({
	               url: window.location.protocol+'//'+window.location.hostname+'/cometd/23.0/',
	               requestHeaders: { Authorization: 'OAuth {!$Api.Session_ID}'}
	           });

	          $jq.cometd.subscribe('/topic/WonOpportunity', function(message) {
	          		createEle(message.data.sobject);
	            });

			});

        </script>
</apex:page>

After saving this page, open same salesforce instance in other browser or tab and make change to any opportunity with status “won”, it will display an alert that opportunity is won.
Output:

Salesforce Streaming API Example
Salesforce Streaming API Example

JSON Reponse:
following JSON response we gets from Streaming API. The Rows returned in Object depends upon the Push topic create earlier.

[
   {
      "channel":"/topic/WonOpportunity",
      "data":{
         "event":{
            "type":"created",
            "createdDate":"2012-05-05T10:06:45.000+0000"
         },
         "sobject":{
            "Name":"om",
            "IsWon":true,
            "Amount":null,
            "OwnerId":"00590000000Gl5VAAS",
            "Id":"00690000006C8yFAAS"
         }
      }
   },
   {
      "channel":"/meta/connect",
      "advice":{
         "reconnect":"retry",
         "interval":0,
         "timeout":110000
      },
      "successful":true,
      "id":"3"
   }
]

Debugging Streaming API:
We can use “firebug” plugin of Mozilla to check whether the http request is made or not from JQuery (comet). Following screen can give you little idea about the http (XHR) requests made from JQuery .

Firebug Tool - Debugging Streaming API of Salesforce
Firebug Tool – Debugging Streaming API of Salesforce

Download Static Resource used in this article for Streaming API example of salesforce

Output Video of Streaming API:

Posted

in

by


Related Posts

Comments

15 responses to “Streaming API Using JQuery – Salesforce”

  1. Rojalinpdp Avatar
    Rojalinpdp

     Nice post…Thanks 4 sharing

  2. Pawan Avatar
    Pawan

    Awesome yaara !!!!

    1. JitendraZaa Avatar
      JitendraZaa

      Thanks Pawan

  3. Abishekh Avatar
    Abishekh

    Hi, Excellent blog. The code works fine in a visual force page, but it does not work in visual force TAB. Do I need to make some specific changes to make it work in visual force TAB?

  4. Grace Patiño Avatar
    Grace Patiño

    Hi, do you think this work in salesforce1 to made a notification like puch notification? if not, do you know something to do that?

    1. Jitendra Zaa Avatar

      Yeah, It should work but user needs to stay on that VF page.

      1. Anugraha B Avatar
        Anugraha B

        What will happen if user navigates to a different page? Will the connection timeout? If yes, can I capture the timeout and reconnect again when the user comes back?

        1. Jitendra Zaa Avatar

          If navigation is changed and next page also implements streaming API then it will work normally but if next page does not implement streaming API then no one will be subscribing API so it will be ignored.

  5. Nitish Singh Avatar
    Nitish Singh

    https://uploads.disquscdn.com/images/524b0040d08e9568a2a2c3cae0cd01f65f0597c8a2403bf863a3aa5a5def1a52.png

    Great Article. I am facing one issue though. Kindly refer to the attachment. I have subscribed to changes to Contact Object from my vf page. As seen in attachment , I have Cases open which is basically the same vf page which has subscribed to cometD.

    Now when the callback is received it is received across all the Case (encircled in Blue) . How do i prevent this .

  6. pavan kumar Avatar
    pavan kumar

    Hi Jitendra,

    Your post is very nice & worthy.But i setup everything as per your post.But i am not able to get any pop notifications.Even errors also i didn’t get it.

  7. pavan kumar Avatar
    pavan kumar

    Hi Jitendra,

    Best post it is working accurately but i got notifications only in vf page.But if you enable it chrome or other browser notifications it would be really nice.

    Thank you,

  8. vamshi Avatar
    vamshi

    Hi Jitendra,

    I am trying to use your code for my requirement to call a long polling service and i am getting the below error and i am using lightning component for that

    Uncaught ReferenceError: jQuery is not defined

    Below is the sample code that

    component:

    controller.js

    ({
    jsLoaded: function(component, event, helper) {
    $.cometd.init({
    url: ‘https://services/VoiceBiometricsService/rest/VBResource/CometConnectionDetails’,
    requestHeaders: { Authorization: ‘OAuth {!$Api.Session_ID}’}
    });

    }
    })

    Thanks in advance!!

    Regards,
    Vamshi

  9. mekyush Avatar

    This is not working with Platform Event. e.g. if i am Subscribing to /event/

    Will it be possible to subscribe Platform Event using above code??

  10. jc Avatar
    jc

    Hi Jitendra,
    Can we(salesforce) subscribe pushtopics from other salesforce instances? Can we use the same pages to see the events?

    Thanks
    jc

  11. MAthew Avatar
    MAthew

    Thanks a lot for posting this. helped me a lot

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Discover more from Jitendra Zaa

Subscribe now to keep reading and get access to the full archive.

Continue Reading