View RSS Feed

Simonds - Discussion on Almost Anything

Saleforce.com APEX - Chatter Trigger Tutorial

Rate this Entry
by , 06-28-2010 at 10:25 AM (7358 Views)
The newest Salesforce.com feature is Chatter. Chatter is a brand new way to collaborate with people at work using your Salesforce.com Organization. Chatter is the Facebook application for the business world. You can follow fellow employees and receive real time updates via email from their chatter feeds. Whether it is an update to an account or opportunity, Chatter works great.

Chatter feeds can be updated using APEX, Salesforce.com's on-demand programming language. By using APEX triggers, a powerful tool that allows for other objects and items to be updated in almost real-time. The following is an APEX Chatter trigger tutorial which performs an update to the Opportunity Chatter feed when someone updates a field on the Opportunity Line Item. Developers can program business logic into APEX triggers, which allows for applications to be developed on the Salesforce platform.

Salesforce has built in governors within their application because it is a multi-tenant platform. One of these governors does not allow for a SOQL (Salesforce Object Query Language) to perform more than 20 queries at a time and will cause an exception to be thrown.

The following APEX Chatter Trigger updates the Opportunity Chatter feed from changes that have occurred on the child object - Opportunity line Item

Code:
trigger new_chatter_update_trigger on OpportunityLineItem (after update) 
{
    //Setup the Feedpost array of items to post to Chatter
    List<FeedPost> posts = new List<FeedPost>();
    
    //Setup the array to hold the ids to Iterate through
    Set<Id> pbeIds = new Set<Id>();
    
    //Iterate through the Line Items
    for (OpportunityLineItem oli : Trigger.new) 
    {   
       // Create individual post
       pbeIds.add(oli.PricebookEntryId);
       pbeIds.add(oli.opportunityId); 
    }
    
    //Setup APEX MAP Arrays to get the required data from the Pricebook and Opportunity 
    Map<Id, PricebookEntry> entries = new Map<Id, PricebookEntry>([select Product2.ProductCode from PricebookEntry where id in :pbeIds]);
    Map<Id, Opportunity> Opp = new Map<Id, Opportunity>([select Account.Name, Account.ID from Opportunity where id in :pbeIds]);
    
    
    //Iterate through the line items once again to add the data to the Chatter Object
    for (OpportunityLineItem oli : Trigger.new)
    {
           OpportunityLineItem oldOLI = Trigger.oldMap.get (oli.id);
           //If the part outcomes are different, let's add to the chatter feed
           if(oli.Part_Outcome__c != oldOli.Part_Outcome__c)           
           {
                  
                  //Let's add the PriceBookEntrty Id to ge the Product name
                  String bodyText = 'has updated the ' +entries.get(oli.Pricebookentryid).Product2.ProductCode+ 
                                    ' from ' +oldOLI.Part_Outcome__c+ ' to ' +oli.Part_Outcome__c+ ' on Account: ' +opp.get(oli.OpportunityId).Account.Name+''; 
                  FeedPost opportunityPost = new Feedpost();    
               opportunityPost.parentId = oli.opportunityId;
               //String bodyText = 'This is the body ';                                                
               opportunityPost.Type = 'LinkPost';
               opportunityPost.Title = '' +entries.get(oli.Pricebookentryid).Product2.ProductCode+ ' socket details';
               opportunityPost.Body = bodyText;
               String id = String.valueOf(oli.Id).substring(0,15);
               opportunityPost.LinkURL = 'https://na2.salesforce.com/' +id;
               posts.add(opportunityPost);
           }
           
           //if the max potential has increased by a million, let's add to the chatter feed
           if(oli.Max_Potential__c >= oldOLI.Max_Potential__c + 1000000)
           {
             decimal NewWholeMaxPotential = oli.Max_Potential__c;
                 decimal maxpotentialdifference = oli.Max_Potential__c/1.0 - oldOLI.Max_Potential__c/1.0;                                                             
                 FeedPost opportunityPost = new FeedPost ();
                 String bodyText = 'has increased the Max Potential of the '
                                   +entries.get(oli.Pricebookentryid).Product2.ProductCode+ ' by $' +maxpotentialdifference+ ' on Account: ' +opp.get(oli.OpportunityId).Account.Name+ '';
                 opportunityPost.Type = 'LinkPost';
                 opportunityPost.Title = ''+entries.get(oli.Pricebookentryid).Product2.ProductCode+' socket details';
                 opportunityPost.Body = bodyText;
                 String id = String.valueOf(oli.id).substring(0,15);
                 opportunityPost.LinkURL = 'https://na2.salesforce.com/'+id;
                 opportunityPost.ParentID = oli.opportunityid;
                 posts.add(opportunityPost);
                
                
               }  
       }    
              
    //if the post is empty, don't try and post it to Chatter    
    if(!posts.isEmpty())
    {
        insert posts;
    }    
    
}
This APEX trigger is called after update, which means that when a user updates the opportunity line item and clicks the save button, the code is invoked. The business logic checks to see if two fields are changed and if the requirements are met, the Chatter feed is updated.

As you can see, the code is clearly noted throughout the trigger explaining which each step is. This is vital incase other developers need to update or change the code later.

I hope this helps others in the community. Many thanks to Will for helping me write and understand the steps it took to get this trigger working. I did receive some guidance from Scott Hemmeter, CEO and founder of the Arrowpointe Corp. He has always been available to help other developers. Thanks Scott I appreciate it!

Enjoy!!

~Mike

Submit "Saleforce.com APEX - Chatter Trigger Tutorial" to Digg Submit "Saleforce.com APEX - Chatter Trigger Tutorial" to del.icio.us Submit "Saleforce.com APEX - Chatter Trigger Tutorial" to StumbleUpon Submit "Saleforce.com APEX - Chatter Trigger Tutorial" to Google

Comments

  1. Michael's Avatar
    Hi,

    In your code I noticed the use of "oldOLI" and then in the if statement after it you used: "oldOli.Part_Outcome__c".
    The same thing for creating the map "Opp" and using "opp.get()".
    Is that a bug or is that code not case sensitive?

    Also, why are you adding IDs from different objects to the same array?
    pbeIds.add(oli.PricebookEntryId);
    pbeIds.add(oli.opportunityId);
    I don't understand why you need to look up the PricebookEntryId in the Opportunity table and vice versa.

    And my last question: Why does the bodyText start with "has"? Is it assumed that the name of the person who triggered the action is prepended to it?

    Thanks in advance,

    Michael
  2. mike's Avatar
    Hi,

    In your code I noticed the use of "oldOLI" and then in the if statement after it you used: "oldOli.Part_Outcome__c".
    The same thing for creating the map "Opp" and using "opp.get()".
    Is that a bug or is that code not case sensitive?

    Good catch Michael that is an error on my part with the case, but this is working in production perfectly and I would assume from that the code is not case sensitive, I would thought it would be, but I guess not


    Also, why are you adding IDs from different objects to the same array?
    pbeIds.add(oli.PricebookEntryId);
    pbeIds.add(oli.opportunityId);
    I don't understand why you need to look up the PricebookEntryId in the Opportunity table and vice versa.

    Because for our particular need, we need to get the Part Name from the Product2 object and you need the PBE Id to get that information


    And my last question: Why does the bodyText start with "has"? Is it assumed that the name of the person who triggered the action is prepended to it?

    Yes it is assumed in this case and works as designed.

    ~Mike

    Thanks in advance,

    Michael
  3. Unregistered's Avatar
    Can Apex Triggers be used based on a Chatter entry? Here's the scenario. Managers want to use the Neglected Accounts report which is based on the Last Activity Date. That date is updated when a user Logs A Call. When Chatter arrived, Reps and CSRs began using Account related Chatter to record phone calls and discussions about the account. So now we have accounts that have a stale Last Activity Date, but in reality there has been a lot of activity visible if you look at the Account's chatter feed. Can we update Last Activity Date when a Chatter entry is made?
  4. mike's Avatar
    Quote Originally Posted by Unregistered
    Can Apex Triggers be used based on a Chatter entry? Here's the scenario. Managers want to use the Neglected Accounts report which is based on the Last Activity Date. That date is updated when a user Logs A Call. When Chatter arrived, Reps and CSRs began using Account related Chatter to record phone calls and discussions about the account. So now we have accounts that have a stale Last Activity Date, but in reality there has been a lot of activity visible if you look at the Account's chatter feed. Can we update Last Activity Date when a Chatter entry is made?
    I am sure they can, even though I have never looked into it. I would look at the new APEX development manual to see if it does. I would think that you could do what you are looking to do
  5. Vidhya's Avatar
    Can we user @Mention to do chatter post from apex code? It is not working as of today. But is there any workaround?
  6. Unregistered's Avatar
    Rather than using:

    opportunityPost.LinkURL = 'https://na2.salesforce.com/'+id;

    I recommend using:

    opportunityPost.LinkURL = URL.getSalesforceBaseUrl().toExternalForm() + '/' + id;
Leave Comment Leave Comment

Trackbacks

Total Trackbacks 0
Trackback URL:

SEO by vBSEO 3.5.2