0

I have been through the Salesforce streaming API demo, and got that working.

For anyone wanting a reminder, the page looks like this

<apex:page >
    <apex:includeScript value="{!$Resource.cometd_js}"/>
    <apex:includeScript value="{!$Resource.jquery}"/>
    <apex:includeScript value="{!$Resource.json2_js}"/>
    <apex:includeScript value="{!$Resource.jquery_cometd}"/>

    <script type="text/javascript">
        (function($){
            $(document).ready(function() {
                // Connect to the CometD endpoint
                $.cometd.init({
                    url: window.location.protocol+'//'+window.location.hostname+'/cometd/24.0/',
                    requestHeaders: { Authorization: 'OAuth {!$Api.Session_ID}'}
                });

                // Subscribe to a topic. JSON-encoded update will be returned in the callback
                $.cometd.subscribe('/topic/InvoiceStatementUpdates', function(message) {
                    $('#content').append('<p>Notification: ' +
                        'Channel: ' + JSON.stringify(message.channel) + '<br>' +
                        'Record name: ' + JSON.stringify(message.data.sobject.Name) +
                        '<br>' + 'ID: ' + JSON.stringify(message.data.sobject.Id) + 
                        '<br>' + 'Event type: ' + JSON.stringify(message.data.event.type)+
                        '<br>' + 'Created: ' + JSON.stringify(message.data.event.createdDate) + 
                        '</p>');
                });
            });
        })(jQuery)
        function disconnect() {
           $.cometd.disconnect();
        }
        window.onbeforeunload = disconnect;
    </script>
    <body>
        <div id="content">
            <h1>Streaming API Test Page</h1>
            <p>This is a demonstration page for Streaming API. Notifications from the InvoiceStatementUpdates channel will appear here...</p>
        </div>
    </body>
</apex:page>

Now I wanted to use this in Lightning components. According to a reply by Skip Sauls here, it's supposedly doable.

This is what I have in my lightning app

<aura:application>
    <ltng:require styles=""
        scripts="/resource/cometd_js,/resource/jquery,/resource/json2_js,/resource/jquery_cometd"
        afterScriptsLoaded="{!c.setupJs}" 
    />

    <div aura:id="content">
        list:
    </div>
</aura:application>

And this is the associated controller:

({
    myAction: function(component, event, helper) {
    },

    setupJs: function() {
        // Connect to the CometD endpoint
        $.cometd.init({
            url: window.location.protocol+'//'+window.location.hostname+'/cometd/24.0/',
            requestHeaders: { Authorization: 'OAuth {!$Api.Session_ID}'}
        });

        // Subscribe to a topic. JSON-encoded update will be returned in the callback
        $.cometd.subscribe('/topic/InvoiceStatementUpdates', function(message) {
            $('.content').append('<p>Notification: ' +
                'Channel: ' + JSON.stringify(message.channel) + '<br>' +
                'Record name: ' + JSON.stringify(message.data.sobject.Name) +
                '<br>' + 'ID: ' + JSON.stringify(message.data.sobject.Id) + 
                '<br>' + 'Event type: ' + JSON.stringify(message.data.event.type)+
                '<br>' + 'Created: ' + JSON.stringify(message.data.event.createdDate) + 
                '</p>');
        });
    }
})

And lastly, this is the error I am receiving in the Chrome console log when the page loads:

POST https://smlt-dev-ed.lightning.force.com/cometd/24.0/ 401 (Unauthorized)

Now, I know that the cometd/24.0 endpoint in my VF page was preceded by a different base URL. My question is whether the Lightning supports using the streaming API, and if so, what changes do I make to my component to get it to work?

  • I tried hard-coding this, to use the URL that my VF page was using. The error was expected, but here it is anyway: Refused to connect to 'https://smlt-dev-ed.my.salesforce.com/cometd/24.0/' because it violates the following Content Security Policy directive: "connect-src 'self'". Not sure where to go from here :( – smatharu Dec 3 '15 at 12:01
  • I want to warn you that this code has several cross site scripting vulnerabilities. You will need to html encode the data if you use jquery append, and this will require using another library. Alternately, build up your dom with setAttribute. – Robert Sussland Dec 3 '15 at 17:30
  • Yep I thought as much that Robert, thanks. The reason for that is that I've just copied the salesforce boilerplate code so I can get it working. I'll happily make it more secure once I know that functionally, the Streaming API can actually be used in lightning components :( – smatharu Dec 4 '15 at 9:27
  • Yes. Unfortunately the Salesforce sample code in the Ajax Toolkit (as well as other workbooks) have XSS, CRUD/FLS, and sharing vulnerabilities in their sample code. There is ongoing work to review the code and update it in the workbooks, but for the moment, please consult the secure coding guidelines: developer.salesforce.com/page/Secure_Coding_Guideline for the most up to date security information, rather than the workbooks. The coding guideline XSS section explicitly talks about the Ajax Toolkit. – Robert Sussland Dec 7 '15 at 1:12
  • 1
    This article may be relevant to your interests: blog.enree.co/2016/03/salesforce-streaming-api-on-demand.html – Mike Tetlow Apr 4 '16 at 13:36
0

As per @mike-tetlow 's answer and link, there isn't currently a lightning way to get the session ID, so we have to resort to fetching it via an Apex controller.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.