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
Kevin Charette 8Kevin Charette 8 

update lead when it is added as a campaign member

Hi there. I would like to get a lead to update with the most recent campaign they are a part of. I believe this requires an Apex trigger off the campaign member. My guess something like when campaign member is created > look for lead or contact id> update lead/contact "Most recent Campaign" lookup field witht the campaign ID of the campaign member. While I think that logic seems correct, I do not know apex. Any help would be greatly appreciated!
Best Answer chosen by Kevin Charette 8
Abdul KhatriAbdul Khatri
Here is the code
trigger UpdateMostRecentCampaign on CampaignMember (after insert) {
    
    Map<Id, Id> idContactMap = new Map<Id, Id>();
    Map<Id, Id> idLeadMap = new Map<Id, Id>();
    
    List<Lead> leadToUpdateList = new List<Lead>();
    List<Contact> contactToUpdateList = new List<Contact>();
    
    for(CampaignMember member : trigger.new) {
        
        if(member.LeadId != null)
            idLeadMap.put(member.LeadId, member.CampaignId);
        
        if(member.ContactId != null)
            idContactMap.put(member.ContactId, member.CampaignId);
    }
    
    if(idLeadMap.size() > 0) 
    {
        for(Id id : idLeadMap.keySet()){
            
            Lead lead = new Lead (Id = id);
            lead.Most_Recent_Campaign = idLeadMap.get(id);
            
            leadToUpdateList.add(lead);
        }
    }
       
    if(idContactMap.size() > 0) 
    {
        for(Id id : idContactMap.keySet()){
            
            Contact contact = new Contact (Id = id);
            contact.Most_Recent_Campaign = idContactMap.get(id);

            contactToUpdateList.add(contact);            
        }
    }       
       
	if(leadToUpdateList.size() > 0)    
        update leadToUpdateList;
        
    
	if(contactToUpdateList.size() > 0)
        update contactToUpdateList;
    
    

}

 

All Answers

Abdul KhatriAbdul Khatri
Here is the code
trigger UpdateMostRecentCampaign on CampaignMember (after insert) {
    
    Map<Id, Id> idContactMap = new Map<Id, Id>();
    Map<Id, Id> idLeadMap = new Map<Id, Id>();
    
    List<Lead> leadToUpdateList = new List<Lead>();
    List<Contact> contactToUpdateList = new List<Contact>();
    
    for(CampaignMember member : trigger.new) {
        
        if(member.LeadId != null)
            idLeadMap.put(member.LeadId, member.CampaignId);
        
        if(member.ContactId != null)
            idContactMap.put(member.ContactId, member.CampaignId);
    }
    
    if(idLeadMap.size() > 0) 
    {
        for(Id id : idLeadMap.keySet()){
            
            Lead lead = new Lead (Id = id);
            lead.Most_Recent_Campaign = idLeadMap.get(id);
            
            leadToUpdateList.add(lead);
        }
    }
       
    if(idContactMap.size() > 0) 
    {
        for(Id id : idContactMap.keySet()){
            
            Contact contact = new Contact (Id = id);
            contact.Most_Recent_Campaign = idContactMap.get(id);

            contactToUpdateList.add(contact);            
        }
    }       
       
	if(leadToUpdateList.size() > 0)    
        update leadToUpdateList;
        
    
	if(contactToUpdateList.size() > 0)
        update contactToUpdateList;
    
    

}

 
This was selected as the best answer
Kevin Charette 8Kevin Charette 8
Thank you sooo much! I have already uploaded your trigger into our Production. Worked like a sharm.

I wonder if there is a way to do this for the opportunity too? 

Kind of last minute I know. But if you have the time to advise on one around an opportunity field, that would be awesome!
Abdul KhatriAbdul Khatri
Normally Opportunities are tied with AccountId (Out of Box) which is related to Contact. Keeping this perspective here is the code with opportunity addition
 
trigger UpdateMostCampaign on CampaignMember (after insert) {
    
    Map<Id, Id> idContactMap = new Map<Id, Id>();
    Map<Id, Id> idLeadMap = new Map<Id, Id>();
    Map<Id, Id> idAccountMap = new Map<Id, Id>();
    
    List<Lead> leadToUpdateList = new List<Lead>();
    List<Contact> contactToUpdateList = new List<Contact>();
    
    for(CampaignMember member : trigger.new) {
        
        if(member.LeadId != null)
            idLeadMap.put(member.LeadId, member.CampaignId);
        
        if(member.ContactId != null)
            idContactMap.put(member.ContactId, member.CampaignId);
    }
    
    if(idLeadMap.size() > 0) 
    {
        for(Id id : idLeadMap.keySet()){
            
            Lead lead = new Lead (Id = id);
            lead.Most_Recent_Campaign = idLeadMap.get(id);
            
            leadToUpdateList.add(lead);
        }
    }
       
    if(idContactMap.size() > 0) 
    {
        Map<Id, Contact> contactMap = new Map<Id, Contact>([SELECT AccountId FROM Contact WHERE Id IN :idContactMap.keySet()]);
        
        for(Id id : idContactMap.keySet()){
            
            idAccountMap.put(contactMap.get(id).AccountId, idContactMap.get(id));
            
            Contact contact = new Contact (Id = id);
            contact.Most_Recent_Campaign = idContactMap.get(id);

            contactToUpdateList.add(contact);            
        }
    } 
    
    if(idAccountMap.size() > 0){
        
        List<Opportunity> oppList = [SELECT AccountId FROM Opportunity WHERE AccountId IN :idAccountMap.keySet()];
        
        for(Opportunity opp : oppList) {
            
            opp.CampaignId = idAccountMap.get(opp.AccountId);
        }
        
        update oppList;
    }
        
	if(leadToUpdateList.size() > 0)    
        update leadToUpdateList;
        
    
	if(contactToUpdateList.size() > 0)
        update contactToUpdateList;

}

 
Kevin Charette 8Kevin Charette 8
Thank you. I was trying to deploy the first iteration that you sent into production and I got this error when I tried to validate it before deploying it: "Your organization's code coverage is 73%. You need at least 75% coverage to complete this deployment. Also, the following triggers have 0% code coverage. Each trigger must have at least 1% code coverage. - UpdateMostRecentCampaign" Do you know how to fix this?
Abdul KhatriAbdul Khatri
Please add this test class but first run it in your development or before pushing to Prod
 
@isTest
public class UpdateMostCampaignTest {
    
    @testSetup static void setupData(){
        
        Lead newLead = new Lead (Company = 'Test Company', LastName = 'Test');
        insert newLead;
        
        Account account = new Account (Name = 'Test');
        insert account;
        
        Contact newContact = new Contact (LastName = 'Test', AccountId = account.Id);
        insert newContact;
        
        Opportunity newOpportunity = new Opportunity (Name = 'Test', StageName = 'Prospecting', CloseDate = date.today(), AccountId = account.Id);
        insert newOpportunity;
        
        Campaign newCampaign = new Campaign ( Name = 'Test Campaign' );
        insert newCampaign;
       
    }
    
    static testMethod void testLeadCampaign() {
    
        Campaign newCampaign = [SELECT Id FROM Campaign WHERE Name = 'Test Campaign'];
        Lead newLead = [SELECT Id FROM Lead WHERE Company = 'Test Company'];
        
        Test.startTest();
            CampaignMember member = new CampaignMember (CampaignId = newCampaign.Id, LeadId = newLead.Id );
        	insert member;
        Test.stopTest();
        
        Lead lead = [SELECT Id FROM Lead WHERE Id = :newLead.Id];
        
        System.assertEquals(newCampaign.Id, lead.Most_Recent_Campaign__c);
        
        
    }
    
    static testMethod void testCompanyCampaign() {
    
        Campaign newCampaign = [SELECT Id FROM Campaign WHERE Name = 'Test Campaign'];
        Contact newContact = [SELECT Id FROM Contact WHERE LastName = 'Test'];
        
        Test.startTest();
            CampaignMember member = new CampaignMember (CampaignId = newCampaign.Id, ContactId = newContact.Id );
        	insert member;
        Test.stopTest();
        
        Contact contact = [SELECT Id FROM Contact WHERE Id = :newContact.Id];
        
        System.assertEquals(newCampaign.Id, contact.Most_Recent_Campaign__c);
        
        
    }
    
    static testMethod void testOpportunityCampaign() {
    
        Campaign newCampaign = [SELECT Id FROM Campaign WHERE Name = 'Test Campaign'];
        Contact newContact = [SELECT Id FROM Contact WHERE LastName = 'Test'];        
        Opportunity newOpportunity = [SELECT Id FROM Opportunity WHERE Name = 'Test'];
        
        Test.startTest();
            CampaignMember member = new CampaignMember (CampaignId = newCampaign.Id, ContactId = newContact.Id );
        	insert member;
        Test.stopTest();
        
        Opportunity opportunity = [SELECT Id FROM Opportunity WHERE Id = :newOpportunity.Id];
        
        System.assertEquals(newCampaign.Id, opportunity.CampaignId);
        
        
    }    

}

 
Abdul KhatriAbdul Khatri
You need to deploy both files together.
Kevin Charette 8Kevin Charette 8
The test should be for the first iteration without the opportunity. As I thought more about it the first one made more sense. Not sure what edits need to be made for it to work with the first code you send rather than the one with the opportunity logic in it.
Abdul KhatriAbdul Khatri
@isTest
public class UpdateMostCampaignTest {
    
    @testSetup static void setupData(){
        
        Lead newLead = new Lead (Company = 'Test Company', LastName = 'Test');
        insert newLead;
        
        Account account = new Account (Name = 'Test');
        insert account;
        
        Contact newContact = new Contact (LastName = 'Test', AccountId = account.Id);
        insert newContact;
        
        Opportunity newOpportunity = new Opportunity (Name = 'Test', StageName = 'Prospecting', CloseDate = date.today(), AccountId = account.Id);
        insert newOpportunity;
        
        Campaign newCampaign = new Campaign ( Name = 'Test Campaign' );
        insert newCampaign;
       
    }
    
    static testMethod void testLeadCampaign() {
    
        Campaign newCampaign = [SELECT Id FROM Campaign WHERE Name = 'Test Campaign'];
        Lead newLead = [SELECT Id FROM Lead WHERE Company = 'Test Company'];
        
        Test.startTest();
            CampaignMember member = new CampaignMember (CampaignId = newCampaign.Id, LeadId = newLead.Id );
        	insert member;
        Test.stopTest();
        
        Lead lead = [SELECT Id FROM Lead WHERE Id = :newLead.Id];
        
        System.assertEquals(newCampaign.Id, lead.Most_Recent_Campaign__c);
        
        
    }
    
    static testMethod void testContactCampaign() {
    
        Campaign newCampaign = [SELECT Id FROM Campaign WHERE Name = 'Test Campaign'];
        Contact newContact = [SELECT Id FROM Contact WHERE LastName = 'Test'];
        
        Test.startTest();
            CampaignMember member = new CampaignMember (CampaignId = newCampaign.Id, ContactId = newContact.Id );
        	insert member;
        Test.stopTest();
        
        Contact contact = [SELECT Id FROM Contact WHERE Id = :newContact.Id];
        
        System.assertEquals(newCampaign.Id, contact.Most_Recent_Campaign__c);
        
        
    }
    
    /*static testMethod void testOpportunityCampaign() {
    
        Campaign newCampaign = [SELECT Id FROM Campaign WHERE Name = 'Test Campaign'];
        Contact newContact = [SELECT Id FROM Contact WHERE LastName = 'Test'];        
        Opportunity newOpportunity = [SELECT Id FROM Opportunity WHERE Name = 'Test'];
        
        Test.startTest();
            CampaignMember member = new CampaignMember (CampaignId = newCampaign.Id, ContactId = newContact.Id );
        	insert member;
        Test.stopTest();
        
        Opportunity opportunity = [SELECT Id FROM Opportunity WHERE Id = :newOpportunity.Id];
        
        System.assertEquals(newCampaign.Id, opportunity.CampaignId);
        
        
    } */   

}

Just commented the opportunity test method
Kevin Charette 8Kevin Charette 8
These are the errors I got from the test: UpdateMostCampaignTest2 testContactCampaign System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: Contact.Most_recent_Campaign__c Stack Trace: Class.UpdateMostCampaignTest2.testContactCampaign: line 52, column 1 UpdateMostCampaignTest2 testLeadCampaign System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: Lead.Most_recent_Campaign__c Stack Trace: Class.UpdateMostCampaignTest2.testLeadCampaign: line 35, column 1
Abdul KhatriAbdul Khatri
sorry my bad
 
@isTest
public class UpdateMostCampaignTest {
    
    @testSetup static void setupData(){
        
        Lead newLead = new Lead (Company = 'Test Company', LastName = 'Test');
        insert newLead;
        
        Account account = new Account (Name = 'Test');
        insert account;
        
        Contact newContact = new Contact (LastName = 'Test', AccountId = account.Id);
        insert newContact;
        
        Opportunity newOpportunity = new Opportunity (Name = 'Test', StageName = 'Prospecting', CloseDate = date.today(), AccountId = account.Id);
        insert newOpportunity;
        
        Campaign newCampaign = new Campaign ( Name = 'Test Campaign' );
        insert newCampaign;
       
    }
    
    static testMethod void testLeadCampaign() {
    
        Campaign newCampaign = [SELECT Id FROM Campaign WHERE Name = 'Test Campaign'];
        Lead newLead = [SELECT Id FROM Lead WHERE Company = 'Test Company'];
        
        Test.startTest();
            CampaignMember member = new CampaignMember (CampaignId = newCampaign.Id, LeadId = newLead.Id );
        	insert member;
        Test.stopTest();
        
        Lead lead = [SELECT Id, Most_Recent_Campaign__c FROM Lead WHERE Id = :newLead.Id];
        
        System.assertEquals(newCampaign.Id, lead.Most_Recent_Campaign__c);
        
        
    }
    
    static testMethod void testContactCampaign() {
    
        Campaign newCampaign = [SELECT Id FROM Campaign WHERE Name = 'Test Campaign'];
        Contact newContact = [SELECT Id FROM Contact WHERE LastName = 'Test'];
        
        Test.startTest();
            CampaignMember member = new CampaignMember (CampaignId = newCampaign.Id, ContactId = newContact.Id );
        	insert member;
        Test.stopTest();
        
        Contact contact = [SELECT Id, Most_Recent_Campaign__c FROM Contact WHERE Id = :newContact.Id];
        
        System.assertEquals(newCampaign.Id, contact.Most_Recent_Campaign__c);
        
        
    }
    
    /*static testMethod void testOpportunityCampaign() {
    
        Campaign newCampaign = [SELECT Id FROM Campaign WHERE Name = 'Test Campaign'];
        Contact newContact = [SELECT Id FROM Contact WHERE LastName = 'Test'];        
        Opportunity newOpportunity = [SELECT Id FROM Opportunity WHERE Name = 'Test'];
        
        Test.startTest();
            CampaignMember member = new CampaignMember (CampaignId = newCampaign.Id, ContactId = newContact.Id );
        	insert member;
        Test.stopTest();
        
        Opportunity opportunity = [SELECT Id, CampaignId FROM Opportunity WHERE Id = :newOpportunity.Id];
        
        System.assertEquals(newCampaign.Id, opportunity.CampaignId);
        
        
    } */   

}

 
Abdul KhatriAbdul Khatri
Sorry my bad 
 
@isTest
public class UpdateMostCampaignTest {
    
    @testSetup static void setupData(){
        
        Lead newLead = new Lead (Company = 'Test Company', LastName = 'Test');
        insert newLead;
        
        Account account = new Account (Name = 'Test');
        insert account;
        
        Contact newContact = new Contact (LastName = 'Test', AccountId = account.Id);
        insert newContact;
        
        Opportunity newOpportunity = new Opportunity (Name = 'Test', StageName = 'Prospecting', CloseDate = date.today(), AccountId = account.Id);
        insert newOpportunity;
        
        Campaign newCampaign = new Campaign ( Name = 'Test Campaign' );
        insert newCampaign;
       
    }
    
    static testMethod void testLeadCampaign() {
    
        Campaign newCampaign = [SELECT Id FROM Campaign WHERE Name = 'Test Campaign'];
        Lead newLead = [SELECT Id FROM Lead WHERE Company = 'Test Company'];
        
        Test.startTest();
            CampaignMember member = new CampaignMember (CampaignId = newCampaign.Id, LeadId = newLead.Id );
        	insert member;
        Test.stopTest();
        
        Lead lead = [SELECT Id, Most_Recent_Campaign__c FROM Lead WHERE Id = :newLead.Id];
        
        System.assertEquals(newCampaign.Id, lead.Most_Recent_Campaign__c);
        
        
    }
    
    static testMethod void testContactCampaign() {
    
        Campaign newCampaign = [SELECT Id FROM Campaign WHERE Name = 'Test Campaign'];
        Contact newContact = [SELECT Id FROM Contact WHERE LastName = 'Test'];
        
        Test.startTest();
            CampaignMember member = new CampaignMember (CampaignId = newCampaign.Id, ContactId = newContact.Id );
        	insert member;
        Test.stopTest();
        
        Contact contact = [SELECT Id, Most_Recent_Campaign__c FROM Contact WHERE Id = :newContact.Id];
        
        System.assertEquals(newCampaign.Id, contact.Most_Recent_Campaign__c);
        
        
    }
    
    /*static testMethod void testOpportunityCampaign() {
    
        Campaign newCampaign = [SELECT Id FROM Campaign WHERE Name = 'Test Campaign'];
        Contact newContact = [SELECT Id FROM Contact WHERE LastName = 'Test'];        
        Opportunity newOpportunity = [SELECT Id FROM Opportunity WHERE Name = 'Test'];
        
        Test.startTest();
            CampaignMember member = new CampaignMember (CampaignId = newCampaign.Id, ContactId = newContact.Id );
        	insert member;
        Test.stopTest();
        
        Opportunity opportunity = [SELECT Id FROM Opportunity WHERE Id = :newOpportunity.Id];
        
        System.assertEquals(newCampaign.Id, opportunity.CampaignId);
        
        
    } */   

}

 
Kevin Charette 8Kevin Charette 8
All deployed. Thanks for all your help Abdul!
Kevin Charette 8Kevin Charette 8
Anything I can do for you let me know.
Abdul KhatriAbdul Khatri
Please mark a best answer
Rajiv ThanneruRajiv Thanneru
@Abdul Khatri 

Can you please bulkify this trigger?
Abdul KhatriAbdul Khatri
@Rajiv

What do you mean bulkify the trigger? Where you feel it is not bulkify?
Rajiv ThanneruRajiv Thanneru
@Abdul Khatri

Incase if we need to process multiple leads and campaigns means. That case
Rajiv ThanneruRajiv Thanneru
@Abdul Khatri
multiple campaigns on single leads means that instance am saying.
 
Abdul KhatriAbdul Khatri
Sorry I have been very busy with other things so couldn't get back to you immediately.

Do you have a design (schema)? I mean how are you planning to process the lead with the campaigns so that I can build something for you? I am asking this because your process start from the lead so the trigger flow will change in this case and above will not work as that start from the campaignmember?