In a previous post I showed how to update the Lead or Contact related to a Task when the activity was logged. That solution only supports updating the primary Lead or Contact (Task.WhoId).

But what if you have Shared Activities enabled and there are 3, 10, 50 Contacts or Leads related to the Task? How do we update all the related records not just the primary one? That is what fellow reader Elias Letsios asked too. In this post I show you my solution for supporting Shared Activities.


NOTE: This solution requires “Shared Activities” enabled in Setup | Activities | Activity Settings. If you do not have this feature enabled then please see my other post How to Update Lead or Contact When Activity Logged.


Getting Started

The solution I developed, available on my GitHub repo, includes one Process Builder, one Flow, and for a small (but important) step, one invocable Apex class.

  1. Enable Shared Activities in Setup | Activities | Activity Settings
  2. Deploy the process, flow, and apex classes to your org:
    • “Update Contact/Lead Task Relations” (Process Builder)
    • “Update Contact/Lead Task Relations Flow” (Flow)
    • “GetTaskWhoRelationSObjectsInvocable” (Apex)
  3. Since TaskRelation records are created asynchronously, wait for the Process Builder scheduled action to complete (usually within a minute)
  4. Navigate to any of the Contacts related with your activity and note the description has changed to “Has been related to a Task.” (the specific field updates are customizable which we discuss later)

Flow Overview


The Flow kicks off in the top-left by querying for TaskRelation records related to the Task input variable that just got logged.

The second step is where our invocable Apex class comes into play to determine which relations are Contacts vs. Leads. More about why this is necessary in the next section below.

After that there are two main blocks in the Flow as outlined in green and blue in the above screen shot focused on looping through the related Contacts (or Leads) and assigning field updates before performing a Fast Update on the sobject collection variables.

Out of the box, the field updates (outlined in red in the above screen shot) simply set the Contact or Lead Description field to “Has been related to a Task.” Those Assignment elements are where you customize the Flow to your field update logic. Here you can either (a) do all your desired field updates in the Flow, or (b) update a custom Date/Time field specific to this solution and when the Contacts/Leads get updated then leverage another Process Builder you create that monitors for the custom Date/Time to change to do any other field updates or actions you desire. I recommend option B as that keeps the business logic outside of the mechanics of identifying which Contacts and Leads to update.

Why the #LowCode with Apex and not just #NoCode?

Unfortunately, Flow does not let you assign values to ID field of SObject Variables. So even though our Flow makes an initial query to learn all the Contact or Lead IDs related to the Task, there is no way to create SObject Variables with those IDs without either:

  • making a Fast Lookup inside a loop (no code, but not bulk friendly), or
  • invoking an Apex class to generate the SObject Variables for you (low code, but bulk friendly)

I chose the second option for performance reasons.

So after the first step in the Flow to query for the TaskRelations, we pass those records to the invocable Apex class to get a Contacts and Leads SObject Collection Variables.



Why do you use Scheduled Actions and not Immediate Actions in Process Builder?


Process Builder has to launch the Flow as a Scheduled Action because TaskRelations / TaskWhoRelations records are created after a delay by Salesforce and not immediately available.

If the Flow were to run as an Immediate Action then likely only the primary Contact/Lead (Task.WhoId) would be updated but the other related records would not (or at least be very inconsistent) because the Flow would not find them when the Fast Lookup step ran.