Quick Demo - Salesforce Platform Events

04:27 0 Comments A+ a-

Hi All,
I am going to show you all a quick demo which I have made using Salesforce Platform Custom Events. Follow below steps:

1) Create Custom Event object:
In setup -> Platform Events -> Create a new object lets say "Opportunity Status Event". Please see below picture for the same.



2) The purpose for this demo is to fire a event as soon as opportunity stage field value changed. So we need to write a trigger on Opportunity object. This trigger will fire a custom event for "Opportunity Status Event" using EventBus.Publish() method. Please check below code:

trigger OpportunityTrigger on Opportunity (after update) { list<Opportunity_Status_Event__e> eventList = new list<Opportunity_Status_Event__e>(); for(Opportunity opp: trigger.new){ if(opp.StageName != Trigger.oldmap.get(opp.id).StageName){ Opportunity_Status_Event__e statusEvent = new Opportunity_Status_Event__e(); statusEvent.record_id__c = opp.id; statusEvent.status__c = opp.StageName; eventList.add(statusEvent); } } if(eventList.size() > 0){ EventBus.publish(eventList); } }

3) Now, as you have created publisher. Now you need to make subscribers.

4) My first subscriber here is VF page called "OpportunityStatus". It shows all opportunity stage names in a graphical way, to make this graphic component, i took help from this site: https://codepen.io/anon/pen/MOJyQN



In this VF page, we need to subscribe our Custom Event which is fired from Opportunity Trigger. For subscribing it, I used "cometd". You can extract this library from internet or you can download all source code from bottom section of this blog. Please see following code:

<apex:page standardController="Opportunity" sidebar="false" extensions="OpportunityStatusController"> <script src="{!URLFOR($Resource.cometd,'cometd/cometd.js')}"/> <script src="{!URLFOR($Resource.cometd,'cometd/jquery-1.5.1.js')}"/> <script src="{!URLFOR($Resource.cometd,'cometd/json2.js')}"/> <script src="{!URLFOR($Resource.cometd,'cometd/jquery.cometd.js')}"/> <apex:sectionHeader title="Opportunity Stage" subtitle="Indicator"/> <style> /* Form Progress */ .progress { text-align: center; } .progress .circle, .progress .bar { display: inline-block; background: #fff; width: 40px; height: 40px; border-radius: 40px; border: 1px solid #d5d5da; } .progress .bar { position: relative; width: 110px; height: 6px; margin: 0 -5px 17px -5px; border-left: none; border-right: none; border-radius: 0; } .progress .circle .label { display: inline-block; width: 32px; height: 32px; line-height: 32px; border-radius: 32px; margin-top: 3px; color: #b5b5ba; font-size: 17px; } .progress .circle .title { color: #b5b5ba; font-size: 13px; line-height: 30px; margin-left: -18px; } /* Done / Active */ .progress .bar.done, .progress .circle.done { background: #eee; } .progress .bar.active { background: linear-gradient(to right, #EEE 40%, #FFF 60%); } .progress .circle.done .label { color: #FFF; background: #8bc435; box-shadow: inset 0 0 2px rgba(0,0,0,.2); } .progress .circle.done .title { color: #444; } .progress .circle.active .label { color: #FFF; background: #0c95be; box-shadow: inset 0 0 2px rgba(0,0,0,.2); } .progress .circle.active .title { color: #0c95be; } .title{ white-space: nowrap; } </style> <div class="progress"> <apex:variable value="{!1}" var="index"/> <apex:repeat value="{!stageValues}" var="stage"> <div class="circle"> <span class="label">{!index}</span> <span class="title">{!stage}</span> <apex:variable value="{!index+1}" var="index"/> </div> <apex:outputPanel rendered="{!stage != 'Closed Won'}" styleClass="bar done"></apex:outputPanel> </apex:repeat> </div> <script> var i = 0; $('.progress .circle').removeClass().addClass('circle'); $('.progress .bar').removeClass().addClass('bar'); $(".progress .circle").each(function( index ) { if($(this).find(".title").text() == "{!currentStatus}"){ $(this).addClass("active"); i = 1; }else if(i == 0){ $(this).addClass("done"); } }); var j$ = jQuery.noConflict(); j$(document).ready(function() { j$.cometd.init({ url: window.location.protocol+'//'+window.location.hostname+'/cometd/41.0/', requestHeaders: { Authorization: 'OAuth {!$Api.Session_ID}'} }); j$.cometd.subscribe('/event/Opportunity_Status_Event__e', function(message) { if(message.data.payload.Record_Id__c == "{!oppId}"){ j$('.progress .circle').removeClass("active"); j$('.progress .circle').removeClass("done"); i = 0; j$(".progress .circle").each(function( index ) { if(j$(this).find(".title").text() == message.data.payload.Status__c){ j$(this).addClass("active"); i = 1; }else if(i == 0){ j$(this).addClass("done"); } }); } }); }); </script> </apex:page>
In above code, you can see, as soon as it receives a event, it changes the indicator values on progress bar.

5) My second subscriber here is another VF page called "OpportunityStatusGraph". It shows current stage of opportunity in  a CSS Circle format with different colors.



It uses same way for subscribing event using "cometd" plugin. See the below code:

<apex:page standardController="Opportunity" sidebar="false" extensions="OpportunityStatusController"> <script src="{!URLFOR($Resource.cometd,'cometd/cometd.js')}"/> <script src="{!URLFOR($Resource.cometd,'cometd/jquery-1.5.1.js')}"/> <script src="{!URLFOR($Resource.cometd,'cometd/json2.js')}"/> <script src="{!URLFOR($Resource.cometd,'cometd/jquery.cometd.js')}"/> <apex:sectionHeader title="Opportunity Stage" subtitle="Indicator"/> <style> .circle { width: 300px; height: 300px; border-radius: 50%; font-size: 25px; color: #fff; line-height: 300px; text-align: center; background: #d9534f; } </style> <div class="circle">{!currentStatus}</div> <script> $(document).ready(function() { setcolor( $(".circle").text()); $.cometd.init({ url: window.location.protocol+'//'+window.location.hostname+'/cometd/41.0/', requestHeaders: { Authorization: 'OAuth {!$Api.Session_ID}'} }); $.cometd.subscribe('/event/Opportunity_Status_Event__e', function(message) { if(message.data.payload.Record_Id__c == "{!oppId}"){ $(".circle").text(message.data.payload.Status__c); setcolor( $(".circle").text()); } }); }); function setcolor(circolor){ if(circolor == 'Prospecting') $(".circle").css("background-color","#f7f7f7"); else if(circolor == 'Qualification'){ $(".circle").css("background-color","#0275d8"); }else if(circolor == 'Needs Analysis'){ $(".circle").css("background-color","#5bc0de"); }else if(circolor == 'Value Proposition'){ $(".circle").css("background-color","#f0ad4e"); }else if(circolor == 'Perception Analysis'){ $(".circle").css("background-color","#d9534f"); }else if(circolor == 'Negotiation/Review'){ $(".circle").css("background-color","#292b2c"); }else if(circolor == 'Closed Won'){ $(".circle").css("background-color","#5cb85c"); } } </script> </apex:page>


5) This is the Apex Class code. This is straight forward code:

public class OpportunityStatusController{ public string oppId {get;set;} public string currentStatus {get;set;} public OpportunityStatusController(ApexPages.standardcontroller sc){ oppId = sc.getRecord().Id; currentStatus = [select id, stagename from opportunity where id=:oppId].StageName; } public List<String> getStageValues(){ Schema.DescribeFieldResult fieldResult = Opportunity.StageName.getDescribe(); List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues(); List<String> options = new List<String>(); for( Schema.PicklistEntry f : ple){ options.add(f.getValue()); } return options; } }

Now, to see full demo of this functionality, check the video below:




Now, you can see, in salesforce we can fire any type of custom event using Platform Events feature. We can also have external apps or websites, which can subscribe these events and updates contents automatically. Like we can have custom web page on heroku or amazon or mobile app window which can subscribe these custom events and listen it.

We can think many other ways or ideas where we can utilize this amazing feature of salesforce.

Comment or drop email if you have any question or suggestion on this.

Downloads:
Static Resources

Thanks