managing-cdc-enablement について
Salesforce の CDC サブスクリプション用メタデータを生成するスキルです。変更イベントを設定する開発者向けに、デフォルト/カスタムチャネル、拡張フィールド、フィルター式の形式要件を扱います。
主な機能
- 01PlatformEventChannelMember メタデータ生成
- 02カスタムチャネルのメタデータ生成
- 03標準・カスタムオブジェクトの購読
- 04拡張フィールドとフィルターの設定
- 05Metadata API の命名形式に準拠
活用シーン
- 01オブジェクトの変更データキャプチャ有効化
- 02オブジェクトのカスタムチャネル購読
- 03イベントへの参照フィールド追加
- 04変更イベントの条件フィルタリング
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ forcedotcom/ sf-skills --skill managing-cdc-enablementインストール後、Claude Code で/managing-cdc-enablementを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/PlatformEventChannel-template.xmlPlatformEventChannelMember-template.xmlreferences/deploy-troubleshooting.mdfilter-expressions.md詳細
Change Data Capture の有効化の管理
Salesforce オブジェクトを Change Data Capture に登録するメタデータを生成します。デフォルトの ChangeEvents チャネルまたはカスタムチャネル用の PlatformEventChannelMember ファイルと、新しいカスタムチャネル用の PlatformEventChannel ファイルが対象です。エンリッチメントフィールド、フィルター式、ならびに Metadata API が実際に受け付ける正規の名前と値の形式について説明します。これらは、多くの内部テスト用フィクスチャやコード検索結果に見られる値とは異なります。
対象範囲
- 対象範囲内:CDC 用の
PlatformEventChannelMemberおよびPlatformEventChannelメタデータの生成。標準オブジェクト、カスタムオブジェクト、またはその両方の登録。エンリッチメントフィールドの設定。フィルター式の設定。カスタムデータチャネルの定義。 - 対象範囲外:カスタムプラットフォームイベント(PE)の公開。これは別のメタデータ型(
PlatformEvent)です。Pub/Sub API または外部 Kafka/Bayeux の設定。料金や上限に関する案内 — ユーザーにはCDC Developer Guideを参照するよう案内してください。Apex でのプログラムによるイベントバスのサブスクライバー。
確認事項
生成を始める前に、まだ明確でない場合はユーザーに確認してください。
- CDC を有効にするエンティティはどれですか(複数可)?標準、カスタム、またはその両方ですか?
- デフォルトチャネル(
ChangeEvents)とカスタムチャネルのどちらですか?カスタムの場合、チャネルの表示ラベルは何ですか? - エンリッチメントフィールドは必要ですか?(値が変更されていない場合でも、コンシューマーが必要とする参照 ID です。)
- フィルター式は必要ですか?(どの変更イベントを出力するかを制御する SOQL WHERE 句の本体です。)
必要な入力
作業を進める前に、以下を収集するか推定してください。
- ソースエンティティの API 名 — 例:
Account、Lead、Order__c。スキル内部でこれをChangeEvent エンティティ名に変換します(ワークフローの手順 2 を参照)。 - チャネル —
ChangeEvents(デフォルト)または、末尾が__chnのカスタムチャネルの開発者名。 - エンリッチメントフィールド(任意) — すべての変更イベントに値を含めるソースオブジェクトのフィールド API 名のリスト。
- フィルター式(任意) — 変更イベントのペイロード内のフィールドに対する述語(例:
Status__c != null)。
特に指定がない場合のデフォルト:
- チャネル:
ChangeEvents(デフォルトの CDC チャネル — パスプレフィックスはありません)。 - エンリッチメントフィールド:なし。
- フィルター式:なし。
ユーザーの依頼が明確かつ完全であれば、不必要なやり取りをせず、ただちに生成してください。
ワークフロー
すべての手順を順番に実行してください。省略したり、順序を入れ替えたりしないでください。
何かを生成する前に、CDC で有効なメタデータ型が限られていることを把握してください。 CDC は、PlatformEventChannelMember(登録するエンティティごとに 1 つ)と PlatformEventChannel(カスタムチャネルの場合のみ)だけで表現されます。<ChangeDataCapture>、.changeDataCapture-meta.xml、changeDataCapture/ ディレクトリ、EnableChangeDataCapture、ManagedEventSubscription は使用しないでください。これらは CDC の対象範囲外です。これらのいずれかを書こうとしている場合は、そこで中止し、代わりに PlatformEventChannelMember ファイルを使用してください。
-
チャネルを特定する — ユーザーがカスタムチャネルを指定した場合は、
PlatformEventChannelファイルを生成します(手順 4 を参照)。それ以外の場合は、デフォルトチャネルにリテラル値ChangeEventsを使用します。 -
ソースエンティティを ChangeEvent エンティティ名に変換する —
<selectedEntity>はソースオブジェクトではなく、ChangeEvent 型です。ソースオブジェクト <selectedEntity>の値AccountAccountChangeEventLeadLeadChangeEventContactContactChangeEventOrder__c(カスタム)Order__ChangeEventMyThing__c(カスタム)MyThing__ChangeEvent標準オブジェクトの場合は、
ChangeEventを末尾に追加します。カスタムオブジェクトの場合は、末尾の__cを__ChangeEventに置き換えます(ダブルアンダースコアはそのまま残します)。 -
チャネルメンバーのファイルを生成します —
(entity, channel)のペアごとに1つのファイルを作成します。ファイル名とfullNameでは、エンティティのステムとChangeEventの間にアンダースコアを1つだけ使用します — これは、XML 本文内でのselectedEntityの形式とは無関係です。カスタムオブジェクトの場合、ファイル名を作成する際はソース名から__cを取り除きます。ソースオブジェクト ファイル名(および fullName) <selectedEntity>(XML 内)AccountAccount_ChangeEvent.platformEventChannelMember-meta.xmlAccountChangeEventLeadLead_ChangeEvent.platformEventChannelMember-meta.xmlLeadChangeEventOrder__cOrder_ChangeEvent.platformEventChannelMember-meta.xml(Order__ChangeEventではありません)Order__ChangeEventMyThing__cMyThing_ChangeEvent.platformEventChannelMember-meta.xml(MyThing__ChangeEventではありません)MyThing__ChangeEventカスタムオブジェクトの場合は間違いやすいので注意してください。ファイル名ではアンダースコアを1つ使い、
selectedEntityではアンダースコアを2つ維持します。構造のテンプレートとしてassets/PlatformEventChannelMember-template.xmlを読み込んでください。 -
カスタムチャネルの場合は、
PlatformEventChannelファイルを生成します — メンバーがデフォルト以外のチャネルを参照する場合に必要です。ユーザーが指定したラベルから DeveloperName を作成します。スペースと英数字以外の文字を取り除き、キャメルケースに変換してから、必ずリテラルのサフィックス__chnを追加します。デプロイ時のInvalid channel nameエラーを防ぐため、ファイル名とチャネルの<eventChannel>参照には、この形式を正確に使用する必要があります。ユーザーの指定 DeveloperName ファイル名 Partner SyncPartnerSync__chnPartnerSync__chn.platformEventChannel-meta.xml(Partner_Sync...またはPartnerSync...ではありません)Order UpdatesOrderUpdates__chnOrderUpdates__chn.platformEventChannel-meta.xmldata syncDataSync__chnDataSync__chn.platformEventChannel-meta.xmlこのチャネルのメンバーは、同じ DeveloperName で参照します:
<eventChannel>PartnerSync__chn</eventChannel>。assets/PlatformEventChannel-template.xmlを読み込んでください。 -
要求された場合は、エンリッチメントフィールドを追加します — フィールドごとに
<enrichedFields><name>FIELD_API_NAME</name></enrichedFields>ブロックを繰り返します。フィールド名は、ソースエンティティ上の1階層の API 名である必要があります。動作確認済みのフィールドは、標準の参照 ID(OwnerId、ParentId)、カスタム参照フィールド(MyLookup__c)、カスタムの非リレーションシップフィールド(Region__c、Status__c)です。Owner.NameやParent.Account.Industryのようなリレーションシップのたどり方は、デプロイ時に「The selected field, X.Y, isn't valid」というエラーで拒否されます。 -
要求された場合は、フィルター式を追加します — 述語を
<filterExpression>...</filterExpression>で囲みます。本体にはWHEREキーワードを含めず、WHERE 句の条件部分を記述します(例:Status__c != null。WHERE Status__c != nullではありません)。サポートされている演算子、フィールド型、注意点については、references/filter-expressions.mdを参照してください。
ルール/制約
| 制約 | 理由 |
|---|---|
<selectedEntity> は ChangeEvent の型名であり、ソースオブジェクト名ではありません | Metadata API はメンバーを ChangeEvent エンティティに関連付けます。Account を直接渡すと、「invalid event in selectedEntity」というエラーで失敗します。 |
メンバーの fullName ではアンダースコアを1つ使います:Account_ChangeEvent | アンダースコアを2つ使う形式(Account__ChangeEvent)は <namespace>__<name> として解析され、「Cannot create a new component with the namespace: Account」というエラーで拒否されます。 |
デフォルトチャネルの値は ChangeEvents そのものです。パスのプレフィックスは付けません | 古いフィクスチャや一部のドキュメントには data/ChangeEvents と記載されていますが、その値ではデプロイ時に「Unable to find the specified channel」が返されます。 |
| エンリッチメントフィールド名には、ソースエンティティ上の単一階層の API 名を使います | 標準フィールド(OwnerId)、カスタム参照フィールド(MyLookup__c)、カスタム非リレーションシップフィールド(Region__c)はいずれも検証に通ります。Owner.Name のようなトラバーサルは「The selected field, X.Y, isn't valid」というエラーで拒否されます。 |
<filterExpression> の本文に WHERE キーワードは含めません | デプロイ時に「filter expression has syntax errors: unexpected token: 'WHERE'」が返されます。 |
フィルターでは IsDeleted を参照できず、リレーションシップのトラバーサル(Owner.Username)もできません | デプロイ時に「field is invalid」というエラーで拒否されます。 |
DateTime フィールドのフィルターでサポートされるのは等価比較(=、!=)のみです。</> は使えません | デプロイ時に「Only equality operators are supported for this field type or value」が返されます。名前付き日付リテラルを使用してください:LastModifiedDate = TODAY。 |
| フィルターの右辺にはリテラルを指定します。フィールド同士の比較はできません | BillingCity = ShippingCity は「unexpected token: 'ShippingCity'」を返します。 |
複合フィールド(例:BillingAddress)をフィルターで使うには、ドット付きのコンポーネントアクセスが必要です | BillingAddress.City = 'X' はデプロイされます。フラットな BillingCity は「field is invalid」として拒否され、BillingAddress をそのまま使うと「has to be used with a component field」として拒否されます。これは、フラットな名前を使う <enrichedFields> とは逆であることに注意してください。 |
カスタムチャネルのファイル名は、メタ XML のサフィックスの前に __chn を付けます | Salesforce の MDAPI 命名規則です。一致しない場合、デプロイ時に曖昧さが生じます。 |
カスタムチャネル XML には <channelType>data</channelType> を含める必要があります | data を指定しないと、CDC 用チャネルとして拒否されます(ストリーミング/イベントチャネル用には他のタイプもあります)。 |
| ソースカスタムオブジェクトは、すでに存在しているか、同じトランザクションでデプロイされている必要があります | Foo__c の ChangeEvent エンティティは、Foo__c が存在するまで作成されません。そうでない場合、メンバーのデプロイは失敗します。 |
デフォルトの ChangeEvents チャネルに対して、PlatformEventChannel ファイルを生成してはいけません | デフォルトチャネルはシステムから提供されます。メンバーでは <eventChannel>ChangeEvents</eventChannel> で参照しますが、チャネルメタファイルが必要なのはカスタム(__chn)チャネルのみです。 |
PlatformEventChannelMember が受け付ける要素は4つのみです:<enrichedFields>、<eventChannel>、<filterExpression>、<selectedEntity> | <description>、<isActive>、<masterLabel>、その他の要素を追加すると、XML スキーマ検証で「Element {...} invalid at this location」というエラーが発生します。ドキュメントに記載されている4つの要素のみを使用してください。 |
PlatformEventChannel が受け付ける要素は2つのみです:<channelType> と <label> | <masterLabel>、<description> などを追加すると、「Element {...}masterLabel invalid at this location in type PlatformEventChannel」が発生します。<masterLabel> ではなく <label> を使用してください。 |
生成するのはメタデータファイルのみです。このスキルから sf project deploy start を実行してはいけません | このスキルは成果物を生成します。デプロイは別のライフサイクルで行います。 |
注意点
| 問題 | 解決方法 |
|---|---|
Unable to find the specified channel | <eventChannel>ChangeEvents</eventChannel> を設定します(data/ のプレフィックスは付けません)。 |
The PlatformEventChannelMember can't be created because it references an invalid event in the "selectedEntity" field | 元のオブジェクトではなく、ChangeEvent 名を使用します。Account ではなく AccountChangeEvent を指定します。 |
Cannot create a new component with the namespace: <Object> | ファイル名のアンダースコアを 1 つにします。Account__ChangeEvent... ではなく Account_ChangeEvent... にします。 |
The selected field, X.Y, isn't valid(<enrichedFields> 内) | Owner.Name を OwnerId に置き換えます。CDC が参照項目を自動的に拡充するため、検証に通るのは 1 段階の項目 API 名のみです。 |
filter expression has syntax errors: unexpected token: 'WHERE' | WHERE キーワードを削除します。本文には述語のみを記述します。 |
The BillingCity field in the filter expression is invalid(または、フラット形式の Address 構成項目) | 複合項目のドット形式を使用します。BillingCity ではなく BillingAddress.City を指定します。複合項目の一覧は references/filter-expressions.md を参照してください。 |
| カスタムオブジェクトのメンバーで「ChangeEvent doesn't exist」エラーが発生する | 元のオブジェクトがまだデプロイされていません。Foo__c オブジェクトのメタデータが同じデプロイに含まれているか、すでに組織に存在することを確認してください。 |
2 回目のデプロイで DUPLICATE_VALUE が発生する | メンバーはすでに登録されています。先に削除するか、処理をスキップしてください。CDC ではメンバーへの upsert は直接サポートされていません。 |
.changeDataCapture-meta.xml ファイルに対して sf infra error (TypeInferenceError, DeployMetadata): Could not infer a metadata type が発生する | そのファイル拡張子とメタデータ型は存在しません。changeDataCapture/<Entity>.changeDataCapture-meta.xml ファイルを platformEventChannelMembers/<Entity>_ChangeEvent.platformEventChannelMember-meta.xml ファイルに置き換えてください。 |
ユーザーが「Order__c を登録して」と言っているが、標準の Order を意味している | 確認してください。標準の OrderChangeEvent とカスタムの Order__ChangeEvent は別のエンティティです。 |
出力要件
成果物:
- 登録するエンティティごとに 1 つの
force-app/.../platformEventChannelMembers/<Entity>_ChangeEvent.platformEventChannelMember-meta.xml。 - カスタムチャネルごとに 1 つの
force-app/.../platformEventChannels/<DevName>__chn.platformEventChannel-meta.xml(該当する場合)。
ファイル構造は assets/ 内のテンプレートに従います。
生成されたファイルを受け取った後、ユーザーはデプロイ前に sf project deploy start --dry-run -d <path> --target-org <alias> を実行して検証できます。ドライランで見慣れないエラーが発生した場合は、references/deploy-troubleshooting.md に一般的なデプロイエラーと、メタデータ側での修正方法が記載されています。
スキル間の連携
| 必要な作業 | 委任先 |
|---|---|
| 元となるカスタムオブジェクトの生成 | generating-custom-object スキル |
| 拡充またはフィルターで参照するカスタム項目の生成 | generating-custom-field スキル |
| 変更イベントを利用するユーザー向けの権限セットの作成 | generating-permission-set スキル |
参考ファイル一覧
| ファイル | 読むタイミング |
|---|---|
assets/PlatformEventChannelMember-template.xml | ステップ 3 — チャネルメンバーのベースとなる構造 |
assets/PlatformEventChannel-template.xml | ステップ 4 — カスタムチャネルのベースとなる構造 |
references/filter-expressions.md | ステップ 6 — フィルター式を記述する際に、サポート対象の演算子と項目型の一覧を確認する |
references/deploy-troubleshooting.md | ユーザーからドライランでのデプロイエラーについて報告があり、原因の診断を求められた場合 |