Skip to main content
3 月 5 日~ 6 日にサンフランシスコで開催される TDX (Salesforce+ でも配信) で「Developer Conference for the AI Agent Era (AI エージェント時代に向けた開発者向けカンファレンス)」にぜひご参加ください。お申し込みはこちら

Apex トリガーを使用した変更イベントへの登録

学習の目的

この単元を完了すると、次のことができるようになります。

  • Apex トリガーを記述して変更イベントに登録する。
  • Salesforce で更新を行い、変更イベント通知を生成する。
  • デバッグログのトリガーからデバッグログメッセージを検証する。
メモ

メモ

日本語で受講されている方へ
Challenge は日本語の Trailhead Playground で開始し、かっこ内の翻訳を参照しながら進めていってください。Challenge での評価は英語データを対象に行われるため、英語の値のみをコピーして貼り付けるようにしてください。日本語の組織で Challenge が不合格だった場合は、(1) この手順に従って [Locale (地域)] を [United States (米国)] に切り替え、(2) [Language (言語)] を [English (英語)] に切り替えてから、(3) [Check Challenge (Challenge を確認)] ボタンをクリックしてみることをお勧めします。

翻訳版 Trailhead を活用する方法の詳細は、自分の言語の Trailhead バッジを参照してください。

ここまでに、Pub/Sub API を使用して変更イベントに登録する方法を学習しました。Apex トリガーは、変更イベントに登録するもう 1 つの方法です。では、詳しく見ていきましょう。

変更イベントの非同期 Apex トリガー

Apex トリガーを使用して、Lightning プラットフォームの変更イベントに登録できます。変更イベントの Apex トリガーは Salesforce オブジェクトの Apex トリガーと似ていますが、いくつかの点が異なります。Salesforce オブジェクトの Apex トリガーと同様に、Salesforce オブジェクトに対応する変更イベントに変更イベントトリガーを定義します。after insert トリガーのみがサポートされています。 

変更イベントトリガーは、変更イベントに after insert キーワードを指定し、次の形式で定義します。

trigger TriggerName on ChangeEventName (after insert) {
}

AccountChangeEvent オブジェクトの例を次に示します。これは、取引先に対応する変更イベントです。

trigger MyAccountChangeTrigger on AccountChangeEvent (after insert) {
}

1 つの変更イベントまたは変更イベントのバッチを受信すると、変更イベントトリガーが起動します。変更イベントトリガーは、オブジェクトトリガーとは異なり、データベーストランザクションの完了後に非同期で実行されます。変更イベントトリガーは非同期で実行されるため、大量のリソースを消費するビジネスロジックに適しています。他方、トランザクションベースのロジックは引き続きオブジェクトトリガーで実行します。変更イベントトリガーでは、変更の処理を分離することでトランザクションの処理時間を短縮できます。

変更イベントトリガーには、次の特性があります。

  • 自動化プロセスエンティティの下で実行される。そのため、トリガーのデバッグログが自動プロセスエンティティによって作成され、CreatedById や OwnerId などのシステム項目が自動プロセスを参照します。
  • Apex 非同期ガバナ制限が適用される。
  • 最大バッチサイズはイベントメッセージ 2,000 件 (Trigger.New の項目数) である。

Apex 変更イベントのレコード項目とヘッダー項目

変更イベントメッセージの項目は静的に定義されるため、他の Apex 型と同様に、すべてのレコード項目が記載されます。Apex 変更イベントメッセージには空 (null) の項目も記載できます。null になるのは、変更のない項目と、更新で明示的に null に設定された項目です。 

どの項目が変更されたかを知るには、changedFields ヘッダー項目を使用します。これには、更新操作で変更されたレコード項目のリストが含まれています。この単元のトリガーの例では、changedFields 項目を使用して、どの項目が更新または削除されたのかを判断する方法を示します。

メモ

changedFields ヘッダー項目は、API バージョン 47.0 以降を使用して保存された Apex 変更イベントトリガーで使用できます。

変更イベントトリガーの作成

変更イベントトリガーを追加する手順は、Salesforce オブジェクトにトリガーを追加するのと同じくらい簡単です。開発者コンソールを使用して、以前に作成した Employee (従業員) カスタムオブジェクトに関連付けられている変更イベントのトリガーを作成します。カスタムオブジェクトの作成時に、Employee__ChangeEvent という変更イベントオブジェクトが作成されます。 

メモ

次の手順では、最初に Employee__c カスタムオブジェクトを作成する必要があります。前の単元の手順に従って、このカスタムオブジェクトを作成します。 

開発者コンソールを使用して変更イベントトリガーを作成する手順は、次のとおりです。

  1. クイックアクセスメニュー (クイックアクセスメニュー) をクリックします。
  2. [開発者コンソール] をクリックします。
  3. 開発者コンソールで、[File (ファイル)] | [New (新規)] | [Apex Trigger (Apex トリガー)] を選択します。
  4. [Name (名前)] 項目に、EmployeeChangeTrigger というトリガーの名前を入力します。
  5. ドロップダウンから、Employee (従業員) カスタムオブジェクトの変更イベントオブジェクト (Employee__ChangeEvent) を選択します。after insert キーワードを指定したトリガーが作成されます。
  6. デフォルトのコンテンツを次のコードに置き換えます。
trigger EmployeeChangeTrigger on Employee__ChangeEvent (after insert) {
  List<Task> tasks = new List<Task>();
  // Iterate through each event message.
  for (Employee__ChangeEvent event : Trigger.New) {
    // Get some event header fields
    EventBus.ChangeEventHeader header = event.ChangeEventHeader;
    System.debug('Received change event for ' +
      header.entityName +
      ' for the ' + header.changeType + ' operation.');
    // For update operations, we can get a list of changed fields
    if (header.changetype == 'UPDATE') {
        System.debug('List of all changed fields:');
        for (String field : header.changedFields) {
            if (null == event.get(field)) {
                System.debug('Deleted field value (set to null): ' + field);
            } else {
                System.debug('Changed field value: ' + field + '. New Value: '
                    + event.get(field));
            }
        }
    }
    // Get record fields and display only if not null.
    System.debug('Some Employee record field values from the change event:');
    if (event.First_Name__c != null) {
      System.debug('First Name: ' + event.First_Name__c);
    }
    if (event.Last_Name__c != null) {
      System.debug('Last Name: ' + event.Last_Name__c);
    }
    if (event.Name != null) {
      System.debug('Name: ' + event.Name);
    }
    if (event.Tenure__c != null) {
      System.debug('Tenure: ' + event.Tenure__c);
    }
    // Create a followup task
    Task tk = new Task();
    tk.Subject = 'Follow up on employee record(s): ' +
    header.recordIds;
    tk.OwnerId = header.CommitUser;
    tasks.add(tk);
  }
  // Insert all tasks in bulk.
  if (tasks.size() > 0) {
    insert tasks;
  }
}

Trigger.New で変更イベントメッセージを受信するたびにこの変更イベントトリガーが反復処理されます。イベントごとに、トリガーがいくつかのヘッダー項目を取得します。操作が更新の場合は、トリガーが nulledFields ヘッダー値にアクセスして、変更された項目のリストも取得します。null でない場合は、トリガーにレコード項目値が表示されます。最後に、新しい Employee (従業員) レコードのフォローアップ ToDo が作成されます。

メモ

ユーザーインターフェースで変更イベントトリガーを作成できるのは、開発者コンソールから作成する場合のみです。変更イベントオブジェクトは、Lightning Experience のオブジェクトマネージャーにも、Salesforce Classic の [設定] にもリストされません。 

変更イベントトリガーの実行の検証

ここで、トリガーが機能していることを手動で検証します。トリガーでイベントメッセージを受信するには、まず [設定] の [変更データキャプチャ] でオブジェクトを有効にします。前のステップですでに Employee (従業員) の通知を有効にしているため、ここではそのステップを省略できます。自動プロセスエンティティの下にデバッグログが作成されるので、[設定] でこのエンティティのデバッグログを有効にして、ログが収集されるようにします。

  1. 新しいタブで [設定] を開くには、クイックアクセスメニュー (クイックアクセスメニュー) をクリックして、[設定] をクリックします。
  2. [Setup (設定)] から、[Quick Find (クイック検索)] ボックスに Debug Logs (デバッグログ) と入力し、[Debug Logs (デバッグログ)] を選択します。
  3. [新規] をクリックします。
  4. [追跡対象エンティティ種別] で、[自動化プロセス] を選択します。
  5. ログの収集期間を選択します。開始日と終了日は、デフォルトで現在の日時に設定されます。終了日入力ボックスをクリックし、カレンダーから翌日を選択して、終了日を延長します。
  6. [デバッグレベル] で、[新しいデバッグレベル] をクリックします。名前に CustomDebugLevel と入力し、デフォルトを受け入れます。
  7. [Save (保存)] をクリックします。

またすぐデバッグログに戻ってくるため、[設定] の [デバッグログ] ページを開いたままにします。次に、Salesforce で何らかの変更を行って、変更イベントトリガーを起動します。Employee (従業員) レコードを作成して更新します。

  1. 新しいタブでアプリケーションランチャー (アプリケーションランチャー) をクリックし、[Employees (従業員)] を見つけて選択します。
  2. [新規] をクリックします。
  3. 次の項目に入力します。
    • Employee Name (従業員名): e-200
    • Last Name (姓): Smith
    • First Name (名): Joseph
    • Tenure (在職期間): 1
  1. [Save (保存)] をクリックします。
  2. 従業員レコードの詳細ページで、[編集] をクリックします。
  3. [First Name (名)] 項目を Joe に変更します。
  4. [Tenure (在職期間)] の値を削除します。
  5. [保存] をクリックします。
  6. [デバッグログ] タブに切り替えて、ブラウザーを更新します。
  7. レコード作成に対応するデバッグログを表示する場合は、リストの 2 つ目のログの横にある [表示] をクリックします (ログは新しい順に並べられています)。System.debug ステートメントの出力は、次のようになります。
...|DEBUG|Received change event for Employee__c for the CREATE operation.
...|DEBUG|Some Employee record field values from the change event:
...|DEBUG|First Name: Joseph
...|DEBUG|Last Name: Smith
...|DEBUG|Name: e-200
...|DEBUG|Tenure: 1.0
  1. レコード更新に対応するデバッグログを表示する場合は、リストの 1 つ目のログの横にある [表示] をクリックします。System.debug ステートメントの出力は、次のようになります。レコードが更新されると、システムが LastModifiedDate 項目を更新するため、この項目は変更された項目の一部としてリストされます。
...|DEBUG|Received change event for Employee__c for the UPDATE operation.
...|DEBUG|List of all changed fields:
...|DEBUG|Changed field value: LastModifiedDate. New Value: 2019-09-26 20:53:29
...|DEBUG|Changed field value: First_Name__c. New Value: Joe
...|DEBUG|Deleted field value (set to null): Tenure__c
...|DEBUG|Some Employee record field values from the change event:
...|DEBUG|First Name: Joe

おめでとうございます。変更イベントトリガーを作成し、ユーザーインターフェースで正常に機能していることを確認しました。次の単元では、変更イベントトリガーの Apex テストを記述して、トリガーのテストを自動化する方法を学習します。

リソース

ハンズオン Challenge

+500 ポイント

準備を始めましょう

この 単元 は各自のハンズオン組織で実行します。[起動] をクリックして開始するか、組織の名前をクリックして別の組織を選びます。

あなたの Challenge

Write a Change Event Trigger
Create a change event trigger that captures changes on opportunities and creates a follow-up task for opportunities whose stage is set to 'Closed Won'.
  • Create an Apex trigger modeled after the EmployeeChangeTrigger example trigger:
    • Name: OpportunityChangeTrigger
    • Object: OpportunityChangeEvent
  • Copy the body of the EmployeeChangeTrigger example trigger. Delete everything after the if statement for the header, starting with the System.debug statements.
  • Modify the for loop so it iterates over every received OpportunityChangeEvent. For each event, if the header changeType field is 'UPDATE', check if event.isWon field is equal to true. You will end up with the following if statement:
    • if ((header.changetype=='UPDATE') && (event.isWon==true)) { // Create a task }
  • Inside the new if statement block, add these lines to create a task.
    • Task tk = new Task();
    • tk.Subject = 'Follow up on won opportunities: ' + header.recordIds;
    • tk.OwnerId = header.CommitUser;
    • tasks.add(tk);
  • Insert the task list after the end of the for loop.
    • if (tasks.size() > 0) {
    • insert tasks;
    • }
Salesforce ヘルプで Trailhead のフィードバックを共有してください。

Trailhead についての感想をお聞かせください。[Salesforce ヘルプ] サイトから新しいフィードバックフォームにいつでもアクセスできるようになりました。

詳細はこちら フィードバックの共有に進む