(This solution works in both Classic and Lightning Experience.)
Your company is using Salesforce campaigns. You need to also give your contacts the ability to opt out of marketing campaigns. Currently, a contact who has opted out of marketing campaigns may be added to a campaign. The marketing user then needs to run a report for those who have opted out and manually remove them from the campaign. You know what happens when there is a manual process. Someone forgets or they accidentally missed removing the contact. Then the contact gets the outcome of the marketing campaign. The contact calls and complains that they have opted out and still they are receiving marketing materials. Not good.
Here is the schema for Contact, Campaign and Campaign Member.
A Contact can have zero to many Campaigns Members. A Campaign can have one or many Campaign Members.
You can implement solutions that will automatically remove any marketing opted out contacts from all associated campaigns prior to the opt out and prevent/remove the contact from new campaigns. This can all be done declaratively, using point-and-click, no code!
Here are a few lessons learned from implementing this use case:
- Learn how to invoke flow from process builder.
- Learn how to pass variables into flow to indicate path in flow to take.
- Use fast flow elements to perform actions on a collection of records using sobject collection variables.
- Create a validation rule to prevent opted out contacts from added to a campaign in Lightning Experience.
- Provide descriptions, where provided, in Salesforce. This may be tedious step, I know, but your future self will thank you when you are trying to remember what you configured or assist other/future admins when troubleshooting or enhancing what was built. This includes variables, the purpose of a flow, what each flow element does, etc.
Business Use Case: Addison Dogster is the system administrator at Universal Containers. Mary Markle is the Director of Marketing. Mary asked Addison if there was a way to not allow users to add contacts who have opted out of marketing campaigns to new marketing campaigns as well as remove the contact from all existing campaigns.
Solution: Being the #AwesomeAdmin that Addison is, she was able to solution this declaratively using process builder and flow on the Contact and Campaign Member objects (and for Lightning Experience only, a validation rule on the Campaign Member object).
Quick Steps:
Pre-Requisite: The Marketing Opt-Out checkbox is exists on the Contact record.
- For those using Lightning Experience, let’s create a validation rule on the Campaign Member object that will prevent contacts who have opted out from being added to a campaign. We want the error to display when the contact’s marketing opt out field is checked so the formula syntax to use is “Contact.Marketing_Opt_Out__c.”
Best practice tip: Don’t forget to provide a description so you and other/future admins know what this validation rule is used for.
2. Now, we need to create a flow that depending on the path passed from process builder, it will either delete new contact that was added to a campaign or will look up all associated campaigns and remove the contact as a campaign member. Go to Setup | Create | Workflows & Approvals | Flows in Salesforce Classic or Process Automation | Flows in Lightning Experience.
A. First, we are going to create three variables and an sObject variable.
The variable will store the campaign ID passed from process builder.
The variable will store the contact ID passed from process builder.
The variable will store the process passed from process builder. We will use this later in the flow to determine what path to take in the flow so we use one consolidated flow to handle the contact removal from the Campaign Member object.
This sobject variable will contain all the campaign member records associated to the Contact for a fast delete later on in the flow.
Best practice tip: Don’t forget to provide a description so you and other/future admins know what this variable is used for.
B. Create a Decision flow element. This will look at the variable varProcessBuilderEntry, string passed from process builder, to then determine the path to take in this flow. For the contact process, the variable varProcessBuilderEntry equals “Contact.” For the campaign member process, the variable varProcessBuilderEntry equals “CampaignMember.”
Best practice tip: Don’t forget to provide a description so you and other/future admins know what this decision flow element does.
C. Now, assuming the Campaign Member process, we will create a Record Delete flow element. This will delete the campaign member record where the CampaignId equals the variable varCampaignID AND the ContactId equals the variable varContactID.
Best practice tip: Don’t forget to provide a description so you and other/future admins know what this record delete flow element does.
D. Next step, we will add a Fast Lookup flow element. This will lookup the Campaign Member object to query records where the ContactId equals the variable varContactID. Any records found would be added to the sObject variable sObjectColCampaigns. Then we will save the Id in the variable.
Best practice tip: Don’t forget to provide a description so you and other/future admins know what this flow element does.
E. Let’s now create another Decision flow element. This will determine whether any campaign member records were found. It is best practice to put this decision in the flow. If there were no campaigns found, the flow would fault when it tries to delete the campaign member records, of which there are none. If there are at least one campaign member record (i.e. sobject variable sObjectColCampaigns IsNull $Global.Constant.False).
Best practice tip: Don’t forget to provide a description so you and other/future admins know what this flow element does.
F. We will now add a Fast Delete flow element. This will then delete the campaign member records in the sobject variable sObjectColCampaigns.
Best practice tip: Don’t forget to provide a description so you and other/future admins know what this flow element does.
G. Add the subflow Send Flow Fault Email. For instructions on how to create this, go to Step 2 of blog post: Maximize Maintainability With Process Builder and Componentized Visual Workflow.
H. Set your flow starting point. And connect the flow elements and the fault connectors to match the below…
I. Save as and provide the following properties. We’re going to call this flow “Remove Contact from Campaign.”
Best practice tip: Provide a description so you and other/future admins know what this flow is used for.
J. Click the “Close” button.
K. On the flows screen, activate the flow.
4. We are going to create the first of two processes. This one is for the Contact object. When the Marketing Opt Out field is updated and changed to true, we will invoke the flow we created in Step 3 and pass onto the flow specific parameters.
Create the process by going to Create | Workflows & Approvals | Process Builder in Salesforce Classic or Process Automation | Process Builder in Lightning Experience.
A. Provide a process name “Take action on new/existing contacts”, API name (auto-populated via tab key), description and select the process starts when “A record changes.”
Best practice tip: Don’t forget to provide a description so you and other/future admins know what this process is for.
B. Specify Contact as the object and to start the process “when a record is created or edited.”
C. Specify the first criteria “Opted Out of Marketing” where the conditions are that the [Contact].Marketing_Out_Out__c Is changed Boolean True AND [Contact].Marketing_Out_Out__c Equals Boolean True.
D. For the immediate action, we are invoke the flow we created in Step 3 – Remove Contact from Campaign. We will pass two variables to flow.
- varProcessBuilderEntry string Contact
- varContactID Field Reference [Contact].Id
E. Activate the process.
5. Lastly, we will create the second of two processes. This one is for the Campaign Member object. When the campaign member is newly created and the contact’s marketing opt out checkbox is checked, we will invoke the flow we created in Step 3 and pass onto the flow specific parameters.
A. Provide a process name “Take Action on Campaign Members”, API name (auto-populated via tab key), description (Process for new or updates to campaign members) and select the process starts when “A record changes.”
Best practice tip: Don’t forget to provide a description so you and other/future admins know what this process is for.
B. Specify Campaign Member as the object and to start the process “when a record is created or edited.”
C. Specify the first criteria “New Campaign Member” where the conditions are formula evaluates to true. We need to use a formula because we need to use the formula for record is new and the contact’s marketing opt out is set to true. Our formula is “IsNew() && [CampaignMember].Contact.Marketing_Opt_Out__c.”
D. For the immediate action, we will invoke the flow we created in Step 3 – Remove Contact from Campaign. We will pass three variables to the flow.
- varCampaignID Field Reference [CampaignMember].CampaignId
- varContactID Field Reference [CampaignMember].ContactId
- varProcessBuilderEntry String CampaignMember
E. Activate the process.
Now, before you deploy the changes to Production, don’t forget to test your configuration changes.
- Log in as the intended user.
- Add a contact with the Marketing opt out checkbox unchecked to a couple of campaigns.
- Update the contact record to check the Marketing opt out checkbox.
- Verify the contact has been removed as a campaign member from all campaigns.
- Add the contact to any marketing campaign. If you are using Lightning Experience, the system will display the validation rule error.
- Verify that the contact is not a campaign member of the marketing campaign the contact was added to in Step 5.
Deployment Notes/Tips:
- The process builders, visual workflow, (if using Lightning Experience, validation rule) can be deployed to Production in a change set (or can be deployed using a tool such as Dreamfactory’s Snapshot).
- You will find the process builders and flow in a change set under the Flow Definition component type.
- Activate the process builders and flow post deployment as they deploy inactive in Production.