プラットフォームイベントの登録
学習の目的
プラットフォームイベントの登録
プラットフォームイベントの公開方法は確認できましたが、プラットフォームイベントに登録して最新のニュースや荷物の配送の通知を受け取るにはどうすればよいのでしょうか? Salesforce Platform では、Apex トリガ、プロセス、フローです。empApi
Lightning コンポーネントと Visualforce アプリケーションでは、CometD を通じてイベントを受信します。外部アプリケーションでも、CometD を使用してイベントに登録します。
Apex トリガを使用したプラットフォームイベント通知の登録
皆さんはおそらくすでに Apex トリガを使用してデータベースイベントに基づくアクションを実行したことがあるでしょう。プラットフォームイベントでも、プロセスは似ています。受信イベントに登録するには、イベントオブジェクトに対する after insert トリガを記述するだけです。トリガは、Apex での自動登録メカニズムを提供します。チャネルの作成とリスンを明示的に行う必要はありません。トリガは、Apex と API のどちらで公開されていても、さまざまなソースからイベント通知を受信します。
プラットフォームイベントは after insert トリガのみをサポートします。after insert トリガイベントは、プラットフォームイベントが公開された後のタイミングに対応します。イベントメッセージが公開されると、after insert トリガが起動されます。
プラットフォームイベントトリガを作成するには、開発者コンソールを使用します。
- [設定] アイコンをクリックし、[開発者コンソール] を選択し、[File (ファイル)] | [New (新規)] | [Apex Trigger (Apex トリガ)] をクリックします。
- 名前を指定し、sObject のイベントを選択して [Submit (送信)] をクリックします。
開発者コンソールにより、トリガテンプレートに after insert
イベントが自動的に追加されます。さらに、[設定] のイベントの定義ページから [トリガ] 関連リストで簡単にトリガを作成できますが、after insert
キーワードを指定する必要があります。
次の例は、Cloud News イベントのトリガを示します。各イベントを反復処理し、Urgent__c
項目でニュースが緊急かどうか確認します。ニュースが緊急の場合、トリガはケースを作成して、ニュースレポーターを派遣し、イベントの場所をケースの件名に追加します。
// 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 トランザクションと同じトランザクションでは実行されません。トリガは、システムユーザである自動化プロセスエンティティの下の独自プロセスで実行されます。そのため、トリガ実行に対応するデバッグログは自動化プロセスエンティティによって作成され、開発者コンソールでは使用できません。プラットフォームイベントトリガログを収集するには、[設定] で追跡フラグエントリを自動化プロセスエンティティに追加します。
- [設定] から、[クイック検索] ボックスに「デバッグログ」と入力し、[デバッグログ] をクリックします。
- [新規] をクリックします。
- [追跡対象エンティティ種別] で、[自動化プロセス] を選択します。
- 収集するログの開始時刻と有効期限を選択します。
- [デバッグレベル] に「*」と入力し、[検索] をクリックします。
- 事前定義されたデバッグレベル (SFDC_DevConsole など) を選択するか、[新規] をクリックして独自のデバッグレベルを作成します。
- [保存] をクリックします。
プラットフォームイベントトリガに関する留意点
イベント処理の順序トリガは、プラットフォームイベント通知を受信した順序で順次処理します。イベントの順序は、イベントの再実行 ID に基づきます。Apex トリガはイベントのバッチを一度に受信できます。イベントの順序は、各バッチ内に保持されます。バッチ内のイベントの発信元は、1 つ以上の公開者である可能性があります。
非同期のトリガ実行
プラットフォームイベントトリガは、独自のプロセス内で非同期に実行され、イベントを公開したトランザクションには含まれません。そのため、イベントが公開されてからトリガがイベントを処理するまでの間に遅延が発生することがあります。トリガの実行結果がイベント公開の直後に使用可能になると想定しないでください。
自動化プロセスシステムユーザ
プラットフォームイベントトリガは、トリガを実行するユーザ (実行ユーザ) の下では実行されず、自動化プロセスシステムユーザの下で実行されるため、
CloudNewsTrigger
の例では、所有者 ID 項目が明示的に設定されています。このトリガの例では、Regional Dispatch というサンプルユーザキューの ID が使用されています。ケースや商談など、OwnerId
項目がトリガにある Salesforce レコードを作成する場合、明示的に所有者 ID を設定してください。ケースとリードの場合、代わりに割り当てルールを使用して所有者を設定できます。また、イベントトリガで作成または更新されたレコードのシステム項目 (
CreatedById
や LastModifiedById
など) は、自動化プロセスエンティティを参照し、実行ユーザは参照しません。同様に、Apex の UserInfo.getUserId()
ステートメントは自動化プロセスエンティティを返します。Apex ガバナ制限
標準またはカスタムオブジェクトトリガと同様、プラットフォームイベントトリガには、Apex ガバナ制限が適用されます。
Apex トリガの制限
プラットフォームイベントトリガは、カスタムおよび標準オブジェクトトリガと同じ制限の多くを共有します。たとえば、トリガから Apex コールアウトを同期して実行することはできません。
トリガバッチサイズ
プラットフォームイベントトリガの最大バッチサイズはイベントメッセージ 2,000 件で、Salesforce オブジェクトトリガのバッチサイズの 200 より大きくなっています。バッチサイズは Trigger.New リストのサイズに対応します。チェックポイントを設定すれば、プラットフォームイベントトリガのバッチサイズを管理したり、制限や検出されなかった例外から復旧することができます。詳細は、『プラットフォームイベント開発者ガイド』の「Apex トリガでの小さなバッチのプラットフォームイベントメッセージの処理」を参照してください。
イベント定義ページの登録関連リスト
[設定] のプラットフォームイベント定義詳細ページでは、すべてのイベントトリガの状態を表示できます。[登録] の下で、有効なトリガのそれぞれが、実行情報および状態と一緒にリストされます。情報には、最終公開イベントや最終処理イベントの再実行 ID が含まれます。状態は、トリガが実行中であるか、復旧できないエラーや不十分な権限により登録から切断されているかを示します。トリガの最大試行回数に達した場合にのみ、エラー状態になります。次のスクリーンショットは、Cloud News イベント詳細ページの [登録] 関連リストを示します。
イベントの 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 に関するドキュメントを参照してください。
クリックを使用したプラットフォームイベント通知の登録
コードを使用せずにイベントメッセージに登録するには、プラットフォームイベントメッセージの受信時に開始されるプロセスを作成します。
次のスクリーンショットは、Cloud News イベントの受信時に開始されるプロセスを示しています。このプロセスが開始されると、郵送先の市区郡がイベント通知の場所と一致する取引先責任者レコードが検索されます。
同様に、一時停止要素を使用して、フローのプラットフォームイベントに登録できます。プラットフォームイベントの発生時にフローを開始するのではなく、それ以前に開始済みのフローが、プラットフォームイベントメッセージを受信するまで一時停止し、受信後再開します。たとえば、Salesforce が Cloud News イベントメッセージを受信するまで待機する一時停止要素を次に示します。イベントの場所が {!contact.MailingCity}
と一致する場合にのみ再開されます。{!contact}
は、取引先責任者レコードの値を保存する、フローのレコード変数です。
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 クライアントの例を参照してください。
CometD を使用してプラットフォームイベント通知に登録するプロセスは、PushTopic イベントや汎用イベントへの登録と似ています。唯一の違いはチャネル名です。プラットフォームイベントのチャネル名は大文字と小文字が区別され、次の形式になります。
/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>'} });
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 開発者ガイド』を参照してください。
Salesforce Platform と外部アプリケーションでのプラットフォームイベントの使用方法を確認しました。可能性は無限です! プラットフォームイベントは、ビジネストランザクションの処理や予防的なカスタマーサービスの取り組みなど、さまざまなアプリケーションやインテグレーションで使用できます。プラットフォームイベントでは、イベントベースのプログラミングモデルを採用して、イベントベースのソフトウェアアーキテクチャの利点を実現できます。
リソース
- Trailhead: インスタント通知アプリケーションの作成
- ストリーミング API 開発者ガイド
- プラットフォームイベント開発者ガイド: 例: Java クライアントを使用した登録とイベントの再生 (EMP コネクタ)
- CometD ドキュメント
- Platform Events Developer Guide (プラットフォームイベント開発者ガイド): Platform Event Limits (プラットフォームイベントの割り当て)
- Platform Events Developer Guide (プラットフォームイベント開発者ガイド): Retry Event Triggers with EventBus.RetryableException (EventBus.RetryableException を使用したイベントトリガの再試行)
- Lightning プラットフォーム Cookbook: Running Case Assignment Rules from Apex (Apex からのケース割り当てルールの実行)
- REST API 開発者ガイド: スキーマ ID によるプラットフォームイベントスキーマ
- REST API 開発者ガイド: イベント名によるプラットフォームイベントスキーマ