function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
jwalshjwalsh 

Trigger on CampaignMember can't update Contact

Hey all,

 

Apex newbie here.  Tried researching this here and through google, can't seem to find an answer.

 

I have a trigger on CampaignMember, after insert.  I'm trying to do a basic lead scoring implementation by counting the number of campaigns that Contacts enter.  I'm writing out values with debug statements and it would seem to me that everything hooks together as it should, but after the event, the Contacts don't retain the values set by the trigger.  Is it that you cannot modify a Contact from a CampaignMember trigger?  If so, is there a place where you can see these types of rules laid out?  I read through all the Trigger documentation in the Apex Developers Guide and can't see any such restrictions.

 

Here's the jist of the code:

 

 

trigger NewCampaignMemberTrigger on CampaignMember (after insert) 
{
    //CampaignHelper and ContactHelper are utility classes that house some convenience methods.  
    //I've outlined the SOQL queries that take place in comments under each call
    Set</*Campaign*/ID> campaignIDs = CampaignHelper.getCampaignIDs(Trigger.new);
        //rolls up Trigger.new[n].campaignID into a Set and returns
    Set</*Contact*/ID> contactIDs = ContactHelper.getContactIDs(Trigger.new);
        //rolls up Trigger.new[n].contactID into a Set (where not null) and returns
    
    Map</*Campaign*/ID, Campaign> campaignMap = CampaignHelper.getCampaignMapByID(campaignIDs);
        //return new Map<ID, Campaign>(
        //  [select id, buyers_cycle_score__c from Campaign where id in: campaignIDs]
        //);
    Map</*Contact*/ID, Contact> contactMap = ContactHelper.getMapByID(contactIDs);
        //return new Map<Id, Contact>(
        //    [select id, AccountId, buyers_cycle_score__c from Contact where id in: contactIDs]
        //);
    List<Contact> updatedContacts = new List<Contact>();
    
    for(CampaignMember cm: Trigger.new)
    {
        if(cm.contactID != null)
        {
            Contact contact = contactMap.get(cm.contactID);
            
            Decimal campaignScore = campaignMap.get(cm.campaignID).buyers_cycle_score__c;
            System.debug('Campaign Score:' + campaignScore);
            //in this example: 5.00
            Decimal existingOpportunityScore = contact.buyers_cycle_score__c == null ? 0 : contact.buyers_cycle_score__c ;
            System.debug('Exist Opportunity Score:' + existingOpportunityScore);
            //in this example: 0.00
            contact.buyers_cycle_score__c = existingOpportunityScore + campaignScore;
            System.debug('Buyers Cycle Score:' + contact.buyers_cycle_score__c);
            //in this example: 5.00
            updatedContacts.add(contact); 
        }
    }
    
    try 
    {
     update updatedContacts;
    }
    catch (DMLException e)
    {
        System.debug('contact update failed: '+e);
     }
}

 

Best Answer chosen by Admin (Salesforce Developers) 
jwalshjwalsh

Appears to be some sort of Heisenbug Uncertainty stuff going on with this one.  As soon as I posted this I went back and did more tests without changing a thing and it works as expected now.