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
Bharat.SharmaBharat.Sharma 

Automate the Process of add to Campaign- Salesforce

hello Everyone,
actually i want to automate the process of  'add to campaign member' but i am getting some error.
Here are the scenario details : 
Whenever any lead enters in the database with LeadSource = Linkedin (PicklistValue) it should automatically get added to the particular campaign which will be having a specific campaign id.
I think this secnario can handle with Trigger , Flows and Process Builder 
I have tried Everything to implement this secnario but i am getting Some errors. please help me to complete this automation.
Any help will be appreciable :)

here is the Trigger
trigger add_member_to_camp on Lead (before insert,after insert) {
   List<CampaignMember> members = new List<CampaignMember>();
    
    for(lead l : Trigger.new){
        
        if(l.LeadSource == 'linkedin'){
            CampaignMember cm = new CampaignMember(CampaignId = '70128000000Btjj');
        }
        try{
        insert members;
    } catch(DmlException e) {
        System.debug('An unexpected error has occured: ' + e.getMessage());
    }
    }

}

Flow 

User-added image

User-added image


User-added image


User-added image

User-added image


And Process builder also  showing some Error 
please help me 

Thanks 
Bharat Sharma
Best Answer chosen by Bharat.Sharma
Shun KosakaShun Kosaka
Hi!
I checked your trigger. the important points are
 - In before trigger context, DML statements cannot be operated.
 - In your case, trigger should be called only after context. (Now, your trigger is called twice!)
 - Campaign members should be added to list.
 - LeadId is required for campaign member.
 Try below code!
trigger add_member_to_camp on Lead (after insert) {
    List<CampaignMember> members = new List<CampaignMember>();
    
    for(lead l : Trigger.new){
        if(l.LeadSource == 'linkedin'){
            CampaignMember cm = new CampaignMember(CampaignId = '70128000000Btjj', LeadId = l.Id);
            members.add(cm);
        }
    }
    try{
        insert members;
    } catch(DmlException e) {
        System.debug('An unexpected error has occured: ' + e.getMessage());
    }
}
Be careful if you develop this trigger in a sandbox org because campaign id will be changed in the production org. And I will check your flow later!
 

All Answers

Shun KosakaShun Kosaka
Hi!
I checked your trigger. the important points are
 - In before trigger context, DML statements cannot be operated.
 - In your case, trigger should be called only after context. (Now, your trigger is called twice!)
 - Campaign members should be added to list.
 - LeadId is required for campaign member.
 Try below code!
trigger add_member_to_camp on Lead (after insert) {
    List<CampaignMember> members = new List<CampaignMember>();
    
    for(lead l : Trigger.new){
        if(l.LeadSource == 'linkedin'){
            CampaignMember cm = new CampaignMember(CampaignId = '70128000000Btjj', LeadId = l.Id);
            members.add(cm);
        }
    }
    try{
        insert members;
    } catch(DmlException e) {
        System.debug('An unexpected error has occured: ' + e.getMessage());
    }
}
Be careful if you develop this trigger in a sandbox org because campaign id will be changed in the production org. And I will check your flow later!
 
This was selected as the best answer
Bharat.SharmaBharat.Sharma
Thank You 
Shun Kosaka !

Is there any other option to Specify the Campaign Without id ??
by the way Its working now :)
 
Shun KosakaShun Kosaka
Hi Bharat,
That's good!

I guess there are some options to specify the record.
- Create unique and required custom field.
- Use custom metadata types/custom settings that have a mapping of sandbox and production record id
etc...

I also looked over the flow. I think a governor limitation error occurs due to the record creation in the loop.
You can use collection variables same as the trigger.
https://developer.salesforce.com/docs/atlas.en-us.salesforce_vpm_guide.meta/salesforce_vpm_guide/vpm_designer_resources_coll_var_pop.htm
Bharat.SharmaBharat.Sharma
Thanks Again shun,

one more thing,
I have created a custom field on lead page named as "First_touch_Campaign__c". As name suggest this field will be filled up automatically with the same campaign name in which lead is added as a campaignMember for the very first time. this field should get locked or no further editing or any updation could takes place. Basically i want this field to get the data once only and that too at the time of lead creation only when the lead will get associated to the campaign in the very beginning.

Can we add this feature in same trigger that we have talked about earlier.
Shun KosakaShun Kosaka

Hi Bharat,
It can be realized like below. In before trigger context, triggered records can be modified directly.

trigger add_member_to_camp on Lead (before insert, after insert) {
    List<CampaignMember> members = new List<CampaignMember>();
    if(Trigger.isBefore){
        for(lead l : Trigger.new){
            l.First_touch_Campaign__c = 'SET STRING OR QUERY CAMPAING RECORD RESULT';
        }
    }
    else if(Trigger.isAfter){
        for(lead l : Trigger.new){
            if(l.LeadSource == 'linkedin'){
                CampaignMember cm = new CampaignMember(CampaignId = '70128000000Btjj', LeadId = l.Id);
                members.add(cm);
            }
        }
        try{
            insert members;
        } catch(DmlException e) {
            System.debug('An unexpected error has occured: ' + e.getMessage());
        }
    }
}
Set field level security of 'First_touch_Campaign__c' as read only and check the result with the profile other than system admin. And tell me if you don't get expected result!
Bharat.SharmaBharat.Sharma
Thanks shun,
for such a fast Reply !!

When i am Passing Query
'l.First_touch_Campaign__c =​ SELECT Name FROM Campaign WHERE Id = '70128000000Btjj'' insted of String.  getting error  like   Illegal assignment from List<Campaign> to String.
Shun KosakaShun Kosaka
Hi,
Type of query results is sObject or List of sObject.
Campaign cmp = [SELECT Name FROM Campaign WHERE Id = '70128000000Btjj];
l.First_touch_Campaign__c =​ cmp.Name;
The following is an another example.
l.First_touch_Campaign__c =​ [SELECT Name FROM Campaign WHERE Id = '70128000000Btjj].Name;
See also,
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_SOQL_working_with_results.htm

Good luck!
Bharat.SharmaBharat.Sharma
Hello and Thanks shun,
Everything is working fine :)

One last thing,
Could you please help me to develope test class for the same trigger.

Thanks for your Support.