It’s great that we are able to track up to 20 fields on an object for changes (up to 60 fields per object if you purchase the Field History feature for an additional fee). But what if you want to do something with the information or want to retain that information in Salesforce?
While you can query and pull out certain field changes from the Contact History object, you may run into performance issues searching through and filtering the contact history object to pull out such field changes.
You may also want to retain some of the field change information without having the data be removed from Salesforce after a period of time. Field history is only kept for 18 months out of the box (unless you purchase Field History, which will increase record retention to 10 years).
Here are a few lessons learned from implementing this use case:
- Records are created in the ContactHistory out of the box object with some delay after a Contact record is saved. If you try and create the new record using the data from the ContactHistory object upon the saving the Contact record, it will pick up the previous field history change record.
- Salesforce only tracks field changes in the ContactHistory object, and does not record the original field value when the record was created. If you also want to capture the original field value, you will need to create this record based on information from the new contact.
- 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 noting the data stored in a custom field, noting where a visual flow is invoked from, the purpose of a flow variable, etc.
- For any data actions (fast and record lookup, create, update and delete actions) performed in visual workflow, best practice is to include a flow element to send an email to your Salesforce administrator about the fault.
Flow trick: To getting the Fault connector to appear, either draw the regular connector link to another flow element or connect it to a temporary flow element. Draw the fault connector to the Send Email element. Then, go back and delete the regular connector.
Business Use Case: Addison Dogster is a system administrator at Universal Container. Sammy Sunshine is a Marketing Manager who wants to keep track of customer email address changes made in Salesforce, including new email addresses, and does not want the field history records to be deleted after 18 months. Note: Email address is one of the many fields tracked for history on the Contact object.
Solution: Being the Awesome Admin that she is, Addison was able to help Sammy through declarative actions, no code. Her solution involves the creation of a new custom object to house the selected, duplicate contact history data, process builder and a visual flow.
Quick Steps:
1.Create a new custom object called Contact History Data (Create | Objects). If you want users to be able to navigate to the object, you will need to create a tab for the custom object (Create | Tabs, click on new used the Custom Objects section).
2. Create the following 5 custom fields in the Contact History under the Custom Fields & Relationships section.
For the Field custom field, the picklist item is “Email”. If you need to use track other field history items, just add them to the picklist. You can find out what the picklist value is by doing a data export of the ContactHistory object and looking at the values in the FieldType column.
Best practice tips:
- Don’t forget to provide a description so you and other/future admins know what these fields are used for.
- Set the FLS (field level security) for each profile. Only make the field visible and editable for the profiles that need it. Do not just click the “Next” button when you are on the screen.
- Select the page layouts that the new fields need to be added to. By fault, new fields are added to the page layout.
3. Create a visual workflow (Create | Workflows & Approvals | Flows). This flow to lookup the most recent email change record created in the ContactHistory object and create a new record in the Contact History Data custom object. This is an autolaunched flow invoked from process builder Update Contact History Data Object that we will create in Step 3.
A. We need to create 5 variables that will be used in the visual workflow per the screenshots below.
Best practice tip: Don’t forget to provide a description so you and other/future admins know what these variables are used for.
B. Create a Wait Element that pause the visual workflow for 0.01 hours. (Note: You can only set the unit to hours or days). Once it is 0.01hrs from the date/time stored in the variable varCurrentDateTime (which will be the Last Modified Date/Time of the contact record), it will then process with the flow.
C. Make sure this flow element is “Set as Start Element.”
D. Create a Record Lookup element that will lookup the ContactHistory object (this is where the Contact field history data is stored) where the ContactID matches the ContactID where the email was changed and the field matches the value stored in the FieldType variable, store the new and old values in the varNewValue and varOldValue variables. Note: We will be passing the varContactID and the varFieldType variables from the Process Builder created in Step 4.
Best practice tip: Don’t forget to provide a description so you and other/future admins know what the record lookup is supposed to do.
D. Create the Wait line to the Record Lookup flow element.
E. Create a Record Create flow element to create a new record in the Contact History Data custom object.
Best practice tip: Don’t forget to provide a description so you and other/future admins know what this record update flow will do.
F. As a best practice, where there is a DML action (fast or record create, update, delete or lookup action) in a flow, you should also include notification of a flow fault.
Note: To avoid “hardcoding” email addresses in a fault email, refer to a post Using Custom Metadata Type in Visual Workflow Fault Emails.
Select the Send Email flow element that is listed under Static Actions, not under Quick Actions.
Configure the body to show the fault message, subject and email address(es).
Body: Fault Message: {!$Flow.FaultMessage}
Subject: Error – Update Person Account Mailing Address
Best practice tip: Don’t forget to provide a description so you and other/future admins know what this send email element is supposed to do.
You will need to draw a connector line between the Record Lookup, Record Update and Send Email elements.
Can’t seem to get the fault connector to appear? Create a temporary flow element (circled below), draw your first connector to that temporary flow element. Then, draw another connector to the send element. This connector has the word “FAULT” in it.
Once that is completed, delete the temporary flow element you created. This is the end result.
G. Provide a name for your flow and ensure that the type is flow since this will be initiated via a button.
Best practice tip: Don’t forget to provide a description so you and other/future admins know what this visual flow is used for, where it is invoked from.
H. Click the “Close” button.
I. On the flows screen, activate the flow.
- Create a process builder (Create | Workflows & Approvals | Process Builder). Click on the New button.
Best practice tip: Don’t forget to provide a description so you and other/future admins know what this process builder is used for.
A. Select the Contact object and to start the process “only when a record is created” as we want to run this upon case record creation.
B. For the node criteria, provide the criteria name and the condition is the Contact’s email Is Changed is true.
C. In the Immediate Actions box, select to “Launch a Flow”, provide an action name, select the visual flow we created in Step 3 above. Set two flow variables.
- varContactID reference [Contact].Id
- varFieldType string Email
- varCurrentDateTime reference [Contact].LastModifiedDate
D. Create a second criteria node to cover when a contact is new. Since the field history will not record fields created by a new contact, we will create a new record into the Contact History Data object. Here, we need to set the criteria to formula which evaluates to true since we are not able to select a filter condition for a new contact. The formula we will use is ISNEW().
E. In the immediate action box, provide the action name and select Create a Record as the action. Set the object variables to match the ones in the screenshot below.
F. Click the Save button.
G. Click the Activate button in the upper right hand corner. Click the “Ok” button.
That’s it. Congrats, you’ve implemented the solution!
Now, before you deploy the changes to Production, you need to test your configuration changes.
1.Login as a user and create a new contact (make sure you provide the email address).
2. Upon save, confirm that a new record containing the new contact with the email field is created in the Contact History Data object.
3. Go back to the contact and update the email address. After 0.01hrs after the contact save, go to the Contact History Data object and confirm that a new record has been created showing the new and old email values.
4. Repeat the above steps for all profiles who can create/update contacts.
Deployment Notes/Tips:
- The new custom object, visual flow and process builder can be deployed to Production in a change set.
- The field level security for the custom fields will need to be manually updated post deployment. I would caution against adding the related profiles in the changeset for deployment as the results of deploying a profile are not reliable. If you have a tool like Snapshot by Dreamfactory, you can use the tool to deploy field permissions.
- Activate the visual flow and process builder after they are deployed in Production as they are deployed as inactive.
Nice solution which could address many different use-cases!
LikeLike
Thanks!
LikeLike
Hi Jenwlee,
Nice solution. It solution will also help when we have need to do a Report on Field History Tracking for Detail Object in Master-Detail Relationship
https://help.salesforce.com/articleView?id=000003727&language=en_US&type=1
Thanks,
Raj
LikeLike
You’re welcome, Raj!
LikeLike
Hi Jenwlee,
Can i know what is the reason you would like to use the process builder together with visual flow? with just process builder to trigger the record creation, should also be ok, right?
Thanks & Regards,
Shan
LikeLike
You have to wait for the activity to be written to the contact history object to take action. Flow offers a flexible wait element that you can use for the process to wait until a certain time to then proceed.
LikeLike
Hi Jenwlee,
Thanks for your reply. Actually i do not need to send the email notification. Just upon certain field update, store the past & new value into the custom object will do. Then Process builder itself should be enough, right?
Thanks
Shan
LikeLike
Yes, it should
LikeLike
This is of tremendous help to me; thank you!
This works perfect for “email”, as you described, but I am having some trouble duplicating this for other field values in the picklist. The record creation works without issue, but values other than the initial email do not update (I think the string value for varFieldType may be the issue). Any advice?
LikeLike
Hi Andrew, if you need help, can you please message me in the Trailblazer community. I may need to see screenshots to assist.
LikeLike