First, some quick background. I'm aware there are several different ways this could be solved. Platform events, Queueables, batch jobs, etc... For now I'm specifically interested in how this would be done using Change Data Capture events.
I have a custom object that is part of a managed package. Whenever there is a change to a specific field on records from this custom object I need to run an expensive process to bring some of the data into sync with an external system. It will likely involve several callouts given the capabilities of the external API.
As such, the callouts can't be done immediately in the transaction where the update occurs. So they should be processed asynchronously after the record is changed, but this should be reasonably timely.
I'm experimenting with using an Apex trigger on the Change Data Capture event of the custom object. I have the change capture trigger setup to detect changes to the field of interest and build up a set of record IDs that need further processing. This all gets passed off to an asynchronous method that can make the required callouts etc...
The problem I'm having is how to include this Change Data Capture trigger in a managed package and make if fire after installing the package.
When I create a new package version I'm forced to include the change event trigger. That's odd, as nothing in the package explicitly references the __ChangeEvent
after insert trigger. But I want it in the package anyway, so whatever.
That deploys fine along with the associated test cases that use Test.enableChangeDataCapture();
and Test.getEventBus().deliver();
.
What isn't getting packaged are the CdcObjectEnablement
records that are configured under "Change Data Capture" in setup (See Select Objects for Change Notifications). Without the custom object being included in the "Selected Entities" the change event trigger won't fire. I'd have to manually activate this set in each subscriber org where I want to change event to fire.
I can't figure out where this configuration is stored in the metadata or which sObject is used to represent it. I have my suspicions about PlatformEventChannelMember (0v8), but I can't access it.