プラットフォームイベントの登録
学習の目的
プラットフォームイベントの登録
プラットフォームイベントの公開方法は確認できましたが、プラットフォームイベントに登録して最新のニュースや荷物の配送の通知を受け取るにはどうすればよいのでしょうか? Salesforce Platform では、Apex トリガー、プロセス、フローです。empApi
Lightning コンポーネントと Visualforce アプリケーションでは、CometD を通じてイベントを受信します。外部アプリケーションで、CometD または Pub/Sub API を使用してイベントに登録します。
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 コールアウトを同期して実行することはできません。
トリガーバッチサイズ
プラットフォームイベントトリガーのバッチサイズはイベントメッセージ 2,000 件で、Salesforce オブジェクトトリガーのバッチサイズの 200 より大きくなっています。バッチサイズは
Trigger.New
リストのサイズに対応します。プラットフォームイベントトリガーのバッチサイズは変更できます。詳細は、『プラットフォームイベント開発者ガイド』の「プラットフォームイベントトリガーのユーザーとバッチサイズの設定」を参照してください。イベント定義ページの登録関連リスト
[設定] のプラットフォームイベント定義詳細ページでは、すべてのイベントトリガーの状態を表示できます。[登録] の下で、有効なトリガーのそれぞれが、実行情報および状態と一緒にリストされます。情報には、最終公開イベントや最終処理イベントの再実行 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 に関するドキュメントを参照してください。
クリックを使用したプラットフォームイベント通知の登録
プラットフォームイベントメッセージを受信したときにフローをトリガーするには、プラットフォームイベントトリガーフローを作成します。開始要素で、フローの実行をトリガーするイベントメッセージを使用するプラットフォームイベントを選択します。
フローを作成するときには、$Record
グローバル変数を参照することでプラットフォームイベントメッセージの項目値を使用できます。
または、一時停止要素を使用して、フローでプラットフォームイベントに登録できます。その場合、プラットフォームイベントメッセージの受信時にフローを開始する代わりに、そのイベントメッセージによって一時停止中のフローインタビューを再開します。たとえば、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 クライアントの例を参照してください。
イベントチャネルまたはカスタムチャネルを指定することでプラットフォームイベントに登録できます。プラットフォームイベントのチャネル名は大文字と小文字が区別され、次の形式になります。
/event/<EventName>__e
たとえば、Cloud News という名前のプラットフォームイベントがある場合、登録時に次のチャネル名を指定します。
/event/Cloud_News__e
カスタムプラットフォームイベントのチャネル名は大文字と小文字が区別され、次の形式になります。カスタムチャネルについての詳細は、『プラットフォームイベント開発者ガイド』の「カスタムチャネルを使用したプラットフォームイベントの 1 つのストリームへのグループ化」を参照してください。
/event/<CustomChannelName>__chn
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 開発者ガイド』を参照してください。
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 開発者ガイド: イベント名によるプラットフォームイベントスキーマ