Opportunity Contact Roles are records that link contacts to an opportunity so one knows the people involved in the deal and their roles. However, Salesforce doesn’t let it have triggers or Rollup Summaries on Opportunities or Contacts from it. This prevents common customization options that are allowed on most other standard and custom objects.

In this post I’ll show you how to implement an Opportunity Rollup Summary using the Declarative Lookup Rollup Summary (DLRS) tool and an Opportunity Contact Role Change Data Capture Trigger to invoke the rollup. There are some limitations so please read carefully.

High-Level Steps

  1. Enable Change Data Capture on “Opportunity Contact Role”.
  2. Create OCRService Apex Class.
  3. Create an OpportunityContactRoleChangeEvent Trigger.
  4. Create OCRServiceTest Test Apex Class.
  5. Configure the desired Opportunity and Contact lookup rollup summaries.

Enable Change Data Capture on Opportunity Contact Role

  1. Open “Change Data Capture” in Setup as an Admin.
  2. Select Opportunity Contact Role as a Selected Entity.
  3. Save

Create OCRService Class

Create the OCRService apex class below so that the code is in a separate class and not in a trigger. It’s also needed because it seems that the DLRS code isn’t able to find the lookup rollup summary records unless without sharing is used. This seems to be because the trigger runs using the Automated Process user.

This code is run from the OpportunityContactRoleChangeEvent trigger and is only run after an OpportunityContactRole is inserted, updated, deleted or undeleted and committed to the database. This code fetches all the Opportunity Contact Role Ids that were changed in the database, queries those records, and then invokes the “Developer” declarative lookup rollup summaries on the Opportunity Contact Role.

Big Limitation

For some reason, it seems that deleted Opportunity Contact Roles are not put in the recycle bin and are purged from the database so even though this code attempts to fetch the deleted ones, they aren’t actually fetched. This prevents deleted Opportunity Contact Roles from triggering the DLRS to update the parent records. To get around this, schedule the desired declarative lookup rollup summaries to run on some interval.

Create OpportunityContactRoleChangeEventTrigger

From the Developer Console, create the following trigger to run the OCRService code.

Create OCRServiceTest Test Class

Create the following test class to test the code so it can be deployed to production.

Install Declarative Lookup Rollup Summary Tool

If needed, install the Declarative Lookup Rollup Summary package using the desired Production or Sandbox links under Packaged Release History.

Create Opportunity Declarative Lookup Example

One best practice is to keep track of the people involved in a deal. To ensure this, management and sales reps need to know which deals have opportunity contact roles or not. To make this easier to report on, a “Number of Contacts” custom number field was added to the Opportunity. (API Name: Number_of_Contacts__c). Now we have to configure a declarative lookup rollup summary to do this.

  1. Open “Manage Lookup Rollup Summaries” tab.
  2. Enter the following values
    • Lookup Rollup Summary Name: OCR Number of Contacts
    • Lookup … Unique Name: OCR_Number_of_Contacts
    • Parent Object: Opportunity
    • Child Object: OpportunityContactRole
    • Relationship Field: OpportunityId
    • Field To Aggregate: Id
    • Aggregate Result Field: Number_of_Contacts__c
    • Calculation Mode: Developer
    • Calculation Sharing Mode: System
  3. Save
  4. Check Active checkbox.
  5. Save

Now insert and update opportunity contact roles and the DLRS code will be invoked.

NOTE: Since we are programmatically invoking the DLRS code, only “Developer” DLRSes are used. These are ones with a calculation mode of “Developer”.


  • One can aggregate information from opportunity contact roles to opportunity and contact records in near real time with a little bit of code and then via declarative lookup rollup summary (DLRS) configuration.


  • Deleted Opportunity Contact Roles won’t fire the DLRS calculation because the deleted opportunity contact role records aren’t in the recycle bin. To get around this, schedule the desired DLRS configurations on a regular interval.
  • The DLRS code runs asychronously so the aggregated fields aren’t updated immediately after save but usually within a few minutes depending on data volume and service availability.

There are probably other limitations as well so please share in the comments.

Let me know if this was helpful by leaving a comment.


1 thought on “Opportunity Contact Role Rollups Using Change Data Capture”

Leave a Reply

Your email address will not be published. Required fields are marked *