プラットフォームイベントの登録

学習の目的

この単元を完了すると、次のことができるようになります。
  • プラットフォームイベントメッセージの登録方法を説明する。
  • プラットフォーム上と外部アプリケーション内のイベントに登録する。
  • Apex テストメソッドでプラットフォームイベントをテストする。
  • CometD を介してプラットフォームイベントに登録する。

プラットフォームイベントの登録

プラットフォームイベントの公開方法は確認できましたが、プラットフォームイベントに登録して最新のニュースや荷物の配送の通知を受け取るにはどうすればよいのでしょうか? Salesforce Platform では、Apex トリガー、プロセス、フローです。empApi Lightning コンポーネントと Visualforce アプリケーションでは、CometD を通じてイベントを受信します。外部アプリケーションでも、CometD を使用してイベントに登録します。

Apex トリガーを使用したプラットフォームイベント通知の登録

皆さんはおそらくすでに Apex トリガーを使用してデータベースイベントに基づくアクションを実行したことがあるでしょう。プラットフォームイベントでも、プロセスは似ています。受信イベントに登録するには、イベントオブジェクトに対する after insert トリガーを記述するだけです。トリガーは、Apex での自動登録メカニズムを提供します。チャネルの作成とリスンを明示的に行う必要はありません。トリガーは、Apex と API のどちらで公開されていても、さまざまなソースからイベント通知を受信します。

プラットフォームイベントは after insert トリガーのみをサポートします。after insert トリガーイベントは、プラットフォームイベントが公開された後のタイミングに対応します。イベントメッセージが公開されると、after insert トリガーが起動されます。

プラットフォームイベントトリガーを作成するには、開発者コンソールを使用します。

  1. [設定] アイコンをクリックし、[開発者コンソール] を選択し、[File (ファイル)] | [New (新規)] | [Apex Trigger (Apex トリガー)] をクリックします。
  2. 名前を指定し、sObject のイベントを選択して [Submit (送信)] をクリックします。

開発者コンソールにより、トリガーテンプレートに after insert イベントが自動的に追加されます。さらに、[設定] のイベントの定義ページから [トリガー] 関連リストで簡単にトリガーを作成できますが、after insert キーワードを指定する必要があります。

次の例は、Cloud News イベントのトリガーを示します。各イベントを反復処理し、Urgent__c 項目でニュースが緊急かどうか確認します。ニュースが緊急の場合、トリガーはケースを作成して、ニュースレポーターを派遣し、イベントの場所をケースの件名に追加します。

メモ

この例を実行する前に、キューを作成し、表示ラベルを「Regional Dispatch」 (地域派遣) に設定します。キューを設定する方法については、Salesforce ヘルプ「キューの設定」を参照してください。キューを表す Group オブジェクトについての詳細は、『Salesforce および Lightning プラットフォームのオブジェクトリファレンス』「Group」を参照してください。この例では、ケースをキューに割り当てます。キューはプラットフォームイベントに含まれておらず、プラットフォームイベントを使用するためにキューを使用する必要はありません。ケースをキューに割り当てると、キューのメンバーであるサポートエージェントのチームにケースを振り分けられるようになります。

// Trigger for listening to Cloud_News events.
trigger CloudNewsTrigger on Cloud_News__e (after insert) {
    // List to hold all cases to be created.
    List<Case> cases = new List<Case>();
    // Get queue Id for case owner
    Group queue = [SELECT Id FROM Group WHERE Name='Regional Dispatch' AND Type='Queue'];
    // Iterate through each notification.
    for (Cloud_News__e event : Trigger.New) {
        if (event.Urgent__c == true) {
            // Create Case to dispatch new team.
            Case cs = new Case();
            cs.Priority = 'High';
            cs.Subject = 'News team dispatch to ' +
                event.Location__c;
            cs.OwnerId = queue.Id;
            cases.add(cs);
        }
   }
    // Insert all cases corresponding to events received.
    insert cases;
}

デバッグログの設定

標準またはカスタムオブジェクトのトリガーとは異なり、プラットフォームイベントのトリガーは、イベントを公開した Apex トランザクションと同じトランザクションでは実行されません。トリガーは、システムユーザーである自動化プロセスエンティティの下の独自プロセスで実行されます。そのため、トリガー実行に対応するデバッグログは自動化プロセスエンティティによって作成され、開発者コンソールでは使用できません。プラットフォームイベントトリガーログを収集するには、[設定] で追跡フラグエントリを自動化プロセスエンティティに追加します。

  1. [設定] から、[クイック検索] ボックスに「デバッグログ」と入力し、[デバッグログ] をクリックします。
  2. [新規] をクリックします。
  3. [追跡対象エンティティ種別] で、[自動化プロセス] を選択します。
  4. 収集するログの開始時刻と有効期限を選択します。
  5. [デバッグレベル] に「*」と入力し、[検索] をクリックします。
  6. 事前定義されたデバッグレベル (SFDC_DevConsole など) を選択するか、[新規] をクリックして独自のデバッグレベルを作成します。
  7. [保存] をクリックします。
メモ

Apex テストのデバッグログは例外です。同じテスト実行ログにイベントトリガーのログが含まれます。

プラットフォームイベントトリガーに関する留意点

イベント処理の順序
トリガーは、プラットフォームイベント通知を受信した順序で順次処理します。イベントの順序は、イベントの再実行 ID に基づきます。Apex トリガーはイベントのバッチを一度に受信できます。イベントの順序は、各バッチ内に保持されます。バッチ内のイベントの発信元は、1 つ以上の公開者である可能性があります。

非同期のトリガー実行
プラットフォームイベントトリガーは、独自のプロセス内で非同期に実行され、イベントを公開したトランザクションには含まれません。そのため、イベントが公開されてからトリガーがイベントを処理するまでの間に遅延が発生することがあります。トリガーの実行結果がイベント公開の直後に使用可能になると想定しないでください。

自動化プロセスシステムユーザー
プラットフォームイベントトリガーは、トリガーを実行するユーザー (実行ユーザー) の下では実行されず、自動化プロセスシステムユーザーの下で実行されるため、CloudNewsTrigger の例では、所有者 ID 項目が明示的に設定されています。このトリガーの例では、Regional Dispatch というサンプルユーザーキューの ID が使用されています。ケースや商談など、OwnerId 項目がトリガーにある Salesforce レコードを作成する場合、明示的に所有者 ID を設定してください。ケースとリードの場合、代わりに割り当てルールを使用して所有者を設定できます。

また、イベントトリガーで作成または更新されたレコードのシステム項目 (CreatedByIdLastModifiedById など) は、自動化プロセスエンティティを参照します。同様に、Apex の UserInfo.getUserId() ステートメントは自動化プロセスエンティティを返します。

メモ
プラットフォームイベントトリガーの実行ユーザーを上書きし、トリガーが自動化プロセスではなくそのユーザーの下で実行されるようにできます。トリガーを設定するには、メタデータ API または Tooling API の PlatformEventSubscriberConfig を使用します。詳細は、『プラットフォームイベント開発者ガイド』「プラットフォームイベントトリガーのユーザーとバッチサイズの設定」を参照してください。
Apex ガバナ制限
標準またはカスタムオブジェクトトリガーと同様、プラットフォームイベントトリガーには、Apex ガバナ制限が適用されます。

Apex トリガーの制限
プラットフォームイベントトリガーは、カスタムおよび標準オブジェクトトリガーと同じ制限の多くを共有します。たとえば、トリガーから Apex コールアウトを同期して実行することはできません。

トリガーバッチサイズ
プラットフォームイベントトリガーのバッチサイズはイベントメッセージ 2,000 件で、Salesforce オブジェクトトリガーのバッチサイズの 200 より大きくなっています。バッチサイズは Trigger.New リストのサイズに対応します。プラットフォームイベントトリガーのバッチサイズは変更できます。詳細は、『プラットフォームイベント開発者ガイド』「プラットフォームイベントトリガーのユーザーとバッチサイズの設定」を参照してください。

[設定] のプラットフォームイベント定義詳細ページでは、すべてのイベントトリガーの状態を表示できます。[登録] の下で、有効なトリガーのそれぞれが、実行情報および状態と一緒にリストされます。情報には、最終公開イベントや最終処理イベントの再実行 ID が含まれます。状態は、トリガーが実行中であるか、復旧できないエラーや不十分な権限により登録から切断されているかを示します。トリガーの最大試行回数に達した場合にのみ、エラー状態になります。次のスクリーンショットは、Cloud News イベント詳細ページの [登録] 関連リストを示します。

メモ
  • [登録] 関連リストには、イベントに登録しているフローとプロセスも表示されます。
  • [登録] 関連リストには、CometD、Pub/Sub API、empApi Lightning コンポーネントを使用する登録者は含まれません。他の種別の登録者については、この単元で後ほど説明します。
  • 大規模プラットフォームイベントの場合、[最終公開 ID] の値は使用できず、常に「利用できません」と表示されます。

イベントの Apex トリガーの登録者の管理

一時停止した登録を停止した場所 (イベントバスで使用可能な最も古いイベントメッセージ) から再開できます。エラーの原因となったイベントメッセージや、不要となったメッセージをバイパスしたい場合は、登録を最新のイベントメッセージから再開できます。

トリガー登録を管理するには、[登録] 関連リストで、Apex トリガーの横にある [管理] をクリックします。

登録詳細ページで、適切なアクションを選択します。
  • 実行中の登録を一時停止するには、[サスペンド] をクリックします。

  • 一時停止した登録をイベントバスで使用可能な最も古いイベントメッセージから再開するには、[再開] をクリックします。
  • 一時停止した登録を最新のイベントメッセージから再開するには、[Resume from Tip (最新から再開)] をクリックします。


フローとプロセスの登録は、[登録] 関連リストでは管理できません。

メモ

トリガーを保存すると、トリガー登録が自動的に再開されます。詳細は、『プラットフォームイベント開発者ガイド』「プラットフォームイベントの詳細ページでのイベントの登録者の表示」を参照してください。

プラットフォームイベントトリガーのテスト

Apex テストを追加して、プラットフォームイベントトリガーが適切に機能することを確認します。Apex コード (トリガーを含む) をパッケージ化または本番環境にリリースする前に、Apex コードをテストする必要があります。Apex テストでプラットフォームイベントを公開するには、publish ステートメントを Test.startTest および Test.stopTest ステートメントで囲みます。

// Create test events
Test.startTest();
// Publish events
Test.stopTest();
// Perform validation here

テストコンテキストで、publish メソッドコールが公開操作をキューに登録します。Test.stopTest() ステートメントにより、イベント公開が実行されます。Test.stopTest() の後に検証を実行します。

次に、Cloud_News イベントのテストクラスと関連付けられたトリガーの例を示します。イベントを公開すると、関連付けられたトリガーが起動します。Test.stopTest() の後、テストでは isSuccess() によって返された Database.SaveResult の値を調べて公開が成功したことを確認します。テストではまた、トリガーが作成したケースを照会します。ケースレコードが見つかった場合、このトリガーは正常に実行され、テストは合格です。

@isTest
public class PlatformEventTest {
    @isTest static void test1() {
        // Create test event instance
        Cloud_News__e newsEvent = new Cloud_News__e(
            Location__c='Mountain City',
            Urgent__c=true,
            News_Content__c='Test message.');
        Test.startTest();
        // Call method to publish events
        Database.SaveResult sr = EventBus.publish(newsEvent);
        Test.stopTest();
        // Perform validation here
        // Verify that the publish was successful
        System.assertEquals(true, sr.isSuccess());
        // Check that the case that the trigger created is present.
        List<Case> cases = [SELECT Id FROM Case];
        // Validate that this case was found.
        // There is only one test case in test context.
        System.assertEquals(1, cases.size());
    }
}

Lightning コンポーネントを使用したプラットフォームイベント通知の登録

Lightning アプリケーションは、empApi Lightning Web または Aura コンポーネントを使用して、アプリケーションのイベントに登録できます。

Lightning Web コンポーネントでの登録

Lightning Web コンポーネントの empApi メソッドを使用するには、次に示すように lightning/empApi モジュールからこのメソッドをインポートします。

import { subscribe, unsubscribe, onError, setDebugFlag, isEmpEnabled }
    from 'lightning/empApi';

次に、インポートしたメソッドを JavaScript コードでコールします。

lightning/empApi モジュールの使用例と詳細なリファレンスについては、Lightning コンポーネントライブラリlightning-emp-api に関するドキュメントを参照してください。

Aura コンポーネントでの登録

Aura コンポーネントで empApi メソッドを使用するには、カスタムコンポーネント内に lightning:empApi コンポーネントを追加して、aura:id 属性を割り当てます。

<lightning:empApi aura:id="empApi"/>

次に、クライアント側コントローラーで、コンポーネントメソッドをコールする関数を追加します。

lightning:empApi コンポーネントの使用例と詳細なリファレンスについては、Lightning コンポーネントライブラリlightning:empApi に関するドキュメントを参照してください。

クリックを使用したプラットフォームイベント通知の登録

プラットフォームイベントメッセージを受信したときにフローをトリガーするには、プラットフォームイベントトリガーフローを作成します。開始要素で、フローの実行をトリガーするイベントメッセージを使用するプラットフォームイベントを選択します。

フローを作成するときには、$Record グローバル変数を参照することでプラットフォームイベントメッセージの項目値を使用できます。

または、一時停止要素を使用して、フローでプラットフォームイベントに登録できます。その場合、プラットフォームイベントメッセージの受信時にフローを開始する代わりに、そのイベントメッセージによって一時停止中のフローインタビューを再開します。たとえば、Salesforce が Cloud News イベントメッセージを受信するまで一時停止する一時停止要素を次に示します。イベントの場所が {!contact.MailingCity} と一致する場合にのみ再開されます。{!contact} レコード変数には、取引先責任者レコードの値が保存されます。

Flow Builder の一時停止設定

CometD を使用したプラットフォームイベント通知の登録

外部アプリケーションは CometD を使用してプラットフォームイベントに登録し、long polling を実行します。プラットフォーム上で実行される empApi Lightning コンポーネントと Visualforce ページでも CometD を使用でき、CometD クライアントとみなされます。CometD は、Comet と呼ばれる AJAX プッシュ技術パターンを使用する、拡張性のある HTTP ベースのイベントルーティングバスです。Bayeux プロトコルを実装します。long polling は Comet プログラミングとも呼ばれ、サーバーからクライアントへの情報プッシュのエミュレーションを可能にします。通常のポーリングと同様、クライアントがサーバーに接続し、サーバーに情報を要求します。ただし、使用できる情報がない場合は空の応答を送信するのではなく、サーバーが要求を保留して、情報が使用できるようになるまで (イベントが発生するまで) 待機します。

Salesforce は、Java ライブラリの EMP コネクタを提供します。これは、CometD への接続とチャネルのリスンの詳細すべてを実装します。EMP コネクタを使用して簡単にプラットフォームイベントに登録できます。EMP コネクタを使用することで、イベントに登録する複雑さを隠すことができます。EMP コネクタについての詳細は、『ストリーミング API 開発者ガイド』の Java クライアントの例を参照してください。

イベントチャネルまたはカスタムチャネルを指定することでプラットフォームイベントに登録できます。プラットフォームイベントのチャネル名は大文字と小文字が区別され、次の形式になります。

/event/<EventName>__e

たとえば、Cloud News という名前のプラットフォームイベントがある場合、登録時に次のチャネル名を指定します。

/event/Cloud_News__e

CometD URL の最後に API バージョンを次のように指定します。

// Connect to the CometD endpoint
    cometd.configure({
               url: 'https://<Salesforce_URL>/cometd/48.0/',
               requestHeaders: { Authorization: 'OAuth <Session_ID>'}
    });

Pub/Sub API を使用したプラットフォームイベント通知への登録

Pub/Sub API では 1 つのインターフェースでプラットフォームイベントの公開とプラットフォームイベントへの登録を実行できます。Pub/Sub API は gRPC API と HTTP/2 に基づいてバイナイベントメッセージを Apache Avro 形式で効率的に公開、配信します。gRPC はオープンソースのリモートプロシジャコール (RPC) フレームワークで、gRPC を使用することでデバイス、モバイルアプリケーション、ブラウザーをバックエンドサービスに接続できます。詳細は、gRPC のドキュメントを参照してください。Apache Avro はデータ逐次化システムです。詳細は Apache Avro を参照してください。

Pub/Sub API はプルサブスクリプションモデルを使用しており、クライアントが処理容量に基づいてサーバーからいくつかのイベントを要求します。プッシュベースのサブスクリプションではクライアントがサーバーからプッシュされた新しいイベントの受信を待ちますが、プルサブスクリプションではクライアントが積極的にサーバーからのイベントを要求します。このイベントフローコントロールでは、イベントの公開が急増した場合にクライアントが処理できないほどのイベントを受信することがありません。

Pub/Sub API には次のような利点があります。

  • 1 つの API でイベントの公開、登録、イベントスキーマの取得を実行できる。
  • 公開操作によって、中間のキューへの追加の結果ではなく、最終的な公開の結果が得られる。
  • フローコントロールで、クライアントのイベント処理速度に基づいて subscribe コールでいくつのイベントを受信するかを指定できる。
  • HTTP/2 による圧縮を使用したリアルタイムで高パフォーマンスなデータストリーミングを実現できる。
  • クライアントでは gRPC API で提供される 11 種類のプログラミング言語 (Python、Java、Node、C++ など) がサポートされる。サポートされるすべての言語については https://grpc.io/docs/languages/ を参照してください。

CometD クライアントと同じように、イベントチャネルまたはカスタムチャネルを指定することでプラットフォームイベントに登録できます。

詳細は Pub/Sub API のドキュメントを参照してください。 

CometD クライアントでの JSON 形式のプラットフォームイベントメッセージ

配信されたプラットフォームイベントのメッセージは、次の Cloud News イベントの例のようになります。

{
  "data": {
    "schema": "_2DBiqh-utQNAjUH78FdbQ",
    "payload": {
      "CreatedDate": "2017-04-27T16:50:40Z",
      "CreatedById": "005D0000001cSZs",
      "Location__c": "San Francisco",
      "Urgent__c": true,
      "News_Content__c": "Large highway is closed due to asteroid collision."
    },
    "event": {
      "replayId": 2
    }
  },
  "channel": "/event/Cloud_News__e"
}

イベントメッセージのスキーマ項目には、プラットフォームイベントスキーマの ID が含まれます (この例では "schema": "_2DBiqh-utQNAjUH78FdbQ")。スキーマはバージョン管理されています。スキーマが変更されるとスキーマ ID も変更されます。

イベントのスキーマが変更されたかどうかを判別するには、REST API でスキーマを取得します。スキーマ ID を使用して、REST API リソース /vXX.X/event/eventSchema/Schema_ID に対して GET 要求を実行します。または、エンドポイント /vXX.X/sobjects/Platform_Event_Name__e/eventSchema にイベント名を指定して、イベントスキーマを取得することもできます。詳細は、『REST API 開発者ガイド』を参照してください。

メモ

PushTopic および汎用イベントとは異なり、プラットフォームイベントでは条件設定済み登録の使用はサポートされません。たとえば、/event/Cloud_News__e?Location__c='San Francisco' に登録して場所で絞り込むことはサポートされません。

Salesforce Platform と外部アプリケーションでのプラットフォームイベントの使用方法を確認しました。可能性は無限です! プラットフォームイベントは、ビジネストランザクションの処理や予防的なカスタマーサービスの取り組みなど、さまざまなアプリケーションやインテグレーションで使用できます。プラットフォームイベントでは、イベントベースのプログラミングモデルを採用して、イベントベースのソフトウェアアーキテクチャの利点を実現できます。

無料で学習を続けましょう!
続けるにはアカウントにサインアップしてください。
サインアップすると次のような機能が利用できるようになります。
  • 各自のキャリア目標に合わせてパーソナライズされたおすすめが表示される
  • ハンズオン Challenge やテストでスキルを練習できる
  • 進捗状況を追跡して上司と共有できる
  • メンターやキャリアチャンスと繋がることができる