Image of Marc Baizman and Stephen Brown for our "How I Solved This" blog post and video.

How I Solved This: Using Flow to Automate Self-Service Contact Record Updates


Welcome to another “How I Solved This.” In this series, we do a deep dive into a specific business problem and share how one #AwesomeAdmin chose to solve it. Once you learn how they solved their specific problem, you’ll be inspired to try their solution yourself! Watch how Stephen Brown empowered contacts to update their contact information and self-subscribe to campaigns with Flow, and then read all the details in the post below. 


Key business problem

I want to enable my contacts to update their contact preferences and details via a self-service website, and then take action on those changes and email them a confirmation of these changes, without creating manual work for myself.


Cleft New Zealand is a small, volunteer-run non-profit organization. We provide advocacy, in-person meetups, and online resources to a community of approximately 100 children and families each year. This involves a lot of outreach and outbound email. While our community isn’t large, we face a challenge commonly encountered by Salesforce Admins: It’s very important that our contact details are accurate and our communications are relevant to customer preferences.

The journey for our contacts is also time-sensitive. Children and families require more support and resources earlier in life, so it’s very important that we’re able to provide these self-service options. We also want to ensure that we aren’t spamming our contacts with information that isn’t relevant to them.

Admins have limited time to spend cleaning and maintaining the database, so it’s important any solution we implement is fully automated.

Contacts can log in to a self-service webpage to update their contact information and subscription preferences. We also have a tool that automatically sends emails to contacts that are added to campaigns.

We were able to meet our requirements with Flow. When a customer submits the self-service form, a custom object is created so we can easily track the history of data changes. A record-triggered flow is fired which updates the related contact, adds a campaign member to the relevant campaign, and then fires an email to the contact verifying the changes that were made.

How I solved it

There have been some enhancements to Flow that meet all of our business requirements. Let’s take a look at how we built the solution, step by step.

1. Capture the change in a custom object

This portion of our solution was created some time ago. We won’t go into the fine details of how this portion of the solution works, but here’s the general overview.

Our contact starts by logging in to the Cleft New Zealand self-service page and submitting updated information.

Screenshot of Cleft New Zealand's self-service page.

When they submit this form, a Contact Data Change record is created.

Screenshot of the Contact Data Change record that was created.

We created the Contact Data Change object to allow for reporting and history tracking on our customer changes. This also allows us to display previous changes to our contacts when they visit the form.

Our custom object automatically collects the data from the fields that were populated on the website as well as the related Contact ID.

2. Create a record-triggered flow

When we’re done with our update flow, we’ll want it to look like this:

Screenshot of the first main flow in Flow Builder.

Head to Setup -> Flow -> Create a new Flow. From here, you’ll select a record-triggered flow.

Screenshot showcasing how you select a record-triggered flow.

Then, you’ll select the Start node and configure the trigger to be A record is created or updated, and we’ll run the flow After the record is saved on the Contact Data Change object.

Screenshot showcasing how to configure the trigger to be A record is created or updated.

Pro Tip: We chose an after-save flow because we’re referencing some formulas within the flow. Formulas are only calculated after a record is saved. 

We’ve also included a conditional requirement to this trigger. In order to prevent circular logic, we’ve created a checkbox field called Updates_Processed__c. This field is updated to True at the very end of the flow. In other words, by only processing records where Updates_Processed__c Equals False, we’re ensuring records are only ever processed once.

Screenshot highlighting how to include a conditional requirement to the trigger.

Once we finish configuring the start node, we’ll drag a Get Records element onto the canvas. Since the Contact Data Change record contains the related Contact ID, we can use this in our flow.

In other words, we’ll get all the contact records, where the Contact ID matches the related Contact ID from our Contact Data Change record.

Screenshot of the "Get Records" element we dragged into the canvas.

The result is a single contact.

Now we’ll add a Decision element to our flow. This will allow us to compare the Contact Data Change record to the contact record we’ve looked up. If the values are the same, then we’ll end the flow. No need to update the database if there are no changes.

Screenshot showcasing the Decision element created.

Pro Tip: Limiting the number of times you update the database in Flow is an excellent pattern to maintain governor limits.

If there are changes to the data, then we can use an Assignment element to assign the new values to our contact, and then use an Update Records element to update the Contact in the database.

Screenshot showcasing how you can Edit an Assignment.

Pro Tip: Remember, in order to update a record with Flow, you must first assign the values and then update the database. 

3. Send an email notification

We’ll need to create a text template before we’re able to configure the send email action. So head over to the Toolbox and create a new text template resource. Make sure to select View as Rich Text on the right-hand side. When in the Rich Text view, you can include formatting like bold or italicized text, spacing, bullets, and styling. You can also insert images and links. 

For our use case, we’ll be bolding some text and also adding references to the Email, Address, Newsletter Subscription, and Coffee Group Subscription fields that we’ve updated. This may look familiar to admins that have seen merge field syntax in email templates.

Screenshot showcasing the new text template resource with information such as email, address, subscribe to newsletter, and subscribe to coffee group.

After you save the text template, you can drag an action onto the canvas and Send Email core action. Make sure to reference your text template in the Body field. Also, make sure you’ve added {!$GlobalConstant.True} to the Rich-Text-Formatted Body field.

Screenshot that shows a text box that says "Edit Send Email core action."

Pro Tip: The icons next to each of the fields in the action configuration show you the expected data type. The upper and lowercase letters indicate text. The interlocked circles indicate a True or False, or boolean, value.

4. Update the Contact Data Change record

We’re nearly finished! Now that we’ve updated the contact and sent the email notification, we’ll need to update the Contact Data Change record by updating the Updates_Processed__c field. This will prevent this record from triggering the flow again in the future.

Image showing how you update the Contact Data record by updating the Updates_Processed___c field.

After we assign the values, we can grab an Update Records element from the Toolbox. Configure the element with the variable you just assigned, and this step is complete.

5. Create a related campaign member flow

If our contact subscribes to our email campaign, we need to add them to our Salesforce campaign as a campaign member.

Second flow with camp member decision tree.

We’ll need to drag a Decision element onto the canvas. In this element, we want to determine if the Subscribe field is true or false. If it’s true, we’ll perform some logic. If it’s false, we’ll skip this step.

Screenshot of the new decision element.

To create the campaign member, we must first find the correct campaign Id. We’ll achieve this with a Get Records element from the Toolbox. Then, we’ll configure the element by manually entering the Name of the campaign we’re looking for.

Screenshot of the new get records element.

Pro Tip: It’s best to avoid hard-coding values like we’ve done above. Consider using custom metadata types to store information like this.

Now let’s drag an Assignment element onto the canvas. There are three required fields to create a Campaign Member: Campaign Id, Contact Id, and Status. We’ve already stored our Contact ID and Campaign ID in flow memory, so we can easily assign them. In our org, we don’t use the Status field for business processes, but we can’t create the record without a value, so we’ll select sent.

Screenshot of assignment elements.

Lastly, we’ll drag an Update Records element on the canvas. Plug in your Campaign Member variable and you’re all set!

Business results

This automation made a big impact at Cleft New Zealand. It allowed us to engage our community in a tailored, thoughtful, and relevant way. Our contacts were able to find nearby coffee group meetups by updating their addresses, and we don’t need to email our entire database if a campaign doesn’t apply to a contact. Perhaps more importantly, people feel more empowered to manage their own data and preferences. This strengthens our relationship with the community and reduces the burden on our limited Salesforce resources.

Do try this at home

I was excited to build this solution entirely in Flow, especially the rich text email. Flow is an excellent automation tool, but remember to build responsibly. You should always build your automations in a sandbox environment and thoroughly test them.

Make sure you’re never building in a vacuum. If there are other builders or admins in your org, make sure you communicate with them about your automation to ensure your work doesn’t conflict or cause issues.

Relevant Trailhead badges

Want to see more good stuff? Subscribe to our channel!