Comments
Description
Transcript
ストリーミング - Salesforce.com
Force.com ストリーミング API 開発者ガイド バージョン 38.0, Winter ’17 @salesforcedocs 最終更新日: 2016/08/21 本書の英語版と翻訳版で相違がある場合は英語版を優先するものとします。 © Copyright 2000–2016 salesforce.com, inc. All rights reserved. Salesforce およびその他の名称や商標は、salesforce.com, inc. の登録商標です。本ドキュメントに記載されたその他の商標は、各社に所有権があります。 目次 Force.com ストリーミング API の開始 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 第 1 章: ストリーミング API の概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 プッシュ技術 . . . . . . . . . . . . . . . . . . Bayeux プロトコル、CometD、および ストリーミング API 用語 . . . . . . . . . . クライアントの接続方法 . . . . . . . . . メッセージの信頼性 . . . . . . . . . . . . . メッセージの永続性 . . . . . . . . . . . . . ......... long polling ......... ......... ......... ......... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 2 3 3 4 4 第 2 章: ワークベンチを使用したクイックスタート . . . . . . . . . . . . . . . . . . . . . . . . 8 前提条件 ステップ ステップ ステップ ステップ ...........................................................8 1: オブジェクトを作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2: PushTopic を作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 3: PushTopic チャネルに登録する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 4: PushTopic チャネルをテストする . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 コード例 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 第 3 章: 例: 対話型 Visualforce ページ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 前提条件 . . . . . . . . . . . . . . . . . . . . . . . . . . ステップ 1: オブジェクトを作成する . . . . . . ステップ 2: PushTopic を作成する . . . . . . . . ステップ 3: 静的リソースを作成する . . . . . . ステップ 4: Visualforce ページを作成する . . . ステップ 5: PushTopic チャネルをテストする . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 14 14 14 15 16 第 4 章: 例: Visualforce ページ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 前提条件 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 ステップ 1: オブジェクトを作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 ステップ 2: PushTopic を作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 ステップ 3: 静的リソースを作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 ステップ 4: Visualforce ページを作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 ステップ 5: PushTopic チャネルをテストする . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 第 5 章: 例: Java クライアント . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 前提条件 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 ステップ 1: オブジェクトを作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 ステップ 2: PushTopic を作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 目次 ステップ 3: JAR ファイルをダウンロードする . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 ステップ 4: ソースコードを追加する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 第 6 章: 例: Visualforce ページを使用した PushTopic ストリーミングイベントと 汎用ストリーミングイベントの再生 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 前提条件 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 サンプルプロジェクトを組織にリリースする . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 デュラブル PushTopic ストリーミングのサンプル . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 Visualforce ページを使用して PushTopic イベントを生成および再生する . . . . . . . . . 34 デュラブル汎用ストリーミングのサンプル . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 権限セットを割り当てる . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 ストリーミングチャネルを作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 Visualforce ページを使用して汎用イベントを生成および再生する . . . . . . . . . . . . . 38 イベントの再生サンプル: コードのウォークスルー . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 第 7 章: 例: 認証 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 開発者テスト用の認証の設定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 OAuth 2.0 での認証の設定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 ストリーミング API の使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 第 8 章: PushTopic の使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 PushTopic クエリ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 セキュリティと PushTopic クエリ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 サポート対象の PushTopic クエリ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 PushTopic クエリの複合項目 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 サポート対象外の PushTopic クエリ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 イベント通知ルール . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 イベント . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 通知 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 PushTopic ストリーミングイベントの再生 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 登録の際の絞り込み条件の設定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 一括登録 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 PushTopic の無効化 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 第 9 章: ストリーミング API の考慮事項 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 クライアントとタイムアウト . . . . . . . . . . . . . . . ストリーミング API のクライアントと Cookie . . . サポートされるブラウザ . . . . . . . . . . . . . . . . . . HTTPS の推奨 . . . . . . . . . . . . . . . . . . . . . . . . . . . ストリーミング API アプリケーションのデバッグ イベント使用状況の監視 . . . . . . . . . . . . . . . . . . 通知メッセージの順序 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 64 64 65 65 66 66 目次 汎用ストリーミング . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 第 10 章: 汎用ストリーミングの概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 デュラブル汎用ストリーミングを使用した汎用ストリーミングイベントの再生 . . . . . . 69 第 11 章: クイックスタート . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 ストリーミングチャネルを作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 Java クライアントを作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 REST を使用してイベントを生成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 リファレンス . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 第 12 章: PushTopic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 第 13 章: StreamingChannel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 第 14 章: Streaming Channel Push . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 第 15 章: ストリーミング API の制限 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 Force.com ストリーミング API の開始 第1章 トピック: • プッシュ技術 • Bayeux プロトコ ル、CometD、およ び long polling • ストリーミング API 用語 • クライアントの接 続方法 • • メッセージの信頼 性 メッセージの永続 性 ストリーミング API の概要 ストリーミング API を使用すると、Salesforce データへの変更が定義した SOQL クエリ に一致する場合、セキュアで拡張性の高い方法で通知を受け取ることができます。 これらのイベントは次の場所で受信できます。 • Salesforce アプリケーション内のページ。 • Salesforce 外のアプリケーションサーバ。 • Salesforce アプリケーション外のクライアント。 ストリーミング API を使用するときのイベントの順序は次のとおりです。 1. SOQL クエリに基づいて PushTopic を作成します。これによりチャネルが定義され ます。 2. クライアントがチャネルに登録します。 3. レコードが作成、更新、削除、復元されます (イベントが発生)。そのレコードへ の変更が評価されます。 4. レコードの変更が PushTopic クエリの条件に一致した場合、サーバが通知を生成 し、登録しているクライアントがその通知を受信します。 ストリーミング API は、定義した条件に基づいてサーバからクライアントに通知を プッシュする場合に便利です。次のようなアプリケーションでストリーミング API を検討してください。 頻繁にポーリングするアプリケーション Salesforce インフラストラクチャに対して絶えずポーリングし、不必要な API コー ルと処理時間を消費するアプリケーションでストリーミング API を使用すると、 データを返さない要求の数を減らし、効率を高めることができます。 全般的な通知 組織内のデータ変更について全般的な通知が必要なアプリケーションにストリー ミング API を使用すると、API コール数が減り、パフォーマンスが向上します。 メモ: ストリーミング API は、API が有効であればどの組織にも使用できます。 これには、Salesforce 組織と Database.com 組織の両方が含まれます。 1 ストリーミング API の概要 プッシュ技術 プッシュ技術 プッシュ技術 (公開/登録モデルとも呼ばる) により、サーバからクライアントに情報が転送されます。この種 類の通信は、クライアントからサーバに対する情報の要求が必要なプル技術とは反対の技術です。 サーバが送信する情報は通常、事前に指定されます。ストリーミング API を使用するときは、PushTopic を作成 してクライアントが受け取る情報を指定します。クライアントは PushTopic チャネルに登録して PushTopic 条件 に一致するイベントの通知を受け取ります。 プッシュ技術では、クライアントが情報のチャネルに登録すると、サーバがクライアントに情報をプッシュ送 信します。クライアントが情報を受け取るには、サーバへの接続を維持する必要があります。ストリーミング API は Bayeux プロトコルと CometD を使用するため、クライアントからサーバへの接続は long polling を使用して 維持されます。 Bayeux プロトコル、CometD、および long polling ストリーミング API は、long polling に Bayeux プロトコルと CometD を使用します。 • Bayeux は、主に HTTP を介して非同期メッセージを伝送するためのプロトコルです。 • CometD は、Comet と呼ばれる AJAX プッシュ技術パターンを使用する、拡張性のある HTTP ベースのイベント ルーティングバスです。Bayeux プロトコルを実装します。Salesforce サーバでは、バージョン 2.0 の CometD が 使用されます。 • long polling は Comet プログラミングとも呼ばれ、サーバからクライアントへの情報プッシュのエミュレー ションを可能にします。通常のポーリングと同様、クライアントがサーバに接続し、サーバに情報を要求 します。ただし、使用できる情報がない場合は空の応答を送信するのではなく、サーバが要求を保留して、 情報が使用できるようになるまで (イベントが発生するまで) 待機します。情報が使用できるようになると、 サーバは完全な応答をクライアントに送信します。クライアントは情報を受け取るとすぐに、次の情報を 再要求します。クライアントは、サーバへの接続を継続して維持するため、常に応答の受信を待機してい ます。サーバがタイムアウトした場合は、クライアントは再接続し、最初からやり直します。 long polling、Bayeux、CometD の知識がない場合は、次のリソースを確認してください。 • CometD ドキュメント: www.cometd.org/documentation • Bayeux プロトコルドキュメント: www.cometd.org/documentation/bayeux • Bayeux プロトコル仕様: www.cometd.org/documentation/bayeux/spec ストリーミング API は、次の CometD メソッドをサポートします。 メソッド 説明 connect クライアントがサーバに接続します。 disconnect クライアントがサーバから切断します。 handshake クライアントがサーバとのハンドシェイクを実行し、long polling 接続を確立しま す。 2 ストリーミング API の概要 ストリーミング API 用語 メソッド 説明 subscribe クライアントが PushTopic で定義されたチャネルに登録します。登録が終わる と、クライアントはそのチャネルからメッセージを受信できます。チャネルに 登録する前に、handshake メソッドのコールが成功している必要があります。 unsubscribe クライアントがチャネルの登録を解除します。 ストリーミング API 用語 ストリーミング API で使用される用語について説明します。 用語 説明 イベント レコードの作成、更新、削除、復元。各イベントによって通知がトリガされる 場合があります。 通知 イベントに対応したメッセージ。通知は 1 つ以上のクライアントが登録されて いるチャネルに送信されます。 PushTopic ユーザが作成するレコード。PushTopic の重要な要素はSOQLクエリです。PushTopic ではストリーミング API チャネルを定義します。 クライアントの接続方法 ストリーミング API は HTTP/1.1 要求-応答モデルと Bayeux プロトコル (CometD 実装) を使用します。Bayeux クライ アントは複数の段階でストリーミング API に接続します。 1. ハンドシェイク要求を送信する。 2. チャネルに登録要求を送信する。 3. long polling を使用して接続する。 CometD メソッドの subscribe または connect をコールする場合などに、サーバがクライアントから受け入 れられる HTTP POST リクエストボディの最大サイズは、32,768 バイトです。要求メッセージがこのサイズを超え ると、応答でエラー「413 Maximum Request Size Exceeded」が返されます。要求をサイズ制限内に抑えるには、1 つの要求で複数のメッセージを送信しないでください。 クライアントは、長命 (long-lived) 接続を維持しながら、サーバからイベントを受信します。 • クライアントがイベントを受信すると、次のイベントのセットを受信するためにすぐに再接続する必要が あります。40 秒以内に再接続しないと、サーバが登録を期限切れにし、接続が終了します。クライアント は、ハンドシェイクと登録を最初からやり直す必要があります。 • イベントが生成されずにクライアントが待機しているときにサーバが接続を閉じた場合、2 分経過したらす ぐにクライアントは再接続する必要があります。 長命 (long-lived) 接続が予期しないネットワークの中断により失われた場合、CometD は自動的に再接続を試みま す。この再接続が成功した場合、この新しい接続では、再ハンドシェイクにより前の登録者が削除されている 3 ストリーミング API の概要 メッセージの信頼性 ため、クライアントは再登録する必要があります。クライアントは、meta/handshake メタチャネルをリス ンして、接続が失われて再確立されたときに通知を受信することができます。 これらの手順の詳細は、「Bayeux プロトコル、CometD、および long polling」を参照してください。 メッセージの信頼性 API バージョン 37.0 以降では、過去のイベントを再生できるため、ストリーミング API で信頼性の高いメッセー ジ配信を実現できます。API バージョン 36.0 以前では、状況によってはクライアントがすべてのメッセージを 受信できないことがありました。 API バージョン 37.0 以降では、ストリーミング API でイベントが 24 時間保存されるため、過去のイベントを再 生できます。デュラブルストリーミングでは、クライアントが切断されている場合や、登録されていない場合 でもメッセージが失われません。クライアントの再登録時に、24 時間の保持期間内の過去のイベントを取得で きます。過去のイベントを再生できるため、信頼性の高いメッセージ配信が実現します。 API バージョン 36.0 以前では、ストリーミング API で、通知の配信の信頼性は保証されていませんでした。デュ ラブルストリーミングを使用しないと、ストリーミングサーバは、クライアントの状態を維持せず、配信され た内容を追跡しません。クライアントは、次のようないくつかの理由でメッセージを受信しないことがありま す。 • クライアントが初めて登録または再接続した場合、チャネルに登録していなかった間に処理されたメッセー ジを受信しないことがあります。 • クライアントが切断し、新たにハンドシェイクを開始した場合は別のアプリケーションサーバを使用する 可能性があります。そのため、その時点からの新しいメッセージのみを受信します。 • システムの使用負荷が高い場合、一部のシステムイベントが削除されます。 • アプリケーションサーバが停止した場合、処理中で未送信のメッセージはすべて失われます。そのアプリ ケーションサーバに接続しているクライアントは切断されます。通知を受け取るには、クライアントは再 接続してトピックチャネルに登録する必要があります。 メッセージ配信の考慮事項 すべての API バージョンで次の点に注意してください。 同じ Apex トランザクション内の複数の通知 同じ Apex トランザクション内の同じレコードで複数の PushTopic 通知が送信される場合は、最後の通知のみ が送信されます。それより前の通知は抑制されます。たとえば、取引先責任者レコードの作成と更新のた めに PushTopic を設定し、PushTopic クエリで fieldA が選択されるとします。取引先責任者が挿入されてか ら Apex トリガによって fieldA が更新された場合、更新の通知のみが送信されます。取引先責任者の作成 の通知は送信されません。 メッセージの永続性 Salesforce ではイベントが 24 時間保存されるため、その保持期間は保存されたイベントを取得できます。スト リーミング API イベントフレームワークでは、イベントプロデューサがイベントコンシューマから分離されま す。登録者は、送信時にイベントをリスンするだけではなく、いつでもイベントを取得できます。 4 ストリーミング API の概要 メッセージの永続性 イベント採番 各ブロードキャストイベントには、数値の ID が割り当てられます。ID は増分されますが、連続するイベント に連番が振られるという保証はありません。ただし、各 ID がその前のイベントの ID よりも大きいことは保証 されます。たとえば、ID 999 のイベントの次のイベントの ID が 1,025 になることもあり得ます。ID は組織および チャネルで一意です。削除されたイベントの ID は再利用されません。 ID は、通知メッセージの replayId 項目に追加されます。たとえば、次の JSON メッセージは汎用イベントの イベントオブジェクトの replayId 項目を示します。 { "clientId":"a1ps4wpe52qytvcvbsko09tapc", "data":{ "event":{ "createdDate":"2016-03-29T19:05:28.334Z", "replayId":55 }, "payload":"This is a message." }, "channel":"/u/TestStreaming" } 次の JSON メッセージは PushTopic イベントのイベントオブジェクトの replayId 項目を示します。 { "clientId":"2t80j2hcog29sdh9ihjd9643a", "data":{ "event":{ "createdDate":"2016-03-29T16:40:08.208Z", "replayId":13, "type":"created" }, "sobject":{ "Website":null, "Id":"001D000000KnaXjIAJ", "Name":"TicTacToe" } }, "channel":"/topic/TestAccountStreaming" } メモ: API バージョン 37.0 以降では、createdDate 項目値の時刻形式が Salesforce アプリケーションで使用 される時刻形式と同じになるように変更されます。時刻部分の末尾は、+0000 ではなく、Z サフィック スになりました。どちらのサフィックスも UTC タイムゾーンで表されます。 イベントの再生 登録者は、保管期間内や特定のイベント後のすべてのイベントなど、受信するイベントを選択できます。デ フォルトでは、登録後に送信された新規イベントのみを受信します。イベントは 24 時間の保管期間を過ぎる と破棄されます。 次の概要図は、イベントコンシューマがさまざまな再生オプションを使用してイベントのストリームを読み取 る方法を示しています。 5 ストリーミング API の概要 メッセージの永続性 表 1 : 再生オプション 再生オプション 説明 再生 ID 登録者は、replayId 値で指定されたイベント後のす べてのイベントを受信します。 -1 登録者は、クライアントの登録後にブロードキャスト された新規イベントを受信します。 -2 登録者は、すべてのイベントを受信します。これに は、24 時間の保管期間内の過去のイベントと、登録 後に送信された新規イベントが含まれます。 イベントを再生するには、ストリーミング API エンドポイントを使用します。 https://Salesforce_Instance/cometd/38.0/ メモ: API バージョン 37.0 以降では、このエンドポイントでデュラブルストリーミングがサポートされま す。バージョン 36.0 では、デュラブル汎用ストリーミングが代替エンドポイント https://Salesforce_Instance/cometd/replay/36.0/ でサポートされます。ただし、バージョン 37.0 にアップグレードして、メインストリーミング API エンドポイントを使用することをお勧めします。 再生メカニズムは、Salesforce が提供する CometD 拡張で実装されます。拡張の例は、JavaScript や Java で提供され ます。たとえば、次のように JavaScript で拡張を登録できます。 // Register streaming extension var replayExtension = new cometdReplayExtension(); replayExtension.setChannel(<Streaming Channel to Subscribe to>); replayExtension.setReplay(<Event Replay Option>); cometd.registerExtension('myReplayExtensionName', replayExtension); メモ: • setReplay() に渡される引数は、「メッセージの永続性」に記載された再生オプションの 1 つです。 • registerExtension() に渡される最初の引数は、コードの再生拡張の名前です。この例では myExtensionName に設定されていますが、任意の文字列にもできます。後で拡張を登録解除する場 合は、この名前を使用します。 6 ストリーミング API の概要 メッセージの永続性 • setReplay() 関数がコールされない場合、または CometD 拡張が登録されない場合、新規イベントの みが登録者に送信されます (-1 オプションと同じ)。 拡張に対して setReplay() 関数をコールすると、その後で登録者が受信するイベントは setReplay() に渡 された再生値パラメータに依存します。 コードサンプル Visualforce のサンプル Visualforce と CometD 拡張を JavaScript で使用する例およびコードのウォークスルーについては、「例: Visualforce ページを使用した PushTopic ストリーミングイベントと汎用ストリーミングイベントの再生」を参照してく ださい。 7 第2章 ワークベンチを使用したクイックスタート このクリックスタートでは、ワークベンチを使って、ストリーミング APIの使用を開始する方法を説明します。 レコードが更新されたときにストリーミング API を使用して通知を受け取るプロセスをステップごとに説明し ます。 • 前提条件 • ステップ 1: オブジェクトを作成する • ステップ 2: PushTopic を作成する • ステップ 3: PushTopic チャネルに登録する • ステップ 4: PushTopic チャネルをテストする 前提条件 クイックスタートの手順を実行するには、アクセス権と適切な権限が必要です。 • Developer Edition 組織にアクセスします。 まだ Force.com 開発者コミュニティのメンバーでない場合、developer.salesforce.com/signup にアク セスし、Developer Edition 組織のサインアップの説明に従ってください。すでに Enterprise Edition、Unlimited Edition、または Performance Edition を所有している場合でも、組織の使用中のデータを保護するために、サン プルデータに対するソリューションの開発、ステージングおよびテストには Developer Edition を使用します。 これは、特に、(データをただ参照するだけのアプリケーションに対し) データを挿入、更新または削除す るアプリケーションの場合に該当します。 • Developer Edition 組織で「API の有効化」権限を有効にする必要があります。この権限はデフォルトで有効に なっていますが、システム管理者によって変更されている場合があります。 • 「ストリーミング API」権限を有効にする必要があります。 メモ: 組織で「API の有効化」権限と「ストリーミング API」権限が有効であることを確認するには、 [設定] から [クイック検索] ボックスに「ユーザインターフェース」と入力し、[ユーザインターフェー ス] を選択します。 • ログインユーザが通知を受信するには、PushTopic 標準オブジェクトに対する「参照」権限が必要です。 • ログインユーザが PushTopic レコードを作成および管理するには、PushTopic 標準オブジェクトに対する「作 成」権限が必要です。 • ログインユーザが開発者コンソールを使用して PushTopic を作成するには、「Apex 開発」権限が必要です。 8 ワークベンチを使用したクイックスタート ステップ 1: オブジェクトを作成する ステップ 1: オブジェクトを作成する 最初のステップでは、InvoiceStatement (請求書明細) オブジェクトを作成します。PushTopic を作成し、その PushTopic に登録すると、InvoiceStatement レコードが作成、更新、削除、復元されたときに通知を受け取れます。オブ ジェクトは Salesforce ユーザインターフェースで作成します。 1. カスタムオブジェクトの管理設定から、Salesforce Classic を使用している場合は [新規カスタムオブジェクト] をクリックし、Lightning Experience を使用している場合は [作成] > [カスタムオブジェクト] を選択します。 2. カスタムオブジェクトを定義します。 • [表示ラベル] 項目に「Invoice Statement」と入力します。 • [表示ラベル(複数形)] 項目に「Invoice Statements」と入力します。 • [母音で始まる場合はチェック] を選択します。 • [レコード名] 項目に「Invoice Number」と入力します。 • [データ型] 項目で、[自動採番] を選択します。 • [表示形式] 項目に「INV-{0000}」と入力します。 • [開始番号] 項目に「1」と入力します。 3. [保存] をクリックします。 4. [Status] 項目を追加します。 a. [カスタム項目 & リレーション] 関連リストまで下方向へスクロールして [新規] をクリックします。 b. [データ型] で [選択リスト] を選択し、[次へ] をクリックします。 c. [表示ラベル] 項目に「Status」と入力します。 d. 表示されたボックスに、1 行に 1 エントリずつ次の選択リスト値を入力します。 Open Closed Negotiating Pending e. [最初の値をデフォルト値とする] のチェックボックスをオンにします。 f. [次へ] をクリックします。 g. 項目レベルセキュリティで、[参照のみ] を選択し、[次へ] をクリックします。 h. [保存 & 新規] をクリックして、この項目を保存し、新しい項目を作成します。 5. 次に、[Description] 項目を作成します (省略可能)。 a. [データ型] 項目で [テキストエリア] を選択し、[次へ] をクリックします。 b. [項目の表示ラベル] 項目と [項目名] 項目に、「Description」と入力します。 c. [次へ] をクリックし、デフォルトを受け入れて、[次へ] をもう一度クリックします。 d. [保存] をクリックして InvoiceStatement オブジェクトの詳細ページに移動します。 9 ワークベンチを使用したクイックスタート ステップ 2: PushTopic を作成する これで InvoiceStatement オブジェクトに 2 つのカスタム項目が作成されました。 関連トピック: Salesforce ヘルプ: オブジェクト管理設定の検索 ステップ 2: PushTopic を作成する 開発者コンソールを使用して SOQL クエリが含まれる PushTopic レコードを作成します。イベント通知は、クエ リに一致する更新について生成されます。または、ワークベンチを使用して PushTopic を作成することもでき ます。 1. 開発者コンソールを開きます。 2. [Debug (デバッグ)] > [Open Execute Anonymous Window (実行匿名ウィンドウを開く)] をクリックします。 3. [Enter Apex Code (Apex コードを入力)] ウィンドウに次の Apex コードを貼り付けて、[Execute (実行)] をクリック します。 PushTopic pushTopic = new PushTopic(); pushTopic.Name = 'InvoiceStatementUpdates'; pushTopic.Query = 'SELECT Id, Name, Status__c, Description__c FROM Invoice_Statement__c'; pushTopic.ApiVersion = 38.0; pushTopic.NotifyForOperationCreate = true; pushTopic.NotifyForOperationUpdate = true; pushTopic.NotifyForOperationUndelete = true; pushTopic.NotifyForOperationDelete = true; pushTopic.NotifyForFields = 'Referenced'; insert pushTopic; メモ: 組織で名前空間プレフィックスが定義済みの場合は、PushTopic クエリを定義するときにカスタ ムオブジェクトおよび項目の名前の先頭に名前空間を指定する必要があります。たとえば、SELECT Id, Name, namespace__Status__c, namespace__Description__c FROM namespace__Invoice_Statement__c と指定します。 NotifyForOperationCreate、NotifyForOperationUpdate、NotifyForOperationDelete、 NotifyForOperationUndelete は true に設定されているため、ストリーミング API は作成、更新、削 除、復元されたレコードを評価し、レコードが PushTopic クエリに一致する場合は通知を生成します。 NotifyForFields は Referenced に設定されているため、ストリーミング API は SELECT 句と WHERE 句の 両方の項目を使用して通知を生成します。項目 Name、Status__c、または Description__c が更新され ると常に、通知がこのチャネル上に生成されます。NotifyForOperationCreate、 NotifyForOperationUpdate、NotifyForOperationDelete、NotifyForOperationUndelete、 NotifyForFields についての詳細は、「イベント通知ルール」を参照してください。 メモ: API バージョン 28.0 以前では、レコードが作成または更新されたときにのみ通知が生成されま す。NotifyForOperationCreate、NotifyForOperationUpdate、NotifyForOperationDelete、 NotifyForOperationUndelete 項目は使用できず、通知を生成するレコードイベントの設定には 10 ワークベンチを使用したクイックスタート ステップ 3: PushTopic チャネルに登録する NotifyForOperations 列挙項目が代わりに使用されます。詳細は、「PushTopic」を参照してくださ い。 関連トピック: Salesforce ヘルプ: 開発者コンソールを開く ステップ 3: PushTopic チャネルに登録する このステップでは、前のステップで PushTopic レコードを使用して作成したチャネルに登録します。 重要: ワークベンチは、無料のオープンソースのコミュニティサポートツールです (ワークベンチのヘル プページを参照)。Salesforceは、デモ目的でのみワークベンチのホスト型インスタンスを提供しています。 このワークベンチのホスト型インスタンスを本番データベースのデータへのアクセスに使用することは お勧めしません。ワークベンチを本番データベースに使用する場合は、各自で所有するリソースを使用 してワークベンチをダウンロード、ホスト、および設定してください。ワークベンチは、 https://github.com/ryanbrainard/forceworkbench/releases からダウンロードできます。 1. ブラウザで、https://developer.salesforce.com/page/Workbench に移動します。 2. [Environment (環境)] で [Production (本番)] を選択します。 3. [API Version (API バージョン)] で 38.0 を選択します。 4. サービスの利用規約に同意し、[Salesforce でログイン] をクリックします。 5. データベースへの接続が確立されると、[Select (選択)] ページが表示されます。 6. [queries (クエリ)] > [Streaming Push Topic (ストリーミング転送トピック)] を選択します。 7. [Push Topic (転送トピック)] 項目で [InvoiceStatementUpdates] を選択します。 8. [Subscribe (登録)] をクリックします。 接続および応答情報と "Subscribed to /topic/InvoiceStatementUpdates" のような応答が表示されます。 このブラウザウィンドウを開いたままにして、接続がタイムアウトしないようにします。次のステップでは、 作成した InvoiceStatement レコードがトリガしたイベント通知を表示できます。 ステップ 4: PushTopic チャネルをテストする ステップ 3: PushTopic チャネルに登録するで使用したブラウザが開いたままで、接続がタイムアウトしていない ことを確認します。このブラウザでイベント通知を表示します。 最後のステップとして PushTopic チャネルをテストするために、ワークベンチで新しい InvoiceStatement レコード を作成し、イベント通知を表示します。 1. 新しいブラウザウィンドウで、ワークベンチのインスタンスを開き、ステップ 3: PushTopic チャネルに登録 するで使用した手順に従い、同じユーザ名を使用してログインします。 メモ: レコードを更新したユーザとチャネルに登録したユーザがレコードを共有していない場合、登 録したユーザは通知を受け取りません。たとえば、組織の共有モデルが非公開の場合などです。 11 ワークベンチを使用したクイックスタート ステップ 4: PushTopic チャネルをテストする 2. [data (データ)] > [Insert (挿入)] をクリックします。 3. [Object Type (オブジェクト種別)] で、[Invoice_Statement__c] を選択します。[Single Record (単一レコード)] 項目 が選択されていることを確認し、[Next (次へ)] をクリックします。 4. [Description__c] 項目に値を入力します。 5. [Confirm Insert (挿入を確認)] をクリックします。 6. [Streaming Push Topics (ストリーミング転送トピック)] ブラウザウィンドウに切り替えます。InvoiceStatement レ コードが作成されたという通知が表示されます。通知では、PushTopic クエリの SELECT ステートメントで定 義した Id、Status__c、および Description__c 項目が返されます。メッセージは次のようになりま す。 { "channel": "/topic/InvoiceStatementUpdates", "data": { "event": { "type": "created", "createdDate": "2011-11-14T17:33:45.000+0000" }, "sobject": { "Name": "INV-0004", "Id": "a00D0000008oLi8IAE", "Description__c": "Test invoice statement", "Status__c": "Open" } } } 12 コード例 第3章 例: 対話型 Visualforce ページ このコード例は、Visualforce ページからストリーミング API を実装する方法を示します。ページ上で通知を受信 するには、ページで登録する PushTopic チャネルの名前を入力し、[登録] をクリックします。[登録解除] をク リックして、チャネルから登録解除し、通知の受信を停止します。 • 前提条件 • ステップ 1: オブジェクトを作成する • ステップ 2: PushTopic を作成する • ステップ 3: 静的リソースを作成する • ステップ 4: Visualforce ページを作成する • ステップ 5: PushTopic チャネルをテストする 前提条件 コード例を完了させるには、アクセス権と適切な権限が必要です。 • Developer Edition 組織にアクセスします。 まだ Force.com 開発者コミュニティのメンバーでない場合、developer.salesforce.com/signup にアク セスし、Developer Edition 組織のサインアップの説明に従ってください。すでに Enterprise Edition、Unlimited Edition、または Performance Edition を所有している場合でも、組織の使用中のデータを保護するために、サン プルデータに対するソリューションの開発、ステージングおよびテストには Developer Edition を使用します。 これは、特に、(データをただ参照するだけのアプリケーションに対し) データを挿入、更新または削除す るアプリケーションの場合に該当します。 • Developer Edition 組織で「API の有効化」権限を有効にする必要があります。この権限はデフォルトで有効に なっていますが、システム管理者によって変更されている場合があります。 • 「ストリーミング API」権限を有効にする必要があります。 メモ: 組織で「API の有効化」権限と「ストリーミング API」権限が有効であることを確認するには、 [設定] から [クイック検索] ボックスに「ユーザインターフェース」と入力し、[ユーザインターフェー ス] を選択します。 • ログインユーザが通知を受信するには、PushTopic 標準オブジェクトに対する「参照」権限が必要です。 • ログインユーザが PushTopic レコードを作成および管理するには、PushTopic 標準オブジェクトに対する「作 成」権限が必要です。 • ログインユーザが開発者コンソールを使用して PushTopic を作成するには、「Apex 開発」権限が必要です。 13 例: 対話型 Visualforce ページ ステップ 1: オブジェクトを作成する ステップ 1: オブジェクトを作成する この例を実行するには、最初に InvoiceStatement オブジェクトを作成する必要があります。このオブジェクトを まだ作成していない場合は、「ステップ 1: オブジェクトを作成する」を参照してください。 ステップ 2: PushTopic を作成する この例を実行するには、PushTopic を作成する必要があります。これをまだ行っていない場合は、「ステップ 2: PushTopic を作成する」を参照してください。 ステップ 3: 静的リソースを作成する 1. 静的リソースの .zip ファイル streaming_api_interactive_visualforce_demo-v25.zip をダウンロー ドします。 2. .zip ファイルから次のファイルを抽出します。 ファイル名 説明 cometd.zip demo.js が使用する CometD ファイル。.zip アーカイブファイルを静的リソー スとして定義すると、Visualforce はそのアーカイブ内のファイルにアクセスで きます。.zip ファイルは仮想ファイルシステムになります。 demo.css Visualforce ページの書式を設定する CSS コード。 demo.js ページがチャネルへの登録、通知の受信と表示、およびチャネルからの登録 解除に使用するコード。 json2.js stringify および parse メソッドが含まれる JavaScript ライブラリ。 StreamingApiDemo ストリーミング API 通知が表示される Visualforce ページ。 3. [設定] から、[クイック検索] ボックスに「静的リソース」と入力し、[静的リソース] を選択して、抽出した ファイルを次の名前で追加します。 ファイル名 静的リソース名 cometd.zip cometd demo.css demo_css demo.js demo_js json2.js json2_js 静的リソースについての詳細は、「Deliver Static Resources with Visualforce」を参照してください。 14 例: 対話型 Visualforce ページ ステップ 4: Visualforce ページを作成する ステップ 4: Visualforce ページを作成する チャネル通知が表示される Visualforce ページを作成します。 1. [設定] から [クイック検索] ボックスに「Visualforce ページ」と入力し、[Visualforce ページ] を選択しま す。 2. [新規] をクリックします。 3. [表示ラベル] 項目に、ページ名 StreamingAPIDemo を入力します。 4. ページのコードを、ダウンロードした StreamingApiDemo ファイルのコードで置き換えます。 <apex:page > <apex:includeScript value="{!$Resource.json2_js}"/> <apex:includeScript value="{!URLFOR($Resource.cometd, 'dojo/dojo.js')}"/> <apex:includeScript value="{!$Resource.demo_js}"/> <apex:stylesheet value="{!$Resource.demo_css}"/> <script>var token = '{!$Api.Session_ID}';</script> <div id="demo"> <div id="datastream"></div> <div id="input"> <div id="join"> <table> <tbody> <tr> <td> </td> <td> Enter Topic Name </td> <td> <input id="topic" type="text" /> </td> <td> <button id="subscribeButton" class="button">Subscribe</button> </td> </tr> </tbody> </table> </div> <div id="joined"> <table> <tbody> <tr> <td> <button id="leaveButton" class="button">Unsubscribe</button> </td> </tr> </tbody> </table> </div> </div> </div> </apex:page> 15 例: 対話型 Visualforce ページ ステップ 5: PushTopic チャネルをテストする 5. [保存] をクリックしてページを保存します。 ステップ 5: PushTopic チャネルをテストする 1. 次の URL を使用して、作成した Visualforce ページを Web ブラウザに読み込みます。 https://myinstance.salesforce.com/apex/StreamingAPIDemo。myinstance は、na1 など、利用 中の Salesforce インスタンスの名前。 2. テキストボックスに、チャネル名「/topic/InvoiceStatementUpdates」を入力します。 3. [登録] をクリックしてチャネルに登録します。 4. 別のブラウザで InvoiceStatement レコードを作成または変更します。Visualforce ページにイベント通知が表示 されます。出力は次のようになります。 { "event": { "type": "updated", "createdDate": "2012-01-27T20:22:28.000+0000" }, "sobject": { "Name": "INV-0005", "Id": "a00D0000008oLiSIAU", "Description__c": "Waiting for vendor materials report.", "Status__c": "Pending" } } _____________ { "event": { "type": "created", "createdDate": "2012-01-27T20:24:47.000+0000" }, "sobject": { "Name": "INV-0012", "Id": "a00D0000008oMt8IAE", "Description__c": "New invoice for Pyramid Construction, Inc.", "Status__c": "Open" } } _____________ 最初のイベント通知は、InvoiceStatement レコードが作成されたときの通知データを示します。2 つ目の通知 は、InvoiceStatement レコードが更新されたときの通知データを示します。 [登録解除] をクリックして、チャネルから登録解除し、通知の受信を停止します。 16 第4章 例: Visualforce ページ このコード例は、Visualforce ページからストリーミング API を実装する方法を示します。ページが実行されると チャネルに登録され、通知を受信します。 • 前提条件 • ステップ 1: オブジェクトを作成する • ステップ 2: PushTopic を作成する • ステップ 3: 静的リソースを作成する • ステップ 4: Visualforce ページを作成する • ステップ 5: PushTopic チャネルをテストする 前提条件 コード例を完了させるには、アクセス権と適切な権限が必要です。 • Developer Edition 組織にアクセスします。 まだ Force.com 開発者コミュニティのメンバーでない場合、developer.salesforce.com/signup にアク セスし、Developer Edition 組織のサインアップの説明に従ってください。すでに Enterprise Edition、Unlimited Edition、または Performance Edition を所有している場合でも、組織の使用中のデータを保護するために、サン プルデータに対するソリューションの開発、ステージングおよびテストには Developer Edition を使用します。 これは、特に、(データをただ参照するだけのアプリケーションに対し) データを挿入、更新または削除す るアプリケーションの場合に該当します。 • Developer Edition 組織で「API の有効化」権限を有効にする必要があります。この権限はデフォルトで有効に なっていますが、システム管理者によって変更されている場合があります。 • 「ストリーミング API」権限を有効にする必要があります。 メモ: 組織で「API の有効化」権限と「ストリーミング API」権限が有効であることを確認するには、 [設定] から [クイック検索] ボックスに「ユーザインターフェース」と入力し、[ユーザインターフェー ス] を選択します。 • ログインユーザが通知を受信するには、PushTopic 標準オブジェクトに対する「参照」権限が必要です。 • ログインユーザが PushTopic レコードを作成および管理するには、PushTopic 標準オブジェクトに対する「作 成」権限が必要です。 • ログインユーザが開発者コンソールを使用して PushTopic を作成するには、「Apex 開発」権限が必要です。 17 例: Visualforce ページ ステップ 1: オブジェクトを作成する ステップ 1: オブジェクトを作成する この例を実行するには、最初に InvoiceStatement オブジェクトを作成する必要があります。このオブジェクトを まだ作成していない場合は、「ステップ 1: オブジェクトを作成する」を参照してください。 ステップ 2: PushTopic を作成する この例を実行するには、PushTopic を作成する必要があります。これをまだ行っていない場合は、「ステップ 2: PushTopic を作成する」を参照してください。 ステップ 3: 静的リソースを作成する 1. http://download.cometd.org/cometd-2.2.0-distribution.tar.gz から CometD の圧縮されたアーカイブ (.tgz) ファイルをダウ ンロードします。 2. cometd-2.2.0-distribution.tar.gz から次の JavaScript ファイルを抽出します。 • cometd-2.2.0/cometd-javascript/common/target/cometd-javascript-common-2.2.0.war • cometd-2.2.0/cometd-javascript/jquery/src/main/webapp/jquery/jquery-1.5.1.js • cometd-2.2.0/cometd-javascript/jquery/src/main/webapp/jquery/json2.js • cometd-2.2.0/cometd-javascript/jquery/src/main/webapp/jquery/jquery.cometd.js Windows 環境で .tgz ファイルを抽出するには、PowerArchiver、7–zip、Winzip のようなユーティリティが必要で す。 3. 次のシェルコマンドを使用して、cometd-javascript-common-2.2.0.war から cometd.js を抽出しま す。 cd cometd-2.2.0/cometd-javascript/common/target jar xvf cometd-javascript-common-2.2.0.war org/cometd.js 4. [設定] から、[クイック検索] ボックスに「静的リソース」と入力し、[静的リソース] を選択して、抽出した ファイルを次の名前で追加します。 ファイル名 静的リソース名 cometd.js cometd jquery-1.5.1.js jquery json2.js json2 jquery.cometd.js jquery_cometd 18 例: Visualforce ページ ステップ 4: Visualforce ページを作成する ステップ 4: Visualforce ページを作成する チャネル通知が表示される Visualforce ページを作成します。 1. [設定] から [クイック検索] ボックスに「Visualforce ページ」と入力し、[Visualforce ページ] を選択しま す。 2. [新規] をクリックします。 3. ページ内のコードを次のコードで置き換えます。 <apex:page> <apex:includeScript value="{!$Resource.cometd}"/> <apex:includeScript value="{!$Resource.jquery}"/> <apex:includeScript value="{!$Resource.json2}"/> <apex:includeScript value="{!$Resource.jquery_cometd}"/> <script type="text/javascript"> (function($){ $(document).ready(function() { // Connect to the CometD endpoint $.cometd.init({ url: window.location.protocol+'//'+window.location.hostname+'/cometd/24.0/', requestHeaders: { Authorization: 'OAuth {!$Api.Session_ID}'} }); // Subscribe to a topic. JSON-encoded update will be returned // in the callback $.cometd.subscribe('/topic/InvoiceStatementUpdates', function(message) { $('#content').append('<p>Notification: ' + 'Channel: ' + JSON.stringify(message.channel) + '<br>' + 'Record name: ' + JSON.stringify(message.data.sobject.Name) + '<br>' + 'ID: ' + JSON.stringify(message.data.sobject.Id) + '<br>' + 'Event type: ' + JSON.stringify(message.data.event.type)+ '<br>' + 'Created: ' + JSON.stringify(message.data.event.createdDate) + '</p>'); }); }); })(jQuery) function disconnect() { $.cometd.disconnect(); } window.onbeforeunload = disconnect; </script> <body> <div id="content"> <h1>Streaming API Test Page</h1> <p>This is a demonstration page for Streaming API. Notifications from the InvoiceStatementUpdates channel will appear here...</p> 19 例: Visualforce ページ ステップ 5: PushTopic チャネルをテストする </div> </body> </apex:page> ステップ 5: PushTopic チャネルをテストする 1. 次の URL を使用して、Visualforce ページを Web ブラウザに読み込みます。 https://myinstance.salesforce.com/apex/StreamingPage。myinstance は、na1 など、利用中 の Salesforce インスタンスの名前です。 2. 別のブラウザで InvoiceStatement レコードを作成または変更します。Visualforce ページにイベント通知が表示 されます。 20 第5章 例: Java クライアント このコード例は、Java クライアントからストリーミング API を実装する方法を示します。Java クライアントが 実行されるとチャネルに登録され、通知を受信します。 • 例: Java クライアント • 前提条件 • ステップ 1: オブジェクトを作成する • ステップ 2: PushTopic を作成する • ステップ 3: JAR ファイルをダウンロードする • ステップ 4: ソースコードを追加する 前提条件 コード例を完了させるには、アクセス権と適切な権限が必要です。 • Developer Edition 組織にアクセスします。 まだ Force.com 開発者コミュニティのメンバーでない場合、developer.salesforce.com/signup にアク セスし、Developer Edition 組織のサインアップの説明に従ってください。すでに Enterprise Edition、Unlimited Edition、または Performance Edition を所有している場合でも、組織の使用中のデータを保護するために、サン プルデータに対するソリューションの開発、ステージングおよびテストには Developer Edition を使用します。 これは、特に、(データをただ参照するだけのアプリケーションに対し) データを挿入、更新または削除す るアプリケーションの場合に該当します。 • Developer Edition 組織で「API の有効化」権限を有効にする必要があります。この権限はデフォルトで有効に なっていますが、システム管理者によって変更されている場合があります。 • 「ストリーミング API」権限を有効にする必要があります。 メモ: 組織で「API の有効化」権限と「ストリーミング API」権限が有効であることを確認するには、 [設定] から [クイック検索] ボックスに「ユーザインターフェース」と入力し、[ユーザインターフェー ス] を選択します。 • ログインユーザが通知を受信するには、PushTopic 標準オブジェクトに対する「参照」権限が必要です。 • ログインユーザが PushTopic レコードを作成および管理するには、PushTopic 標準オブジェクトに対する「作 成」権限が必要です。 • ログインユーザが開発者コンソールを使用して PushTopic を作成するには、「Apex 開発」権限が必要です。 21 例: Java クライアント ステップ 1: オブジェクトを作成する ステップ 1: オブジェクトを作成する この例を実行するには、最初に InvoiceStatement オブジェクトを作成する必要があります。このオブジェクトを まだ作成していない場合は、「ステップ 1: オブジェクトを作成する」を参照してください。 ステップ 2: PushTopic を作成する この例を実行するには、PushTopic を作成する必要があります。これをまだ行っていない場合は、「ステップ 2: PushTopic を作成する」を参照してください。 ステップ 3: JAR ファイルをダウンロードする 次のライブラリファイルを、Java クライアントアプリケーションのストリーミング API 用のビルドパスに追加 します。 1. http://download.cometd.org/cometd-2.3.1-distribution.tar.gz から圧縮されたアーカイブファ イルをダウンロードします。 2. cometd-2.3.1.tgz から次の JAR ファイルを抽出します。 • cometd-2.3.1/cometd-java/bayeux-api/target/bayeux-api-2.3.1.jar • cometd-2.3.1/cometd-java/cometd-java-client/target/cometd-java-client-2.3.1.jar • cometd-2.3.1/cometd-java/cometd-java-common/target/cometd-java-common-2.3.1.jar 3. maven.org から圧縮された Jetty Hightide アーカイブファイル jetty-hightide-7.4.4.v20110707.tar.gz をダウンロードします。 Jetty Hightide は、オープンソースの Web コンテナサービスである Jetty のディストリビューションです。詳細 は、Jetty Hightide のドキュメントを参照してください。 4. jetty-hightide-7.4.4.v20110707.tar.gz から次の JAR ファイルを抽出します。 • jetty-hightide-7.4.4.v20110707/lib/jetty-client-7.4.4.v20110707.jar • jetty-hightide-7.4.4.v20110707/lib/jetty-http-7.4.4.v20110707.jar • jetty-hightide-7.4.4.v20110707/lib/jetty-io-7.4.4.v20110707.jar • jetty-hightide-7.4.4.v20110707/lib/jetty-util-7.4.4.v20110707.jar ステップ 4: ソースコードを追加する 1. 次のコードを StreamingClientExample.java という名前の Java ソースファイルに追加します。このコー ドは、PushTopic チャネルに登録し、ストリーミング情報を処理します。 package demo; import org.cometd.bayeux.Channel; import org.cometd.bayeux.Message; import org.cometd.bayeux.client.ClientSessionChannel; 22 例: Java クライアント import import import import ステップ 4: ソースコードを追加する org.cometd.bayeux.client.ClientSessionChannel.MessageListener; org.cometd.client.BayeuxClient; org.cometd.client.transport.ClientTransport; org.cometd.client.transport.LongPollingTransport; import org.eclipse.jetty.client.ContentExchange; import org.eclipse.jetty.client.HttpClient; import import import import java.net.MalformedURLException; java.net.URL; java.util.HashMap; java.util.Map; /** * This example demonstrates how a streaming client works * against the Salesforce Streaming API. **/ public class StreamingClientExample { // // // // This URL is used only for logging in. The LoginResult returns a serverUrl which is then used for constructing the streaming URL. The serverUrl points to the endpoint where your organization is hosted. static final String LOGIN_ENDPOINT = "https://login.salesforce.com"; private static final String USER_NAME = "[email protected]"; private static final String PASSWORD = "change_this_to_your_testpassword"; // NOTE: Putting passwords in code is not a good practice and not recommended. // Set this to // against the private static private static true only when using this client Summer'11 release (API version=22.0). final boolean VERSION_22 = false; final boolean USE_COOKIES = VERSION_22; // The channel to subscribe to. Same as the name of the PushTopic. // Be sure to create this topic before running this sample. private static final String CHANNEL = VERSION_22 ? "/InvoiceStatementUpdates" : "/topic/InvoiceStatementUpdates"; private static final String STREAMING_ENDPOINT_URI = VERSION_22 ? "/cometd" : "/cometd/38.0"; // The long poll duration. private static final int CONNECTION_TIMEOUT = 20 * 1000; // milliseconds private static final int READ_TIMEOUT = 120 * 1000; // milliseconds public static void main(String[] args) throws Exception { System.out.println("Running streaming client example...."); final BayeuxClient client = makeClient(); client.getChannel(Channel.META_HANDSHAKE).addListener (new ClientSessionChannel.MessageListener() { 23 例: Java クライアント ステップ 4: ソースコードを追加する public void onMessage(ClientSessionChannel channel, Message message) { System.out.println("[CHANNEL:META_HANDSHAKE]: " + message); boolean success = message.isSuccessful(); if (!success) { String error = (String) message.get("error"); if (error != null) { System.out.println("Error during HANDSHAKE: " + error); System.out.println("Exiting..."); System.exit(1); } Exception exception = (Exception) message.get("exception"); if (exception != null) { System.out.println("Exception during HANDSHAKE: "); exception.printStackTrace(); System.out.println("Exiting..."); System.exit(1); } } } }); client.getChannel(Channel.META_CONNECT).addListener( new ClientSessionChannel.MessageListener() { public void onMessage(ClientSessionChannel channel, Message message) { System.out.println("[CHANNEL:META_CONNECT]: " + message); boolean success = message.isSuccessful(); if (!success) { String error = (String) message.get("error"); if (error != null) { System.out.println("Error during CONNECT: " + error); System.out.println("Exiting..."); System.exit(1); } } } }); client.getChannel(Channel.META_SUBSCRIBE).addListener( new ClientSessionChannel.MessageListener() { public void onMessage(ClientSessionChannel channel, Message message) { System.out.println("[CHANNEL:META_SUBSCRIBE]: " + message); boolean success = message.isSuccessful(); if (!success) { 24 例: Java クライアント ステップ 4: ソースコードを追加する String error = (String) message.get("error"); if (error != null) { System.out.println("Error during SUBSCRIBE: " + error); System.out.println("Exiting..."); System.exit(1); } } } }); client.handshake(); System.out.println("Waiting for handshake"); boolean handshaken = client.waitFor(10 * 1000, BayeuxClient.State.CONNECTED); if (!handshaken) { System.out.println("Failed to handshake: " + client); System.exit(1); } System.out.println("Subscribing for channel: " + CHANNEL); client.getChannel(CHANNEL).subscribe(new MessageListener() { @Override public void onMessage(ClientSessionChannel channel, Message message) { System.out.println("Received Message: " + message); } }); System.out.println("Waiting for streamed data from your organization ..."); while (true) { // This infinite loop is for demo only, // to receive streamed events on the // specified topic from your organization. } } private static BayeuxClient makeClient() throws Exception { HttpClient httpClient = new HttpClient(); httpClient.setConnectTimeout(CONNECTION_TIMEOUT); httpClient.setTimeout(READ_TIMEOUT); httpClient.start(); String[] pair = SoapLoginUtil.login(httpClient, USER_NAME, PASSWORD); if (pair == null) { System.exit(1); } 25 例: Java クライアント ステップ 4: ソースコードを追加する assert pair.length == 2; final String sessionid = pair[0]; String endpoint = pair[1]; System.out.println("Login successful!\nServer URL: " + endpoint + "\nSession ID=" + sessionid); Map<String, Object> options = new HashMap<String, Object>(); options.put(ClientTransport.TIMEOUT_OPTION, READ_TIMEOUT); LongPollingTransport transport = new LongPollingTransport( options, httpClient) { @Override protected void customize(ContentExchange exchange) { super.customize(exchange); exchange.addRequestHeader("Authorization", "OAuth " + sessionid); } }; BayeuxClient client = new BayeuxClient(salesforceStreamingEndpoint( endpoint), transport); if (USE_COOKIES) establishCookies(client, USER_NAME, sessionid); return client; } private static String salesforceStreamingEndpoint(String endpoint) throws MalformedURLException { return new URL(endpoint + STREAMING_ENDPOINT_URI).toExternalForm(); } private static void establishCookies(BayeuxClient client, String user, String sid) { client.setCookie("com.salesforce.LocaleInfo", "us", 24 * 60 * 60 * 1000); client.setCookie("login", user, 24 * 60 * 60 * 1000); client.setCookie("sid", sid, 24 * 60 * 60 * 1000); client.setCookie("language", "en_US", 24 * 60 * 60 * 1000); } } 2. StreamingClientExample.java を編集して、次の値を変更します。 ファイル名 静的リソース名 USER_NAME ログインユーザのユーザ名 PASSWORD USER_NAME (ログインユーザ) のパスワード CHANNEL /topic/InvoiceStatementUpdates LOGIN_ENDPOINT https://test.salesforce.com (Sandbox を使用する場合のみ。本番組織の 場合は、LOGIN_ENDPOINT の変更は必要ありません)。 26 例: Java クライアント ステップ 4: ソースコードを追加する 3. 次のコードを SoapLoginUtil.java という名前の Java ソースファイルに追加します。このコードは、ユー ザ名とパスワードをサーバに送信し、セッション ID を受信します。 重要: 他のユーザのユーザ名とパスワードは処理しないでください。また、本番環境で使用する場合 は、ログインを OAuth に委任してください。 package demo; import import import import import java.io.ByteArrayInputStream; java.io.IOException; java.io.UnsupportedEncodingException; java.net.MalformedURLException; java.net.URL; import import import import import org.eclipse.jetty.client.ContentExchange; org.eclipse.jetty.client.HttpClient; org.xml.sax.Attributes; org.xml.sax.SAXException; org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; public final class SoapLoginUtil { // The enterprise SOAP API endpoint used for the login call in this example. private static final String SERVICES_SOAP_PARTNER_ENDPOINT = "/services/Soap/u/22.0/"; private static final String ENV_START = "<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' " + "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " + "xmlns:urn='urn:partner.soap.sforce.com'><soapenv:Body>"; private static final String ENV_END = "</soapenv:Body></soapenv:Envelope>"; private static byte[] soapXmlForLogin(String username, String password) throws UnsupportedEncodingException { return (ENV_START + " <urn:login>" + " <urn:username>" + username + "</urn:username>" + " <urn:password>" + password + "</urn:password>" + " </urn:login>" + ENV_END).getBytes("UTF-8"); } public static String[] login(HttpClient client, String username, String password) throws IOException, InterruptedException, SAXException, ParserConfigurationException { ContentExchange exchange = new ContentExchange(); exchange.setMethod("POST"); 27 例: Java クライアント ステップ 4: ソースコードを追加する exchange.setURL(getSoapURL()); exchange.setRequestContentSource(new ByteArrayInputStream(soapXmlForLogin( username, password))); exchange.setRequestHeader("Content-Type", "text/xml"); exchange.setRequestHeader("SOAPAction", "''"); exchange.setRequestHeader("PrettyPrint", "Yes"); client.send(exchange); exchange.waitForDone(); String response = exchange.getResponseContent(); SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); SAXParser saxParser = spf.newSAXParser(); LoginResponseParser parser = new LoginResponseParser(); saxParser.parse(new ByteArrayInputStream( response.getBytes("UTF-8")), parser); if (parser.sessionId == null || parser.serverUrl == null) { System.out.println("Login Failed!\n" + response); return null; } URL soapEndpoint = new URL(parser.serverUrl); StringBuilder endpoint = new StringBuilder() .append(soapEndpoint.getProtocol()) .append("://") .append(soapEndpoint.getHost()); if (soapEndpoint.getPort() > 0) endpoint.append(":") .append(soapEndpoint.getPort()); return new String[] {parser.sessionId, endpoint.toString()}; } private static String getSoapURL() throws MalformedURLException { return new URL(StreamingClientExample.LOGIN_ENDPOINT + getSoapUri()).toExternalForm(); } private static String getSoapUri() { return SERVICES_SOAP_PARTNER_ENDPOINT; } private static class LoginResponseParser extends DefaultHandler { private boolean inSessionId; private String sessionId; private boolean inServerUrl; private String serverUrl; @Override public void characters(char[] ch, int start, int length) { 28 例: Java クライアント ステップ 4: ソースコードを追加する if (inSessionId) sessionId = new String(ch, start, length); if (inServerUrl) serverUrl = new String(ch, start, length); } @Override public void endElement(String uri, String localName, String qName) { if (localName != null) { if (localName.equals("sessionId")) { inSessionId = false; } if (localName.equals("serverUrl")) { inServerUrl = false; } } } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) { if (localName != null) { if (localName.equals("sessionId")) { inSessionId = true; } if (localName.equals("serverUrl")) { inServerUrl = true; } } } } } 4. 別のブラウザウィンドウで、InvoiceStatement レコードを作成または変更します。PushTopic 内のクエリに対応 するデータを作成または変更すると、出力は次のようになります。 Running streaming client example.... Login successful! Server URL: https://www.salesforce.com Session ID=00DD0000000FSp9!AQIAQIVjGYijFhiAROTc455T6kEVeJGXuW5VCnp LANCMawS7.p5fXbjYlqCgx7They_zFjmP5n9HxvfUA6xGSGtC1Nb6P4S. Waiting for handshake [CHANNEL:META_HANDSHAKE]: { "id":"1", "minimumVersion":"1.0", "supportedConnectionTypes":["long-polling"], "successful":true, "channel":"/meta/handshake", "clientId":"31t0cjzfbgnfqn1rggumba0k98u", "version":"1.0" } 29 例: Java クライアント ステップ 4: ソースコードを追加する [CHANNEL:META_CONNECT]: { "id":"2", "successful":true, "advice":{"interval":0,"reconnect":"retry","timeout":110000}, "channel":"/meta/connect"} Subscribing for channel: /topic/InvoiceStatementUpdates Waiting for streamed data from your organization ... [CHANNEL:META_SUBSCRIBE]: { "id":"4", "subscription":"/topic/InvoiceStatementUpdates", "successful":true, "channel":"/meta/subscribe" } [CHANNEL:META_CONNECT]: { "id":"3", "successful":true, "channel":"/meta/connect" } Received Message: { "data": { "sobject": { "Name":"INV-0002", "Id":"001D000000J3fTHIAZ", "Status__c":"Pending"}, "event":{"type":"updated", "createdDate":"2011-09-06T18:51:08.000+0000" } }, "channel":"/topic/InvoiceStatementUpdates" } [CHANNEL:META_CONNECT]: { "id":"5", "successful":true, "channel":"/meta/connect" } 30 第6章 例: Visualforce ページを使用した PushTopic スト リーミングイベントと汎用ストリーミングイベ ントの再生 このサンプルアプリケーションでは、PushTopic イベントと汎用イベントのデュラブルストリーミングイベント に登録する方法について説明します。このアプリケーションには、2 つの対話型Visualforceページが含まれてい ます。1 つは PushTopic イベント用、1 つは汎用イベント用です。テストイベントを生成して、各ページに表示 できます。どのイベントを取得して表示するかは、再生オプションを設定して指定します。 イベントを再生するためのロジックは、Visualforce ページの Visualforce コンポーネント内に含まれています。こ のコンポーネントは Salesforce が提供する CometD 拡張を登録し、再生オプションを設定します。 このセクションの内容: 前提条件 デュラブルストリーミングのサンプルの実行に必要となる権限を設定します。 サンプルプロジェクトを組織にリリースする ワークベンチを使用して、すべてのプロジェクトコンポーネントを組織にコピーします。 デュラブル PushTopic ストリーミングのサンプル デュラブル PushTopic ストリーミング Visualforce のサンプルでは、再生オプションを使用してデュラブル PushTopic イベント通知の登録と受信を行う方法について説明しています。 デュラブル汎用ストリーミングのサンプル デュラブル汎用ストリーミング Visualforce のサンプルでは、再生オプションを使用してデュラブル汎用イベ ント通知の登録と受信を行う方法について説明しています。 イベントの再生サンプル: コードのウォークスルー CometD 再生拡張を JavaScript で登録して使用する方法について説明します。 前提条件 デュラブルストリーミングのサンプルの実行に必要となる権限を設定します。 • Developer Edition 組織へのアクセス権があり、「API の有効化」権限と「ストリーミング API」権限が有効に なっている必要があります。「API の有効化」権限はデフォルトで有効になっていますが、システム管理者 によって変更されている場合があります。 まだ Force.com 開発者コミュニティのメンバーでない場合、developer.salesforce.com/signup にアク セスし、Developer Edition 組織のサインアップの説明に従ってください。すでに Enterprise Edition、Unlimited 31 例: Visualforce ページを使用した PushTopic ストリーミン グイベントと汎用ストリーミングイベントの再生 サンプルプロジェクトを組織にリリースする Edition、または Performance Edition を所有している場合でも、組織の使用中のデータを保護するために、サン プルデータに対するソリューションの開発、ステージングおよびテストには Developer Edition を使用します。 これは、特に、(データをただ参照するだけのアプリケーションに対し) データを挿入、更新または削除す るアプリケーションの場合に該当します。 メモ: 組織で「API の有効化」権限と「ストリーミング API」権限が有効であることを確認するには、 [設定] から [クイック検索] ボックスに「ユーザインターフェース」と入力し、[ユーザインターフェー ス] を選択します。 • ログインユーザが通知を受信するには、StreamingChannel 標準オブジェクトに対する「参照」権限が必要で す。 • ログインユーザが通知を作成および管理するには、StreamingChannel 標準オブジェクトに対する「作成」権 限が必要です。 • ログインユーザが Apex クラスを保存するには、「Apex 開発」権限が必要です。 • ログインユーザが Visualforce ページを保存するには、「アプリケーションのカスタマイズ」権限が必要で す。 サンプルプロジェクトを組織にリリースする ワークベンチを使用して、すべてのプロジェクトコンポーネントを組織にコピーします。 1. developerforce GitHub リポジトリから Salesforce Durable Streaming Demo .zip ファイルをダウンロー ドします。 必要に応じて、https://github.com/developerforce/SalesforceDurableStreamingDemo でプロジェクトのコンテンツを 参照できます。サンプルアプリケーションには 2 つの Visualforce ページがあり、関連コンポーネントといく つかの共通コンポーネントが含まれています。.zip ファイルをリリースすると、組織に次の共通コンポーネ ントがインストールされます。 コンポーネント 説明 cometdReplayExtension JavaScript の CometD 拡張を表す静的リソース。この拡 張は、ストリーミング API の再生メカニズムを実装 します。 cometd、jquery、jquery_cometd、json2 CometD、jquery、および JSON の静的リソース。 次のアプリケーションコンポーネントは、デュラブル PushTopic ストリーミングページ用です。 コンポーネント 説明 DurablePushTopicEventDisplay CometD 拡張 cometdReplayExtension を使用して イベントを再生するVisualforceコンポーネント。この 拡張はハンドシェイクと登録コールを処理し、再生 オプションを設定します。 32 例: Visualforce ページを使用した PushTopic ストリーミン グイベントと汎用ストリーミングイベントの再生 サンプルプロジェクトを組織にリリースする コンポーネント 説明 Visualforce コンポーネントに再生機能を含めると、 Visualforce ページに再生機能を追加してアプリケー ションで再利用できます。 DurablePushTopicStreamingController Visualforce ページの基盤となるロジックを保持する Apex コントローラ。 DurablePushTopicStreamingDemo Visualforce ページ Visualforce ページ。このページはメインページであ り、デュラブル PushTopic イベントの生成、表示、再 生に使用します。 次のアプリケーションコンポーネントは、デュラブル汎用ストリーミングページ用です。 コンポーネント 説明 DurableGenericEventDisplay CometD 拡張 cometdReplayExtension を使用して イベントを再生するVisualforceコンポーネント。この 拡張はハンドシェイクと登録コールを処理し、再生 オプションを設定します。 Visualforce コンポーネントに再生機能を含めると、 Visualforce ページに再生機能を追加してアプリケー ションで再利用できます。 DurableGenericStreamingController Visualforce ページの基盤となるロジックを保持する Apex コントローラ。 StreamingChannel ストリーミングチャネルの作成に使用するカスタム オブジェクト。 DurableGenericStreamingDemo Visualforce ページ Visualforce ページ。このページはメインページであ り、デュラブル汎用イベントの生成、表示、再生に 使用します。 DurableStreamingDemo 権限セット StreamingChannel sObject に参照および作成アクセス権 を付与するために使用する権限セット。 ワークベンチを使用して、zip ファイルを組織に移行します。 2. https://workbench.developerforce.com/login.php でワークベンチにログインします。 重要: ワークベンチは、無料のオープンソースのコミュニティサポートツールです (ワークベンチのヘ ルプページを参照)。Salesforceは、デモ目的でのみワークベンチのホスト型インスタンスを提供してい ます。このワークベンチのホスト型インスタンスを本番データベースのデータへのアクセスに使用す ることはお勧めしません。ワークベンチを本番データベースに使用する場合は、各自で所有するリ 33 例: Visualforce ページを使用した PushTopic ストリーミン グイベントと汎用ストリーミングイベントの再生 デュラブル PushTopic ストリーミングのサンプル ソースを使用してワークベンチをダウンロード、ホスト、および設定してください。ワークベンチ は、https://github.com/ryanbrainard/forceworkbench/releases からダウンロードできます。 3. [環境] は、本番のデフォルト値のままにします。 4. [API バージョン] の値が 37.0 以上であることを確認します。 5. サービスの利用規約に同意し、[Salesforce でログイン] をクリックします。 6. Developer Edition 組織のユーザ名とパスワードを入力し、[ログイン] をクリックします。 7. [移行] > [リリース] を選択します。 8. [ファイルを選択] をクリックして、ダウンロードした .zip ファイルを見つけます。 9. [次へ] をクリックして、[リリース] をクリックします。 10. リリースが完了し、リリースの状況が [成功] に変更されるまで待ちます。 11. 別のブラウザタブで組織にログインします。 関連トピック: GitHub: ストリーミング再生クライアント拡張 デュラブル PushTopic ストリーミングのサンプル デュラブル PushTopic ストリーミング Visualforce のサンプルでは、再生オプションを使用してデュラブル PushTopic イベント通知の登録と受信を行う方法について説明しています。 Visualforce ページを使用して PushTopic イベントを生成および再生す る このステップでは、Visualforce ページを使用して独自の PushTopic ストリーミングイベントを生成し、それらの イベントを異なるオプションで再生します。 Visualforce ページが読み込まれると、Account オブジェクトに PushTopic が作成されます。イベントを再生するオ プションによって、このページもこのトピックに登録し、取引先の作成、更新、削除の通知を受信します。 Visualforce ページでは、作成、更新、削除を行う取引先の名前を指定できます。これらの操作によってイベン ト通知が生成され、[通知] セクションに表示されます。どのイベントを受信して表示するかは、再生オプショ ンで登録して制御できます。イベントを生成したら、次のイベントからイベントの再生を開始できます。 • 再生 ID によって指定した、特定のイベント後のすべてのイベント。 • 登録直後にブロードキャストされた最初のイベント (再生オプション -1)。 • 過去 24 時間以内に組織に保持された最も古いイベント (再生オプション -2)。このサンプルでは、再生オプ ション -2 をデフォルトオプションとして使用しています。 この Visualforce のサンプルは、デュラブルストリーミングデモアプリケーションの一部です。 1. [永続ストリーミングデモ] アプリケーションを開きます。 2. [永続 PushTopic ストリーミングデモ] タブをクリックします。 34 例: Visualforce ページを使用した PushTopic ストリーミン グイベントと汎用ストリーミングイベントの再生 Visualforce ページを使用して PushTopic イベントを生成 および再生する Visualforce ページが読み込まれ、Account オブジェクト用に作成された PushTopic に登録されます。 3. Visualforce ページで、取引先用にいくつかのイベントを生成します。たとえば、「Test account」を生成 します。 4. [作成、更新、新規取引先を削除] をクリックします。 メモ: このページはデフォルト (-2) で新しいイベントと古いイベントすべてに登録し、[通知] セクショ ンにイベントを表示します。イベントを初めて生成したときは保存されているイベントはなく、新し いイベントのみが表示されます。 5. イベントが読み取られる時点を変更するには、[ID から再実行] 項目に読み取りを開始する再生 ID を入力し ます。たとえば、再生 ID 2 のイベントより後のすべてのイベントを読み取るには、「2」と入力します。そ の後、[登録を更新] をクリックします。 [通知] セクションが更新され、再生 ID が 3 の最新イベントのみが表示されます。 6. 登録後に送信されたイベントのみを受信するには、[ID から再実行] 項目に「-1」と入力します。その後、 [登録を更新] をクリックします。 この時点後の新規イベントのみが表示されるため、[通知] セクションはクリアされます。 7. 取引先名に「Lightning」を使用して、いくつかの新しいイベントを前と同様の方法で生成します。 [通知] セクションが新規イベントで更新され、古いイベントは表示されません。 35 例: Visualforce ページを使用した PushTopic ストリーミン グイベントと汎用ストリーミングイベントの再生 Visualforce ページを使用して PushTopic イベントを生成 および再生する 8. 再生オプションを -2 に戻します。 ページには、以前送信されたイベントも含めて、すべてのイベントが表示されます。 36 例: Visualforce ページを使用した PushTopic ストリーミン グイベントと汎用ストリーミングイベントの再生 デュラブル汎用ストリーミングのサンプル デュラブル汎用ストリーミングのサンプル デュラブル汎用ストリーミング Visualforce のサンプルでは、再生オプションを使用してデュラブル汎用イベン ト通知の登録と受信を行う方法について説明しています。 権限セットを割り当てる 1. [設定] から、[クイック検索] ボックスに「権限セット」と入力し、[権限セット] を選択します。 2. [DurableStreamingDemo] をクリックして、[割り当ての管理] をクリックします。 3. [割り当てを追加] をクリックします。 4. サンプルを実行しているユーザの横にあるチェックボックスをオンにして、[割り当て]をクリックします。 5. [完了] をクリックします。 37 例: Visualforce ページを使用した PushTopic ストリーミン グイベントと汎用ストリーミングイベントの再生 ストリーミングチャネルを作成する ストリーミングチャネルを作成する 組織で適切な ストリーミング API 権限を有効にする必要があります。 Salesforce UI を使用して、StreamingChannel オブジェクトを作成します。 1. Developer Edition 組織にログインします。 2. Salesforce Classic を使用している場合は、[すべてのタブ] (+)で[ストリーミングチャネル]を選択します。Lightning Experience を使用している場合は、アプリケーションランチャーから [その他の項目] を選択し、[ストリーミ ングチャネル] をクリックします。 3. [ストリーミングチャネル] タブで [新規] をクリックして、ストリーミングチャネルを作成します。 4. [ストリーミングチャネル名] に「/u/TestStreaming」と入力し、説明 (省略可能) を追加します。新しい [ストリーミングチャネル] ページは、次のようになります。 5. [保存] をクリックします。これで、クライアントが通知用に登録できるストリーミングチャネルが作成さ れました。 StreamingChannel は通常の作成可能な Salesforce オブジェクトであるため、Apex や、SOAP API または REST API など のデータ API を使用するか、ワークベンチなどのツールを使用して、プログラムで作成することもできます。 詳細は、「StreamingChannel」を参照してください。 Visualforce ページを使用して汎用イベントを生成および再生する このステップでは、Visualforce ページを使用して独自のストリーミングイベントを生成し、それらのイベント を異なるオプションで再生します。 Visualforce ページは、イベントを再生するオプションを使用してイベントに登録するストリーミングクライア ントをシミュレーションします。Visualforce ページでは、イベントのメッセージ、および作成するメッセージ 数を指定できます。このページはイベントをリスンし、受信したイベントを [通知] セクションに表示します。 イベントを生成したら、次のイベントからイベントの再生を開始できます。 • 再生 ID によって指定した、特定のイベント後のすべてのイベント。 • 登録直後にブロードキャストされた最初のイベント (再生オプション -1)。 • 過去 24 時間以内に組織に保持された最も古いイベント (再生オプション -2)。このサンプルでは、再生オプ ション -2 をデフォルトオプションとして使用しています。 この Visualforce のサンプルは、デュラブルストリーミングデモアプリケーションの一部です。 38 例: Visualforce ページを使用した PushTopic ストリーミン グイベントと汎用ストリーミングイベントの再生 Visualforce ページを使用して汎用イベントを生成および 再生する 1. [永続ストリーミングデモ] アプリケーションを開きます。 2. [永続汎用ストリーミングデモ] タブをクリックします。 Visualforce ページが読み込まれ、以前に作成したテストチャネルに登録されます。 3. Visualforce ページで、いくつかのイベントを生成します。メッセージテキストに任意のテキスト (「テスト メッセージ」など) を入力します。イベント数に「10」と入力します。 4. [生成] をクリックします。 メモ: このページはデフォルト (-2) ですべてのイベントに登録し、[通知] セクションにイベントを表示 します。イベントを初めて生成したときは保存されているイベントはなく、新しいイベントのみが表 示されます。 5. イベントが読み取られる時点を変更するには、[ID から再実行] 項目に読み取りを開始する再生 ID を入力し ます。たとえば、再生 ID 5 のイベントより後のすべてのイベントを読み取るには、「5」と入力します。そ の後、[登録を更新] をクリックします。 [通知] セクションが更新され、再生 ID 6 以降の最新 5 件のイベントのみが表示されます。 6. 登録後に送信されたイベントのみを受信するには、[ID から再実行] 項目に「-1」と入力します。その後、 [登録を更新] をクリックします。 この時点後の新規イベントのみが表示されるため、[通知] セクションはクリアされます。 7. 「新規イベント」というメッセージのいくつかの新しいイベントをステップ 3 と同様の方法で生成します。 [通知] セクションが新規イベントで更新され、古いイベントは表示されません。 39 例: Visualforce ページを使用した PushTopic ストリーミン グイベントと汎用ストリーミングイベントの再生 Visualforce ページを使用して汎用イベントを生成および 再生する 8. 再生オプションを -2 に戻します。 ページには、以前送信されたイベントも含めて、すべてのイベントが表示されます。 40 例: Visualforce ページを使用した PushTopic ストリーミン グイベントと汎用ストリーミングイベントの再生 イベントの再生サンプル: コードのウォークスルー イベントの再生サンプル: コードのウォークスルー CometD 再生拡張を JavaScript で登録して使用する方法について説明します。 イベントの再生の JavaScript サンプル このデュラブルストリーミングのサンプルには、cometdReplayExtension 再生拡張を使用してイベントを 再生する JavaScript コードが含まれています。このコードは DurableGenericEventDisplay コンポーネントと DurablePushTopicEventDisplay Visualforce コンポーネント内にあり、Visualforce ページに埋め込まれています。JavaScript を Visualforce ページに直接追加するか、Visualforce コンポーネントを再利用できます。このセクションではサン プルコンポーネント部分が強調表示されています。 まず、Salesforce が提供する CometD 拡張 cometdReplayExtension を登録してイベントを再生します。このス ニペットでは、ストリーミングチャネルと再生オプションも設定します。registerExtension の最初の引数 は、拡張の登録解除に使用する任意の名前です。 // Register Generic Streaming Replay extension var replayExtension = new cometdReplayExtension(); replayExtension.setChannel(<Streaming Channel to Subscribe to>); 41 例: Visualforce ページを使用した PushTopic ストリーミン グイベントと汎用ストリーミングイベントの再生 イベントの再生サンプル: コードのウォークスルー replayExtension.setReplay(<Event Replay Option>); cometd.registerExtension('myReplayExtensionName', replayExtension); 次に、クライアントが CometD 再生エンドポイントに接続します。エンドポイントの API バージョンは 37.0 以降 である必要があります。現在のセッションのセッション ID 値が Authorization ヘッダーで渡されます。 // Connect to the CometD endpoint cometd.init({ url: 'https://Salesforce_instance/cometd/37.0/', requestHeaders: { Authorization: 'OAuth <Session ID>'} }); 最後に、CometD subscribe() 関数のコールバックを指定します。チャネルでメッセージが受信されたとき に、CometD がこのコールバック関数をコールします。このサンプルでは、コールバック関数によってページ にメッセージデータが表示されます。ID 値が "content" の div HTML 要素にデータが追加されます。 // Subscribe to a topic. JSON-encoded update will be returned in the callback cometd.subscribe(channel, function(message) { $('#content').append('<p>Notification ' + 'on channel: ' + JSON.stringify(message.channel) + '<br>' + 'Payload: ' + JSON.stringify(message.data.payload) + '<br>' + 'Replay Id: ' + JSON.stringify(message.data.event.replayId) + '<br>' + 'Full message: ' + JSON.stringify(message) + '</p>'); } ); cometdReplayExtension 拡張 cometdReplayExtensionでは、受信メッセージと送信メッセージでコールされるコールバックを使用できます。こ れらのコールバックは、ハンドシェイク時に拡張の登録を確認し、登録時に再生オプションを設定するロジッ クを実装します。 ハンドシェイク時に、受信メッセージのコールバックで再生拡張が登録されているかどうかが確認されます。 登録されている場合は、_extensionEnabled 変数が true に設定されます。 this.incoming = function(message) { if (message.channel === '/meta/handshake') { if (message.ext && message.ext[REPLAY_FROM_KEY] == true) { _extensionEnabled = true; } } } 登録時に、送信メッセージのコールバックで _extensionEnabled 変数を使用して再生拡張が登録されてい るかどうかが確認されます。拡張が登録されている場合、コールバックは指定された再生オプションに基づい 42 例: Visualforce ページを使用した PushTopic ストリーミン グイベントと汎用ストリーミングイベントの再生 イベントの再生サンプル: コードのウォークスルー てイベントに登録します。このサンプルでは、拡張の setReplay() 関数をコールして再生オプションを設定 しています。 this.outgoing = function(message) { if (message.channel === '/meta/subscribe') { if (_extensionEnabled) { if (!message.ext) { message.ext = {}; } var replayFromMap = {}; replayFromMap[_channel] = _replay; // add "ext : { "replay" : { CHANNEL : REPLAY_VALUE }}" // to subscribe message. message.ext[REPLAY_FROM_KEY] = replayFromMap; } } }; 43 第7章 例: 認証 開発者テスト用に単純な認証スキームを設定できます。本番システムには、OAuth 2.0 などの強固な認証を使用 してください。 • 開発者テスト用の認証の設定 • OAuth 2.0 での認証の設定 開発者テスト用の認証の設定 開発者テスト用の認証を設定する手順は、次のとおりです。 重要: この認証方法は簡単に使用できるため、コードをすばやくテストする場合にお勧めです。ただし、 本番環境では OAuth 2.0 を使用してセキュリティを強化することをお勧めします。接続アプリケーション による OAuth 認証方法には、アクセスが制限されるなどの利点があります。 1. SOAP API の login() コールを使用してログインし、セッション ID を取得します。 2. このセッション ID を使用して HTTP 認証ヘッダーを次のように設定します。 Authorization: Bearer sessionId CometD エンドポイントでは、すべての要求にセッション ID が必要です。また、Salesforce サーバによって設 定された追加の Cookie が必要です。 詳細は、「ステップ 4: ソースコードを追加する」を参照してください。 OAuth 2.0 での認証の設定 OAuth 2.0 の設定では、ユーザインターフェース内とその他の場所でいくつかの設定を行う必要があります。手 順に不明な点がある場合は、『Force.com REST API 開発者ガイド』または OAuth 2.0 のドキュメントを参照してくだ さい。 この章のサンプル Java コードでは Apache HttpClient ライブラリを使用します。このライブラリは http://hc.apache.org/httpcomponents-client-ga/ からダウンロードできます。 1. Salesforce Classic では、[設定] から、[クイック検索] ボックスに「アプリケーション」と入力し、[アプリケー ション]を選択します。Lightning Experienceでは、[クイック検索] ボックスに「アプリケーション」と入力し、 [アプリケーションマネージャ]を選択します。[接続アプリケーション] 関連リストの [新規] をクリックし て、新しい接続アプリケーションを作成します。 44 例: 認証 OAuth 2.0 での認証の設定 ここで指定する [コールバック URL] は、Web アプリケーションのコールバック URL と同じです。Java を使 用する場合、通常はこれはサーブレットです。また、セキュアである必要があります。http:// は機能せ ず、https:// のみが機能します。開発環境では、コールバック URL は https://my-website/_callback のような形になります。[保存] をクリックすると、[コンシューマ鍵] が作成され、表示されます。また、 [コンシューマの秘密] が作成されます (表示するにはリンクをクリックします)。 メモ: OAuth 2.0 仕様では、「コンシューマ」ではなく「クライアント」を使用します。Salesforceは OAuth 2.0 をサポートします。 Salesforce のリモートアクセスアプリケーションで使用される用語と、この手順の残りの部分にあるサンプ ルコードに含まれる値は次のように対応します。 • client_id は [コンシューマ鍵] に対応 • client_secret は [コンシューマの秘密] に対応 • redirect_uri は [コールバック URL] に対応 その他に指定する必要のあるパラメータは grant_type です。OAuth 2.0 コールバックでは、サンプルに示 すように、値は authorization_code です。これらのパラメータの詳細については、 https://developer.salesforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com を参照してください。 client_id (または consumer key) の値と client_secret (または consumer secret) が有効な場合、 Salesforce はコールバックを、access_token. の値が含まれる redirect_uri に指定された URI に送信し ます。 2. Java またはその他のクライアントアプリケーションから、認証 URL への要求を行い、grant_type、 client_id、client_secret、username、および password を渡します。次に例を示します。 HttpClient httpclient = new DefaultHttpClient(); HttpPost post = new HttpPost(baseURL); List<BasicNameValuePair> parametersBody = new ArrayList<BasicNameValuePair>(); parametersBody.add(new parametersBody.add(new parametersBody.add(new parametersBody.add(new parametersBody.add(new BasicNameValuePair("grant_type", password)); BasicNameValuePair("client_id", clientId)); BasicNameValuePair("client_secret", client_secret)); BasicNameValuePair("username", "[email protected]")); BasicNameValuePair("password", "swordfish")); 重要: この認証方法は開発環境でのみ使用し、本番コードには使用しないでください。 例: この例では、セッション ID を取得 (認証) し、最初の応答に含まれるリソース https://instance.salesforce.com/id/00Dxxxxxxxxxxxx/005xxxxxxxxxxxx に従って、ユーザ に関する詳細情報を取得します。 public static void oAuthSessionProvider(String loginHost, String username, String password, String clientId, String secret) throws HttpException, IOException { // Set up an HTTP client that makes a connection to REST API. DefaultHttpClient client = new DefaultHttpClient(); HttpParams params = client.getParams(); HttpClientParams.setCookiePolicy(params, CookiePolicy.RFC_2109); 45 例: 認証 OAuth 2.0 での認証の設定 params.setParameter(HttpConnectionParams.CONNECTION_TIMEOUT, 30000); // Set the SID. System.out.println("Logging in as " + username + " in environment " + loginHost); String baseUrl = loginHost + "/services/oauth2/token"; // Send a post request to the OAuth URL. HttpPost oauthPost = new HttpPost(baseUrl); // The request body must contain these 5 values. List<BasicNameValuePair> parametersBody = new ArrayList<BasicNameValuePair>(); parametersBody.add(new BasicNameValuePair("grant_type", "password")); parametersBody.add(new BasicNameValuePair("username", username)); parametersBody.add(new BasicNameValuePair("password", password)); parametersBody.add(new BasicNameValuePair("client_id", clientId)); parametersBody.add(new BasicNameValuePair("client_secret", secret)); oauthPost.setEntity(new UrlEncodedFormEntity(parametersBody, HTTP.UTF_8)); // Execute the request. System.out.println("POST " + baseUrl + "...\n"); HttpResponse response = client.execute(oauthPost); int code = response.getStatusLine().getStatusCode(); Map<String, String> oauthLoginResponse = (Map<String, String>) JSON.parse(EntityUtils.toString(response.getEntity())); System.out.println("OAuth login response"); for (Map.Entry<String, String> entry : oauthLoginResponse.entrySet()) { System.out.println(String.format(" %s = %s", entry.getKey(), entry.getValue())); } System.out.println(""); // Get user info. String userIdEndpoint = oauthLoginResponse.get("id"); String accessToken = oauthLoginResponse.get("access_token"); List<BasicNameValuePair> qsList = new ArrayList<BasicNameValuePair>(); qsList.add(new BasicNameValuePair("oauth_token", accessToken)); String queryString = URLEncodedUtils.format(qsList, HTTP.UTF_8); HttpGet userInfoRequest = new HttpGet(userIdEndpoint + "?" + queryString); HttpResponse userInfoResponse = client.execute(userInfoRequest); Map<String, Object> userInfo = (Map<String, Object>) JSON.parse(EntityUtils.toString(userInfoResponse.getEntity())); System.out.println("User info response"); for (Map.Entry<String, Object> entry : userInfo.entrySet()) { System.out.println(String.format(" %s = %s", entry.getKey(), entry.getValue())); } System.out.println(""); // Use the user info in interesting ways. System.out.println("Username is " + userInfo.get("username")); System.out.println("User's email is " + userInfo.get("email")); Map<String, String> urls = (Map<String, String>)userInfo.get("urls"); System.out.println("REST API url is " + urls.get("rest").replace("{version}", 46 例: 認証 OAuth 2.0 での認証の設定 "38.0")); } このコードからの出力は、次のようになります。 Logging in as [email protected] in environment https://login.salesforce.com POST https://login.salesforce.com/services/oauth2/token... OAuth login response id = https://login.salesforce.com/id/00D30000000ehjIEAQ/00530000003THy8AAG issued_at = 1334961666037 instance_url = https://instance.salesforce.com access_token = 00D30000000ehjI!ARYAQHc.0Mlmz.DCg3HRNF.SmsSn5njPkry2SM6pb6rjCOqfAODaUkv5CGksRSPRb.xb signature = 8M9VWBoaEk+Bs//yD+BfrUR/+5tkNLgXAIwal1PMwsY= User info response user_type = STANDARD status = {created_date=2012-04-08T16:44:58.000+0000, body=Hello} urls = {sobjects=https://instance.salesforce.com/services/data/v{version}/sobjects/, feeds=https://instance.salesforce.com/services/data/v{version}/chatter/feeds, users=https://instance.salesforce.com/services/data/v{version}/chatter/users, query=https://instance.salesforce.com/services/data/v{version}/query/, enterprise=https://instance.salesforce.com/services/Soap/c/{version}/00D30000000ehjI, recent=https://instance.salesforce.com/services/data/v{version}/recent/, feed_items=https://instance.salesforce.com/services/data/v{version}/chatter/feed-items, search=https://instance.salesforce.com/services/data/v{version}/search/, partner=https://instance.salesforce.com/services/Soap/u/{version}/00D30000000ehjI, rest=https://instance.salesforce.com/services/data/v{version}/, groups=https://instance.salesforce.com/services/data/v{version}/chatter/groups, metadata=https://instance.salesforce.com/services/Soap/m/{version}/00D30000000ehjI, profile=https://instance.salesforce.com/00530000003THy8AAG} locale = en_US asserted_user = true id = https://login.salesforce.com/id/00D30000000ehjIEAQ/00530000003THy8AAG nick_name = SampleNickname photos = {picture=https://instance.content.force.com/profilephoto/005/F, thumbnail=https://c.instance.content.force.com/profilephoto/005/T} display_name = Sample User first_name = Admin last_modified_date = 2012-04-19T04:35:29.000+0000 username = [email protected] email = [email protected] organization_id = 00D30000000ehjIEAQ last_name = User utcOffset = -28800000 active = true user_id = 00530000003THy8AAG language = en_US Username is [email protected] User's email is [email protected] REST API url is https://instance.salesforce.com/services/data/v38.0/ 47 ストリーミング API の使用 第8章 トピック: • PushTopic クエリ • イベント通知ルー ル • PushTopic ストリー ミングイベントの 再生 • 登録の際の絞り込 み条件の設定 • 一括登録 • PushTopic の無効化 PushTopic の使用 作成した各 PushTopic レコードは CometD のチャネルに対応します。チャネル名は、 PushTopic 名にプレフィックス「/topic/」を付加した名前です (/topic/MyPushTopic など)。Bayeux クライアントはこのチャネル上でストリーミングされたイベントを受 信できます。チャネル名では、登録するときに大文字と小文字が区別されます。 メモ: Bulk API によって実行された更新では、通知の量がチャネルの許容量を超 える可能性があるため通知は生成されません。 PushTopic レコードが作成されるとすぐに、一致するレコード作成、更新、削除、復 元があるかどうかの評価がシステムで開始されます。一致がある場合は常に新しい 通知が生成されます。サーバは、現在登録されているチャネルに新しい通知がある か毎秒ポーリングします。この時間は全体的なサーバ負荷に応じて変動する場合が あります。 PushTopic は、いつチャネル内で通知を生成するかを定義します。これを指定するに は、次の PushTopic 項目を設定します。 • PushTopic クエリ • イベント • 通知 メモ: 通知を受信するには、PushTopic クエリのオブジェクトおよび PushTopic 自 体の両方への参照アクセス権が必要です。 48 PushTopic の使用 PushTopic クエリ PushTopic クエリ PushTopic クエリは PushTopic チャネルの基礎であり、作成、更新、削除、復元のどのレコードイベントが発生 したら通知を生成するかを定義します。このクエリは、有効な SOQL クエリである必要があります。通知が適 時に送信されるようにするために、次の要件が PushTopic クエリに適用されます。 • クエリの SELECT 句には Id を含める必要があります。例: SELECT Id, Name FROM.... • 1 つのクエリにつきエンティティは 1 つのみです。 • オブジェクトは、指定された API バージョンで有効である必要があります。 PushTopic の SELECT 句に指定した項目によって通知の本文が構成され、PushTopic チャネルでストリーミングされ ます。たとえば、PushTopic クエリが SELECT Id, Name, Status__c FROM InvoiceStatement__c の場 合、ID、Name、および Status__c 項目はそのチャネルで送信されるすべての通知に含まれます。そのチャネ ルに表示される通知メッセージの例を次に示します。 { "channel": "/topic/InvoiceStatementUpdates", "data": { "event": { "type": "updated", "createdDate": "2011-11-03T15:59:06.000+0000" }, "sobject": { "Name": "INV-0001", "Id": "a00D0000008o6y8IAA", "Status__c": "Open" } } } PushTopic クエリを変更した場合、それらの変更はサーバで直ちに有効になります。クライアントは、新しい SOQL クエリに一致した場合にのみイベントを受け取ります。PushTopic の Name を変更しても、現在の登録に は影響はありません。新しい登録では、新しいチャネル名を使用する必要があります。 セキュリティと PushTopic クエリ 登録者に次の権限がある場合、作成、更新、削除、復元されたレコードに関する通知が登録者に送信されま す。 • WHERE 句に指定された項目への項目レベルセキュリティアクセス権 • クエリのオブジェクトへの参照アクセス権 • PushTopic への参照アクセス権 • 共有ルールに基づいた新規または変更されたレコードの表示権限 登録者にクエリの SELECT 句で参照される特定の項目へのアクセス権がない場合、それらの項目は通知には含ま れません。登録者にクエリの WHERE 句で参照されるどの項目へのアクセス権もない場合、登録者は通知を受け 取りません。 49 PushTopic の使用 サポート対象の PushTopic クエリ たとえば、次の[クエリ]値を使用して PushTopic に登録しようとしているユーザがいるとします。 SELECT Id, Name, SSN__c FROM Employee__c WHERE Bonus_Received__c = true AND Bonus_Amount__c > 20000 登録者に Bonus_Received__c と Bonus_Amount__c のいずれの項目へのアクセス権もない場合、登録は失 敗します。登録者に SSN__c へのアクセス権がない場合、通知でこの項目は返されません。 登録者がすでに PushTopic に登録しているが、その後、項目レベルセキュリティが変更されて WHERE 句で参照 されている項目へのアクセス権がなくなった場合、ストリーミング通知は送信されません。 サポート対象の PushTopic クエリ すべてのカスタムオブジェクトが、PushTopic クエリでサポートされます。次に示す標準オブジェクトのサブ セット (Account、Campaign、Case、Contact、Lead、Opportunity、Task) は、PushTopic クエリでサポートされます。ま た、次に示す標準オブジェクト ContractLineItem、Entitlement、LiveChatTranscript、Quote、QuoteLineItem、および ServiceContract は、パイロットプログラムを通じて PushTopic クエリでサポートされます。 重要: 次の方法を使用して作成または更新された Task は、ストリーミング API の Task オブジェクトトピッ クに表示されません。 • リードの取引の開始 • エンティティのマージ • 取引先責任者/リードの一括メール送信 また、標準 SOQL 演算子と大部分の SOQL ステートメントおよび式もサポートされます。一部の SOQL ステート メントはサポートされていません。「サポート対象外の PushTopic クエリ」を参照してください。 サポートされる SOQL ステートメントのサンプルを次に示します。 • カスタムオブジェクト SELECT Id, MyCustomField__c FROM MyCustomObject__c • 標準オブジェクト (カスタム項目が含まれる場合あり) – Account SELECT Id, Name FROM Account WHERE NumberOfEmployees > 1000 – Campaign SELECT Id, Name FROM Campaign WHERE Status = 'Planned' – Case SELECT Id, Subject FROM Case WHERE Status = 'Working' AND IsEscalated = TRUE – Contact SELECT Id, Name, Email FROM Contact; 50 PushTopic の使用 PushTopic クエリの複合項目 – Lead SELECT Id, Company FROM Lead WHERE Industry = 'Computer Services' – Opportunity SELECT Id, Name, Amount FROM Opportunity WHERE CloseDate < 2011-06-14 – Task SELECT Id, Subject, IsClosed, Status FROM Task WHERE isClosed = TRUE 重要: • IsClosed 項目で通知を受信するには、登録者は、クエリで参照される Status 項目を登録す る必要があります。 • WhoCount および WhatCount 項目で通知を受信するには、登録者は、WhoId および WhatId 項目を登録する必要があります。WhoCount または WhatCount 項目のいずれかのみに基づく 登録はサポートされていません。 PushTopic クエリの複合項目 デフォルトでは、PushTopic クエリに含まれる項目によって複合項目 (名前項目や住所項目など) のサポートが異 なります。名前複合項目の場合、名前項目を指定する必要があります。住所項目と地理位置情報項目の場合、 その構成項目を指定する必要があります。 メモ: PushTopic 項目 NotifyForFields が All に設定されている場合、複合項目がサポートされます。 この場合、PushTopic クエリで複合項目または構成項目を明示的に参照する必要はありません。次のセク ションにリストされている特殊な動作は、NotifyForFields が Referenced (デフォルト)、または NotifyForFields が Select または Where に設定されている場合にのみ適用されます。 名前複合項目 名前複合項目の変更を検出するには、SELECT または WHERE 句に名前項目を含めます。firstName や lastName など の構成項目は省略可能ですが、名前項目が必須です。返される通知メッセージには、すべての構成項目値が含 まれます。名前項目を省略すると、構成項目が含まれていても変更を検出できません。 次の表に、サポートされている SELECT ステートメントとサポートされていない SELECT ステートメントを示しま す。次のステートメントには、取引先責任者またはリードの名前複合項目の項目が含まれています。 項目 サポートされているかどうか SELECT Id, Name ○ SELECT Id, Name, firstName, lastName ○ SELECT Id, firstName, lastName × 51 PushTopic の使用 サポート対象外の PushTopic クエリ 住所複合項目 住所複合項目の変更を検出するには、SELECT または WHERE 句に構成項目を含めます。住所項目 (取引先責任者 の MailingAddress や取引先の ShippingAddress など) は省略可能ですが、構成項目は必須です。構成項目を省略する と、住所項目が含まれていても変更を検出できません。 次の表に、サポートされている SELECT ステートメントとサポートされていない SELECT ステートメントを示しま す。次のステートメントには、取引先責任者の MailingAddress 項目が含まれています。 項目 サポートされているかどうか SELECT Id, MailingAddress × SELECT Id, MailingAddress, MailingCity, MailingStreet ○ SELECT Id, MailingCity, MailingStreet ○ 地理位置情報の複合項目 地理位置情報複合項目の変更を検出するには、SELECT または WHERE 句に緯度および経度構成項目を含めます。 地理位置情報項目は省略可能ですが、構成項目は必須です。構成項目を省略すると、地理位置情報項目が含ま れていても変更を検出できません。 次の表に、サポートされている SELECT ステートメントとサポートされていない SELECT ステートメントを示しま す。次のステートメントには、location__c と呼ばれるカスタム地理位置情報項目とその構成項目が含まれ ています。 項目 サポートされているかどうか SELECT Id, location__c × SELECT Id, location__c, location__latitude__s, location__longitude__s ○ SELECT Id, location__latitude__s, location__longitude__s ○ サポート対象外の PushTopic クエリ PushTopic クエリでは次の SOQL ステートメントはサポートされません。 • 選択された項目リストの Id を含まないクエリ • 準結合と反結合 – クエリ例: SELECT Id, Name FROM Account WHERE Id IN (SELECT AccountId FROM Contact WHERE Title = 'CEO') – エラーメッセージ: INVALID_FIELD, semi/anti join sub-selects are not supported 52 PushTopic の使用 サポート対象外の PushTopic クエリ • 集計クエリ (AVG、MAX、MIN、および SUM を使用するクエリ) – クエリ例: SELECT Id, AVG(AnnualRevenue) FROM Account – エラーメッセージ: INVALID_FIELD, Aggregate queries are not supported • COUNT – クエリ例: SELECT Id, Industry, Count(Name) FROM Account – エラーメッセージ: INVALID_FIELD, Aggregate queries are not supported • LIMIT – クエリ例: SELECT Id, Name FROM Contact LIMIT 10 – エラーメッセージ: INVALID_FIELD, 'LIMIT' is not allowed • リレーション (ただし ID は参照可能) – クエリ例: SELECT Id, Contact.Account.Name FROM Contact – エラーメッセージ: INVALID_FIELD, relationships are not supported • [テキストエリア] 項目の値の検索 • ORDER BY – クエリ例: SELECT Id, Name FROM Account ORDER BY Name – エラーメッセージ: INVALID_FIELD, 'ORDER BY' clause is not allowed • GROUP BY – クエリ例: SELECT Id, AccountId FROM Contact GROUP BY AccountId – エラーメッセージ: INVALID_FIELD, 'Aggregate queries are not supported' • WHERE 句の数式項目 (SELECT 句ではサポートされている) • NOT – クエリ例: SELECT Id FROM Account WHERE NOT Name = 'Salesforce.com' – エラーメッセージ: INVALID_FIELD, 'NOT' is not supported これを有効なクエリにするには、SELECT Id FROM Account WHERE Name != 'Salesforce.com' に変 更します。 メモ: NOT IN 句は PushTopic クエリでサポートされます。 • OFFSET – クエリ例: SELECT Id, Name FROM Account WHERE City = 'New York' OFFSET 10 – エラーメッセージ: INVALID_FIELD, 'OFFSET' clause is not allowed • TYPEOF – クエリ例: SELECT TYPEOF Owner WHEN User THEN LastName ELSE Name END FROM Case – エラーメッセージ: INVALID_FIELD, 'TYPEOF' clause is not allowed メモ: TYPEOF は、現在 SOQL 多態性機能の一部の開発者プレビューとして利用可能です。組織での TYPEOF の有効化については、Salesforce にお問い合わせください。 53 PushTopic の使用 イベント通知ルール イベント通知ルール レコードイベントの通知は、PushTopic の設定に基づいて生成されます。ストリーミング API 一致ロジックは、 PushTopic レコードの NotifyForOperationCreate、NotifyForOperationUpdate、 NotifyForOperationDelete、NotifyForOperationUndelete、NotifyForFields 項目を使用して通知 を生成するかどうかを判断します。 削除および復元イベント通知を取得するには、クライアントは cometd/29.0 (またはそれ以降) の ストリーミ ング API エンドポイントを使用して接続する必要があります。 イベント 通知が生成されるイベントは、レコードの作成、更新、削除、復元です。PushTopic の NotifyForOperationCreate、NotifyForOperationUpdate、NotifyForOperationDelete、 NotifyForOperationUndelete 項目を使用して、その PushTopic チャネルで通知が生成されるイベントを指 定できます。項目は次のように設定されます。 項目 説明 NotifyForOperationCreate 作成操作で通知を生成する場合は true、それ以外の 場合は false。 NotifyForOperationDelete 削除操作で通知を生成する場合は true、それ以外の 場合は false。 NotifyForOperationUndelete 復元操作で通知を生成する場合は true、それ以外の 場合は false。 NotifyForOperationUpdate 更新操作で通知を生成する場合は true、それ以外の 場合は false。 API バージョン 28.0 以前では、NotifyForOperations 項目を使用して通知を生成するイベントを指定します が、指定できるのは作成イベントまたは更新イベントのみです。次の NotifyForOperations 値があります。 NotifyForOperations 項 説明 目値 All (デフォルト) レコードが作成または更新された場合にレコードを評価し、必要に応じて通知 を生成します。 Create レコードが作成された場合にのみレコードを評価し、必要に応じて通知を生成 します。 Update レコードが更新された場合にのみレコードを評価し、必要に応じて通知を生成 します。 Extended Extended の値は、作成操作と更新操作のいずれもイベントを生成するように 設定されていないことを示します。この値は、API バージョン 28.0 以前に書き込 54 PushTopic の使用 通知 NotifyForOperations 項 説明 目値 まれたクライアントが、削除通知および復元通知を生成するように設定された Salesforce 組織で動作できるようにするために提供されています。 イベント項目の値と NotifyForFields 値を組み合わせることで、ストリーミング API を使用して通知を生成 するタイミングを柔軟に設定できます。 通知 レコードの作成または更新 (イベント) 後、レコードは PushTopic クエリに対して評価され、必要に応じて通知が 生成されます。通知とは、イベントの結果としてチャネルに送信されるメッセージです。通知は JSON 形式の メッセージです。PushTopic 項目 NotifyForFields では、レコードが PushTopic クエリに対してどのように評 価されるかを指定します。次の NotifyForFields 値があります。 NotifyForFields 項目値 説明 All WHERE 句で参照される項目の値が WHERE 句で指定された値と一致した場合、す べてのレコード項目変更について通知が生成されます。 Referenced (default) SELECT 句と WHERE 句の両方で参照されている項目への変更が評価されます。 SELECT 句で参照されている項目が変更されたか、WHERE 句で参照されている項目 が変更され、かつ WHERE 句で参照されている項目の値が WHERE 句で指定されて いる値と一致するすべてのレコードについて、通知が生成されます。 Select SELECT 句で参照されている項目への変更が評価されます。SELECT 句で参照されて いる項目が変更され、かつ WHERE 句で参照される項目の値が WHERE 句で指定さ れた値と一致するすべてのレコードについて、通知が生成されます。 Where WHERE 句で参照されている項目への変更が評価されます。WHERE 句で参照され ている項目が変更され、かつ WHERE 句で参照される項目の値が WHERE 句で指定 された値と一致するすべてのレコードについて、通知が生成されます。 PushTopic クエリの SELECT 句で指定した項目は、通知メッセージに含まれます。 NotifyForFields を All に設定した場合 PushTopic.NotifyForFields の値を All に設定した場合、レコードのいずれかの項目値が変更されると、 ストリーミング API 一致ロジックがレコードを評価して通知を生成するかどうかを判断します。レコード項目 値が変更されると、PushTopic クエリの SELECT 句または WHERE 句でこれらの項目が参照されているかどうかの評 価が行われます。 イベント 通知が生成される条件 レコードが作成される レコード項目値が WHERE 句に指定された値と一致する 55 PushTopic の使用 通知 イベント 通知が生成される条件 レコードが更新される レコード項目値が WHERE 句に指定された値と一致する 例 PushTopic クエリ 結果 SELECT Id, f1, f2, f3 レコードのいずれかの項目値が変更された場合、通知を生成します。 FROM InvoiceStatement SELECT Id, f1, f2 FROM レコードのいずれかの項目値が変更され、かつ f3 および f4 が WHERE 句の値と一 InvoiceStatement WHERE 致する場合、通知を生成します。 f3 = 'abc' AND f4 LIKE 'xyz' SELECT Id FROM InvoiceStatement ID が SELECT 句の唯一の項目である場合、いずれかの項目値が変更されると通知 が生成されます。 SELECT Id FROM レコードのいずれかの項目値が変更され、かつ f3 および f4 が WHERE 句の値と一 InvoiceStatement WHERE 致する場合、通知を生成します。 f3 = 'abc' AND f4 LIKE 'xyz' SELECT Id FROM レコードのいずれかの項目値が変更され、かつレコード ID が WHERE 句の IN リス InvoiceStatement WHERE トに含まれる場合、通知を生成します。 Id IN ('a07B0000000KWZ7IAO', 'e10R0000000KEU9IAO', 'v32B0000000KWZ7YEP') SELECT Id, f1, f2 FROM レコードのいずれかの項目値が変更され、かつレコード ID が WHERE 句の IN リス InvoiceStatement WHERE トに含まれる場合、通知を生成します。 Id IN ('a07B0000000KWZ7IAO', 'e10R0000000KEU9IAO', 'v32B0000000KWZ7YEP') SELECT Id, f1, f2 FROM レコードのいずれかの項目値が変更され、かつ f3 および f4 が WHERE 句と一致 InvoiceStatement WHERE し、かつレコード ID が WHERE 句の IN リストに含まれる場合、通知を生成しま f3 = 'abc' AND f4 LIKE す。 'xyz' AND Id IN ('a07B0000000KWZ7IAO', 'e10R0000000KEU9IAO', 'v32B0000000KWZ7YEP') 警告: NotifyForFields を All に設定する場合は注意が必要です。この値を使用すると、新しい項目値 が WHERE 句の値と一致すれば、すべてのレコード項目の変更について通知が生成されます。そのため、 生成される通知の数が多くなる可能性があり、1 日あたりのイベント割り当て制限に達することがありま 56 PushTopic の使用 通知 す。さらに、すべてのレコード変更が評価され、多くの通知が生成されると、システムの負荷が高くな ることがあります。 NotifyForFields を Referenced に設定した場合 PushTopic.NotifyForFields の値を Referenced に設定した場合、レコードのいずれかの項目値が変更さ れると、その項目がクエリの SELECT 句または WHERE 句で参照されていれば、ストリーミング API 一致ロジック がレコードを評価して通知を生成するかどうかを判断します。 PushTopic.NotifyForFields 値が Referenced の場合、PushTopic クエリには ID 以外の項目を 1 つ以上含む SELECT 句か、ID 以外の項目を 1 つ以上含む WHERE 句が必要です。 イベント 通知が生成される条件 レコードが作成される レコード項目値が WHERE 句に指定された値と一致する レコードが更新される • PushTopic クエリの SELECT 句で指定されたレコード項目の 1 つ以上が変更され るか、 • PushTopic クエリの WHERE 句で指定されたレコード項目の 1 つ以上が変更さ れ、かつ • WHERE 句に指定された項目のレコード値がすべて、PushTopic クエリの WHERE 句の値に一致する 例 PushTopic クエリ 結果 SELECT Id, f1, f2, f3 FROM InvoiceStatement__c f1、f2、f3 のいずれかが変更された場合、通知を生成します。 SELECT Id, f1, f2 FROM InvoiceStatement__c WHERE f3 = 'abc' AND f4 LIKE 'xyz' f1、f2、f3、f4 のいずれかが変更され、かつ f3 および f4 が WHERE 句 の値と一致する場合、通知を生成します。 SELECT Id FROM InvoiceStatement__c WHERE f3 = 'abc' AND f4 LIKE 'xyz' f3 および f4 が変更され、かつ f3 および f4 が WHERE 句の値と一致す る場合、通知を生成します。 SELECT Id, f1, f2 FROM InvoiceStatement__c WHERE Id IN ('a07B0000000KWZ7IAO', 'e10R0000000KEU9IAO', 'v32B0000000KWZ7YEP') f1 または f2 が変更され、かつレコード ID が WHERE 句の IN リストに 含まれる場合、通知を生成します。 SELECT Id, f1, f2 FROM InvoiceStatement__c WHERE f3 = 'abc' AND f4 LIKE 'xyz' AND Id IN ('a07B0000000KWZ7IAO', f1、f2、f3、f4 のいずれかが変更され、かつ f3 および f4 が WHERE 句 の値と一致し、かつ ID が WHERE 句の IN リストに含まれる場合、通 知を生成します。 57 PushTopic の使用 通知 PushTopic クエリ 結果 'e10R0000000KEU9IAO', 'v32B0000000KWZ7YEP') NotifyForFields を Select に設定した場合 PushTopic.NotifyForFields の値を Select に設定した場合、レコードのいずれかの項目値が変更される と、その項目がクエリの SELECT 句で参照されていれば、ストリーミング API 一致ロジックがレコードを評価し て通知を生成するかどうかを判断します。 PushTopic.NotifyForFields 値が Select の場合、PushTopic クエリには ID 以外の項目を 1 つ以上含む SELECT 句が必要です。 イベント 通知が生成される条件 レコードが作成される レコード項目値が WHERE 句に指定された値と一致する レコードが更新される • PushTopic クエリの SELECT 句で指定されたレコード項目の 1 つ以上が変更さ れ、かつ • WHERE 句に指定された項目のレコード値がすべて、PushTopic クエリの WHERE 句の値に一致する 例 PushTopic クエリ 結果 SELECT Id, f1, f2, f3 FROM InvoiceStatement__c f1、f2、f3 のいずれかが変更された場合、通知を生成します。 SELECT Id, f1, f2 FROM InvoiceStatement__c WHERE f3 = 'abc' AND f4 LIKE 'xyz' f1 または f2 が変更され、かつ f3 および f4 が WHERE 句の値と一致す る場合、通知を生成します。 SELECT Id, f1, f2 FROM InvoiceStatement__c WHERE Id IN ('a07B0000000KWZ7IAO', 'e10R0000000KEU9IAO', 'v32B0000000KWZ7YEP') f1 または f2 が変更され、かつ ID が WHERE 句の IN リストに含まれる 場合、通知を生成します。 SELECT Id, f1, f2 FROM InvoiceStatement__c WHERE f3 = 'abc' AND f4 LIKE 'xyz' AND Id IN ('a07B0000000KWZ7IAO', 'e10R0000000KEU9IAO', 'v32B0000000KWZ7YEP') f1 または f2 が変更され、かつ f3 および f4 が WHERE 句の値と一致 し、かつ ID が WHERE 句の IN リストに含まれる場合、通知を生成し ます。 58 PushTopic の使用 通知 NotifyForFields を Where に設定した場合 PushTopic.NotifyForFields の値を Where に設定した場合、レコードのいずれかの項目値が変更される と、その項目がクエリの WHERE 句で参照されていれば、ストリーミング API 一致ロジックがレコードを評価し て通知を生成するかどうかを判断します。 PushTopic.NotifyForFields 値が Where の場合、PushTopic クエリには Id 以外の項目を 1 つ以上含む WHERE 句が必要です。 イベント 通知が生成される条件 レコードが作成される レコード項目値が WHERE 句に指定された値と一致する レコードが更新される • PushTopic クエリの WHERE 句で指定されたレコード項目の 1 つ以上が変更さ れ、かつ • WHERE 句に指定された項目のレコード値がすべて、PushTopic クエリの WHERE 句の値に一致する 例 PushTopic クエリ 結果 SELECT Id, f1, f2 FROM InvoiceStatement__c WHERE f3 = 'abc' AND f4 LIKE 'xyz' f3 または f4 が変更され、その値が WHERE 句の値と一致する場合、 通知を生成します。 SELECT Id FROM InvoiceStatement__c WHERE f3 = 'abc' AND f4 LIKE 'xyz' f3 または f4 が変更され、その値が WHERE 句の値と一致する場合、 通知を生成します。 SELECT Id, f1, f2 FROM InvoiceStatement__c WHERE f3 = 'abc' AND f4 LIKE 'xyz' AND Id IN ('a07B0000000KWZ7IAO', 'e10R0000000KEU9IAO', 'v32B0000000KWZ7YEP') f3 または f4 が変更され、かつ f3 および f4 が WHERE 句の値と一致 し、かつレコード ID が WHERE 句の IN リストに含まれる場合、通知 を生成します。 通知シナリオ シナリオ例と、通知を生成するために必要な PushTopic レコードの項目値の一覧を次に示します。 シナリオ 設定 すべてのレコード更新についてすべての通知を • MyPushTopic.Query = SELECT Id, Name, 受け取る。 Description__c FROM InvoiceStatement • MyPushTopic.NotifyForFields = All 59 PushTopic の使用 シナリオ PushTopic ストリーミングイベントの再生 設定 Name 項目または Amount 項目が変更された場合 • MyPushTopic.Query = SELECT Id, Name, Amount__c にのみ、すべてのレコード変更について通知を FROM InvoiceStatement 受け取る。たとえば、リストビューを管理して • MyPushTopic.NotifyForFields = Referenced いる場合などです。 特定のレコードに対するすべてのレコード変更 • MyPushTopic.Query = SELECT Id, Name, Amount__c について通知を受け取る。 FROM InvoiceStatement WHERE Id='a07B0000000KWZ7IAO' • MyPushTopic.NotifyForFields = All 特定のレコードの Name 項目または Amount 項目 • MyPushTopic.Query = SELECT Id, Name, Amount__c が変更された場合にのみ、通知を受け取る。た FROM InvoiceStatement WHERE とえば、ユーザが詳細ページを表示していて、 Id='a07B0000000KWZ7IAO' これら 2 つの項目のみが表示されている場合な • MyPushTopic.NotifyForFields = Referenced どです。 特定の州のベンダーの請求書明細レコードの変 • MyPushTopic.Query = SELECT Id, Name, Amount__c 更のすべてについて通知を受け取る。 FROM InvoiceStatement WHERE BillingState__c = 'NY' • MyPushTopic.NotifyForFields = All 請求額が 1,000 ドル以上の場合、請求書明細レ • MyPushTopic.Query = SELECT Id, Name FROM コードの変更のすべてについて通知を受け取 InvoiceStatement WHERE Amount > 999 る。 • MyPushTopic.NotifyForFields = Referenced PushTopic ストリーミングイベントの再生 Salesforce では、PushTopic ベースのイベントが 24 時間保存され、保存されたイベントと新規イベントを取得で きます。登録者は、再生オプションを使用して受信するイベントを選択できます。 デュラブルイベントについての詳細は、「メッセージの永続性」を参照してください。 コードサンプル • GitHub: デュラブル PushTopic ストリーミングデモ • GitHub: ストリーミング再生クライアント拡張 登録の際の絞り込み条件の設定 チャネルに登録するときに、レコード項目を指定して絞り込み、PushTopic イベント通知の数を減らします。 次のように、登録 URI に追加する式で検索条件を指定します。 60 PushTopic の使用 一括登録 /topic/ChannelName?<expression> ChannelName はチャネルで、<expression> は 1 つ以上の条件を含む式です。& 演算子を使用して条件を結 合します。& 演算子のみがサポートされています。<expression> に次の構文を使用します。 ?fieldA=valueA&fieldB=valueB&... 検索条件で使用される各項目を PushTopic クエリに含めます。& 演算子は論理 OR 演算子のように機能するため、 いずれかの条件が true になるとレコードイベントが一致します。 メモ: 検索条件に ID を使用する場合は、18 文字の ID 形式を使用します。15 文字の ID はサポートされてい ません。 例: 次の登録では、業種が「Energy」(エネルギー) または市区郡(納入先) が「San Francisco」(サンフランシス コ) となっているレコードのイベント通知が返されます。 /topic/myChannel?Industry='Energy'&ShippingCity='San Francisco' この登録の PushTopic クエリには、Industry 項目と ShippingCity 項目が含まれています。 一括登録 複数のトピックに同時に登録できます。 そのためには、1 つの登録メッセージではなく登録メッセージの JSON 配列を送信します。たとえば、次のコー ドは 3 つのトピックに登録します。 [ { "channel": "/meta/subscribe", "clientId": "Un1q31d3nt1f13r", "subscription": "/topic/foo" }, { "channel": "/meta/subscribe", "clientId": "Un1q31d3nt1f13r", "subscription": "/topic/bar" }, { "channel": "/meta/subscribe", "clientId": "Un1q31d3nt1f13r", "subscription": "/topic/baz" } ] 詳細については、「Bayeux の仕様」を参照してください。 PushTopic の無効化 PushTopic を削除するのではなく、一時的に無効化するには、isActive 項目を false に設定します。 61 PushTopic の使用 PushTopic の無効化 • ID を指定して PushTopic を無効化するには、次の Apex コードを実行します。 PushTopic pt = new PushTopic(Id='0IFD0000000008jOAA', IsActive = false); update(pt); 62 第9章 トピック: • クライアントとタ イムアウト • ストリーミング API のクライアントと Cookie • サポートされるブ ラウザ • HTTPS の推奨 • ストリーミング API アプリケーション のデバッグ • イベント使用状況 の監視 • 通知メッセージの 順序 ストリーミング API の考慮事項 ストリーミング APIを使用すると、Salesforceデータについてほぼリアルタイムの更新 通知を作成できます。この章では、ストリーミング API の実装に際して留意が必要 な、クライアントおよびトラブルシューティングに関する考慮事項を取り上げます。 63 ストリーミング API の考慮事項 クライアントとタイムアウト クライアントとタイムアウト ストリーミング API では、Bayeux プロトコルでサポートされている 2 つのタイムアウトが適用されます。 ソケットタイムアウト: 110 秒 クライアントは、接続の待機中にイベント (JSON 形式の HTTP 応答) を受信します。イベントが生成されずに クライアントが引き続き待機している場合、接続は110 秒後にタイムアウトし、サーバは接続を閉じます。 クライアントは、2 分以内に再接続して接続タイムアウトを回避する必要があります。 再接続タイムアウト: 40 秒 イベントを受信したら、クライアントは次のイベントのセットを受け取るために再接続する必要がありま す。40 秒以内に再接続しないと、サーバが登録を期限切れにし、接続が終了します。この状態が発生する と、クライアントはハンドシェイク、登録、および接続を最初から再度やり直す必要があります。 各ストリーミング API クライアントは、インスタンスにログインし、セッションを維持します。クライアント がハンドシェイク、接続、または登録を行うと、セッションタイムアウトが再び最初から適用されます。クラ イアントが応答 (イベント、登録結果など) を受信してから 40 秒以内にサーバに再接続しない場合、クライア ントセッションはタイムアウトします。 これらのタイムアウトは、ストリーミング API クライアントセッションに適用され、Salesforce 認証セッション には適用されません。クライアントセッションがタイムアウトすると、認証セッションは組織固有のタイムア ウトポリシーが適用されるまで有効なままになります。 ストリーミング API のクライアントと Cookie ストリーミング API を使用するために作成したクライアントは、サーバとの間で使用される標準 Cookie プロト コルに従う必要があります。クライアントは、https://instance_name.salesforce.com/cometd など、 ドメインおよび URI パスに対応した適切な Cookie を受け取って送信する必要があります。 クライアントに対する ストリーミング API 要件は次のとおりです。 • POST のコンテンツが JSON の場合、cometd へのすべてのコールに "Content-Type: application/json" ヘッダーが必要です。 • Salesforce セッション ID または OAuth トークンを含むヘッダーが必要です。たとえば、Authorization: Bearer sessionId と指定します。 • クライアントは、ドメインおよび URI パスに対応した適切な Cookie をすべて受け取って返送する必要があり ます。クライアントは、サーバとの間で使用される標準 Cookie プロトコルに従う必要があります。 • 登録応答とその他の応答には、次の項目が含まれている場合があります。これらの項目は、CometD 仕様に は含まれません。 – EventType に created または updated のいずれかが含まれる。 – CreatedDate にイベントの作成日が含まれる。 サポートされるブラウザ ストリーミング API では、次のブラウザがサポートされます。 64 ストリーミング API の考慮事項 HTTPS の推奨 • Internet Explorer 8 以上 • Firefox 4 以上 最新のセキュリティ更新と修正が適用された最新バージョンのブラウザを使用することをお勧めします。Internet Explorer 6 または 7 を使用する必要がある地域では、jQuery 1.5.1 および CometD 2.2.0 を使用する Streaming API でこれ らのブラウザが動作することが Salesforce で確認済みです。 HTTPS の推奨 ストリーミング APIはシステム管理者が組織について定義した設定に従います。デフォルトでは、これは HTTPS です。データのセキュリティを保護するために、HTTPS を使用することをお勧めします。 ストリーミング API アプリケーションのデバッグ ストリーミング APIアプリケーションをデバッグするには、すべての要求と応答を確認できる必要があります。 ストリーミング API アプリケーションはステートフルであるため、アプリケーションのデバッグにはプロキシ ツールを使用する必要があります。Burp Proxy、Fiddler、Firebug など、すべての要求と結果の内容をレポートで きるツールを使用してください。 最も一般的なエラーとして次のようなものがあります。 • ブラウザと JavaScript の問題 • 正しくない順序で送信された要求 • Bayeux プロトコルに従っていない不正な形式の要求 • 認証の問題 • 長命 (long-lived) 接続によるネットワークまたはファイアウォールの問題 これらのツールを使用すると、要求、ヘッダー、post の本文、結果を参照できます。Salesforce にお問い合わせ いただくときは、トラブルシューティングに役立つようにこれらの要素をコピーして保存しておいてくださ い。 デバッグプロセスの最初のステップでは、「ワークベンチを使用したクイックスタート」、「例: 対話型 Visualforce ページ」、「例: Visualforce ページ」、または「例: Java クライアント」の手順に従って、提供されたサンプルを 実装できることを確認します。次のステップでは、デバッグツールを使用して、症状と問題の原因を切り分け ます。 402 エラー 場合によっては、次のような「402::Uknown client」が含まれたエラー通知を受け取る場合があります。 Thu Mar 29 06:08:08 PDT 2012 [CHANNEL:META_CONNECT]: {"id":"78","error":"402::Unknown client","successful":false,"advice":{"interval":500,"reconnect":"handshake"} これは、クライアント接続のタイムアウトなど、さまざまな状況で発生します。このエラーが発生した場合、 サーバとハンドシェイクをして再接続する必要があります。クライアントのタイムアウトとストリーミング API 制限についての詳細は、 「クライアントとタイムアウト」と「ストリーミング API の制限」を参照してください。 65 ストリーミング API の考慮事項 イベント使用状況の監視 イベント使用状況の監視 24 時間の間に生成できるイベントの数は、組織の種別に応じて異なります。詳細は、「ストリーミング API の 制限」を参照してください。[組織情報] ページでストリーミング API イベントの使用状況を監視できます。こ のページには以下の手順でアクセスします。 • [設定] から、[クイック検索] ボックスに「組織情報」と入力し、[組織情報] を選択します。 [組織情報] ページを更新すると、ストリーミング API イベント値がわずかに変動する場合があります。これら のわずかな変動に関係なく、設定した制限は正確に評価されます。 通知メッセージの順序 組織でのデータの変更は、順番に行われます。ただし、ストリーミング API でイベント通知メッセージを受信 する順序は保証されません。クライアント側では、createdDate を使用して、チャネルに返される通知メッ セージの順序を指定できます。createdDate の値は、イベントの発生時期を示す UTC 日付/時間の値です。 次のコードでは、複数のメッセージが生成されます。1 つはレコードの作成時に、もう 1つはレコードの更新 時に生成されます。 { "channel": "/topic/InvoiceStatementUpdates", "clientId": "1g177wgjj14omtdo3rcl0hjhm4w", "data": { "event": { "type": "updated", "createdDate": "2013-05-10T18:16:19.000+0000" }, "sobject": { "Name": "INV-0002", "test_ds__Status__c": "Negotiating", "test_ds__Description__c": "Update to invoice statement #2", "Id": "a00D0000008pvxcIAA" } } } { "channel": "/topic/InvoiceStatementUpdates", "clientId": "1g177wgjj14omtdo3rcl0hjhm4w", "data": { "event": { "type": "created", "createdDate": "2013-05-10T18:15:11.000+0000" }, "sobject": { "Name": "INV-0003", "test_ds__Status__c": "Open", "test_ds__Description__c": "New invoice statement #1", "Id": "a00D0000008pvzdIAA" } 66 ストリーミング API の考慮事項 通知メッセージの順序 } } 67 汎用ストリーミング 第 10 章 トピック: • デュラブル汎用ス トリーミングを使 用した汎用スト リーミングイベン トの再生 汎用ストリーミングの概要 汎用ストリーミングでは、ストリーミング APIを使用して、Salesforceデータの変更に 関連付けられていない一般イベントの通知を送信します。 指定するカスタムイベントに基づいて通知を送受信する場合は、汎用ストリーミン グを使用します。汎用ストリーミングは、次に挙げるような、カスタム通知を送信 する必要があるすべての状況で使用できます。 • 特定のチームまたは組織全体に通知を送信する • Salesforce の外部で発生するイベントの通知を送信する 汎用ストリーミングを使用するには、以下が必要です。 • チャネルを定義する StreamingChannel (大文字と小文字を区別する名前) • チャネルに登録された 1 つ以上のクライアント • チャネルの転送イベントを監視および呼び出すことができる Streaming Channel Push REST API リソース 68 汎用ストリーミングの概要 デュラブル汎用ストリーミングを使用した汎用ストリー ミングイベントの再生 デュラブル汎用ストリーミングを使用した汎用ストリーミングイ ベントの再生 クライアントはチャネルに登録した後に、Salesforceセッションが有効である限り汎用ストリーミングイベント を受信できます。クライアントがチャネルに登録する前、または登録済みクライアントがSalesforceセッション から切断された後に送信されたイベントは欠落します。ただし、クライアントはデュラブル汎用ストリーミン グを使用して、24 時間の保持期間内の欠落イベントを取得できます。 デュラブルイベントについての詳細は、「メッセージの永続性」を参照してください。 コードサンプル 汎用ストリーミングイベントの再生方法のコードサンプルは、「例: Visualforce ページを使用した PushTopic スト リーミングイベントと汎用ストリーミングイベントの再生」を参照してください。 69 第 11 章 クイックスタート このクイックスタートでは、ストリーミング API で汎用ストリーミングの使用を開始する方法を説明します。 イベントが REST 経由で転送されたときにストリーミング API を使用して通知を受け取るプロセスをステップご とに説明します。 このセクションの内容: ストリーミングチャネルを作成する Salesforce UI を使用して、新しい StreamingChannel オブジェクトを作成します。 Java クライアントを作成する Bayeux および CometD を使用してチャネルに登録する Java クライアントを作成します。 REST を使用してイベントを生成する Streaming Channel Push REST API リソースを使用して、チャネル登録者に対してイベント通知を生成します。 ストリーミングチャネルを作成する Salesforce UI を使用して、新しい StreamingChannel オブジェクトを作成します。 組織で適切な ストリーミング API 権限を有効にする必要があります。 1. Developer Edition 組織にログインします。[すべてのタブ] (+) で、[ストリーミングチャネル] を選択します。 2. [ストリーミングチャネル] タブで [新規] を選択して、新しいストリーミングチャネルを作成します。 3. [ストリーミングチャネル名] に「/u/notifications/ExampleUserChannel」と入力し、説明 (省略可能) を入力します。新しい [ストリーミングチャネル] ページは、次のようになります。 70 クイックスタート Java クライアントを作成する 4. [保存] を選択します。これで、クライアントが通知用に登録できる新しいストリーミングチャネルが作成 されました。 StreamingChannel は通常の作成可能な Salesforce オブジェクトであるため、Apex や、SOAP API または REST API など のデータ API を使用して、プログラムで作成することもできます。 さらに、イベント通知を送受信できるユーザを制限する必要がある場合、StreamingChannel でのユーザ共有を使 用して制御できます。「公開/参照のみ」または「参照・更新」アクセス権によって共有されるチャネルでは、 そのチャネルに登録しているクライアントのうち、共有ユーザまたはグループのセットに関連付けられたユー ザセッションも使用するクライアントに対してのみイベント送信が行われます。共有チャネルに対する「参 照・更新」アクセス権を持つユーザのみが、そのチャネルでのイベント生成または実際の StreamingChannel レ コードの変更を行うことができます。StreamingChannel のユーザ共有を変更するには、[設定] から [クイック検 索] ボックスに「共有設定」と入力し、[共有設定] を選択して StreamingChannel 共有ルールを作成または変更し ます。 汎用ストリーミングでは、クライアントが最初にチャネルに登録するときに StreamingChannel が作成される、 動的ストリーミングチャネルもサポートされます。組織内の動的ストリーミングチャネルを有効化するには、 [設定] から [クイック検索] ボックスに「ユーザインターフェース」と入力し、[ユーザインターフェース] を選 択して [動的ストリーミングチャネル作成を有効化] を有効化します。 Java クライアントを作成する Bayeux および CometD を使用してチャネルに登録する Java クライアントを作成します。 1. 必要に応じて、CometD および Jetty .jar ファイルをダウンロードしてインストールします。 2. 新しい Java プロジェクトで、次のコードを StreamingClientExample.java という名前の Java ソースファ イルに追加します。このコードは、作成したストリーミングチャネルに登録し、通知をリスンします。Java 開発環境に応じて、このファイルとクラスの名前を Main に変更しなければならない場合があります。 package demo; import import import import import import import org.cometd.bayeux.Channel; org.cometd.bayeux.Message; org.cometd.bayeux.client.ClientSessionChannel; org.cometd.bayeux.client.ClientSessionChannel.MessageListener; org.cometd.client.BayeuxClient; org.cometd.client.transport.ClientTransport; org.cometd.client.transport.LongPollingTransport; import org.eclipse.jetty.client.ContentExchange; import org.eclipse.jetty.client.HttpClient; import import import import java.net.MalformedURLException; java.net.URL; java.util.HashMap; java.util.Map; /** * This example demonstrates how a streaming client works * against the Salesforce Streaming API with generic notifications. **/ 71 クイックスタート Java クライアントを作成する public class StreamingClientExample { // // // // This URL is used only for logging in. The LoginResult returns a serverUrl which is then used for constructing the streaming URL. The serverUrl points to the endpoint where your organization is hosted. static final String LOGIN_ENDPOINT = "https://login.salesforce.com"; private static final String USER_NAME = "[email protected]"; private static final String PASSWORD = "change_this_to_your_testpassword"; // NOTE: Putting passwords in code is not a good practice and not recommended. // The channel to subscribe to. // Be sure to create the StreamingChannel before running this sample. private static final String CHANNEL = "/u/notifications/ExampleUserChannel"; private static final String STREAMING_ENDPOINT_URI = "/cometd/38.0"; // The long poll duration. private static final int CONNECTION_TIMEOUT = 20 * 1000; // milliseconds private static final int READ_TIMEOUT = 120 * 1000; // milliseconds public static void main(String[] args) throws Exception { System.out.println("Running streaming client example...."); final BayeuxClient client = makeClient(); client.getChannel(Channel.META_HANDSHAKE).addListener (new ClientSessionChannel.MessageListener() { public void onMessage(ClientSessionChannel channel, Message message) { System.out.println("[CHANNEL:META_HANDSHAKE]: " + message); boolean success = message.isSuccessful(); if (!success) { String error = (String) message.get("error"); if (error != null) { System.out.println("Error during HANDSHAKE: " + error); System.out.println("Exiting..."); System.exit(1); } Exception exception = (Exception) message.get("exception"); if (exception != null) { System.out.println("Exception during HANDSHAKE: "); exception.printStackTrace(); System.out.println("Exiting..."); System.exit(1); } } } 72 クイックスタート Java クライアントを作成する }); client.getChannel(Channel.META_CONNECT).addListener( new ClientSessionChannel.MessageListener() { public void onMessage(ClientSessionChannel channel, Message message) { System.out.println("[CHANNEL:META_CONNECT]: " + message); boolean success = message.isSuccessful(); if (!success) { String error = (String) message.get("error"); if (error != null) { System.out.println("Error during CONNECT: " + error); System.out.println("Exiting..."); System.exit(1); } } } }); client.getChannel(Channel.META_SUBSCRIBE).addListener( new ClientSessionChannel.MessageListener() { public void onMessage(ClientSessionChannel channel, Message message) { System.out.println("[CHANNEL:META_SUBSCRIBE]: " + message); boolean success = message.isSuccessful(); if (!success) { String error = (String) message.get("error"); if (error != null) { System.out.println("Error during SUBSCRIBE: " + error); System.out.println("Exiting..."); System.exit(1); } } } }); client.handshake(); System.out.println("Waiting for handshake"); boolean handshaken = client.waitFor(10 * 1000, BayeuxClient.State.CONNECTED); if (!handshaken) { System.out.println("Failed to handshake: " + client); System.exit(1); } System.out.println("Subscribing for channel: " + CHANNEL); 73 クイックスタート Java クライアントを作成する client.getChannel(CHANNEL).subscribe(new MessageListener() { @Override public void onMessage(ClientSessionChannel channel, Message message) { System.out.println("Received Message: " + message); } }); System.out.println("Waiting for streamed data from your organization ..."); while (true) { // This infinite loop is for demo only, // to receive streamed events on the // specified topic from your organization. } } private static BayeuxClient makeClient() throws Exception { HttpClient httpClient = new HttpClient(); httpClient.setConnectTimeout(CONNECTION_TIMEOUT); httpClient.setTimeout(READ_TIMEOUT); httpClient.start(); String[] pair = SoapLoginUtil.login(httpClient, USER_NAME, PASSWORD); if (pair == null) { System.exit(1); } assert pair.length == 2; final String sessionid = pair[0]; String endpoint = pair[1]; System.out.println("Login successful!\nServer URL: " + endpoint + "\nSession ID=" + sessionid); Map<String, Object> options = new HashMap<String, Object>(); options.put(ClientTransport.TIMEOUT_OPTION, READ_TIMEOUT); LongPollingTransport transport = new LongPollingTransport( options, httpClient) { @Override protected void customize(ContentExchange exchange) { super.customize(exchange); exchange.addRequestHeader("Authorization", "OAuth " + sessionid); } }; BayeuxClient client = new BayeuxClient(salesforceStreamingEndpoint( endpoint), transport); return client; } private static String salesforceStreamingEndpoint(String endpoint) 74 クイックスタート Java クライアントを作成する throws MalformedURLException { return new URL(endpoint + STREAMING_ENDPOINT_URI).toExternalForm(); } } 3. StreamingClientExample.java を編集して、次の値を変更します。 ファイル名 静的リソース名 USER_NAME ログインユーザのユーザ名 PASSWORD USER_NAME (ログインユーザ) のパスワード CHANNEL /u/notifications/ExampleUserChannel LOGIN_ENDPOINT https://test.salesforce.com (Sandbox を使用する場合のみ。本番組織の 場合は、LOGIN_ENDPOINT の変更は必要ありません)。 4. 次のコードを SoapLoginUtil.java という名前の Java ソースファイルに追加します。このコードは、ユー ザ名とパスワードをサーバに送信し、セッション ID を受信します。 重要: 他のユーザのユーザ名とパスワードは処理しないでください。また、本番環境で使用する場合 は、ログインを OAuth に委任してください。 package demo; import import import import import java.io.ByteArrayInputStream; java.io.IOException; java.io.UnsupportedEncodingException; java.net.MalformedURLException; java.net.URL; import import import import import org.eclipse.jetty.client.ContentExchange; org.eclipse.jetty.client.HttpClient; org.xml.sax.Attributes; org.xml.sax.SAXException; org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; public final class SoapLoginUtil { // The enterprise SOAP API endpoint used for the login call in this example. private static final String SERVICES_SOAP_PARTNER_ENDPOINT = "/services/Soap/u/22.0/"; private static final String ENV_START = "<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' 75 クイックスタート Java クライアントを作成する " + "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " + "xmlns:urn='urn:partner.soap.sforce.com'><soapenv:Body>"; private static final String ENV_END = "</soapenv:Body></soapenv:Envelope>"; private static byte[] soapXmlForLogin(String username, String password) throws UnsupportedEncodingException { return (ENV_START + " <urn:login>" + " <urn:username>" + username + "</urn:username>" + " <urn:password>" + password + "</urn:password>" + " </urn:login>" + ENV_END).getBytes("UTF-8"); } public static String[] login(HttpClient client, String username, String password) throws IOException, InterruptedException, SAXException, ParserConfigurationException { ContentExchange exchange = new ContentExchange(); exchange.setMethod("POST"); exchange.setURL(getSoapURL()); exchange.setRequestContentSource(new ByteArrayInputStream(soapXmlForLogin( username, password))); exchange.setRequestHeader("Content-Type", "text/xml"); exchange.setRequestHeader("SOAPAction", "''"); exchange.setRequestHeader("PrettyPrint", "Yes"); client.send(exchange); exchange.waitForDone(); String response = exchange.getResponseContent(); SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); SAXParser saxParser = spf.newSAXParser(); LoginResponseParser parser = new LoginResponseParser(); saxParser.parse(new ByteArrayInputStream( response.getBytes("UTF-8")), parser); if (parser.sessionId == null || parser.serverUrl == null) { System.out.println("Login Failed!\n" + response); return null; } URL soapEndpoint = new URL(parser.serverUrl); StringBuilder endpoint = new StringBuilder() .append(soapEndpoint.getProtocol()) .append("://") .append(soapEndpoint.getHost()); if (soapEndpoint.getPort() > 0) endpoint.append(":") .append(soapEndpoint.getPort()); 76 クイックスタート Java クライアントを作成する return new String[] {parser.sessionId, endpoint.toString()}; } private static String getSoapURL() throws MalformedURLException { return new URL(StreamingClientExample.LOGIN_ENDPOINT + getSoapUri()).toExternalForm(); } private static String getSoapUri() { return SERVICES_SOAP_PARTNER_ENDPOINT; } private static class LoginResponseParser extends DefaultHandler { private boolean inSessionId; private String sessionId; private boolean inServerUrl; private String serverUrl; @Override public void characters(char[] ch, int start, int length) { if (inSessionId) sessionId = new String(ch, start, length); if (inServerUrl) serverUrl = new String(ch, start, length); } @Override public void endElement(String uri, String localName, String qName) { if (localName != null) { if (localName.equals("sessionId")) { inSessionId = false; } if (localName.equals("serverUrl")) { inServerUrl = false; } } } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) { if (localName != null) { if (localName.equals("sessionId")) { inSessionId = true; } if (localName.equals("serverUrl")) { inServerUrl = true; } } } } } 77 クイックスタート Java クライアントを作成する 5. REST リソースを使用してこのクライアントアプリケーションを実行し、通知を生成すると、出力は次のよ うになります。 Running streaming client example.... Login successful! Server URL: https://www.salesforce.com Session ID=00DD0000000FSp9!AQIAQIVjGYijFhiAROTc455T6kEVeJGXuW5VCnp LANCMawS7.p5fXbjYlqCgx7They_zFjmP5n9HxvfUA6xGSGtC1Nb6P4S. Waiting for handshake [CHANNEL:META_HANDSHAKE]: { "id":"1", "minimumVersion":"1.0", "supportedConnectionTypes":["long-polling"], "successful":true, "channel":"/meta/handshake", "clientId":"31t0cjzfbgnfqn1rggumba0k98u", "version":"1.0" } [CHANNEL:META_CONNECT]: { "id":"2", "successful":true, "advice":{"interval":0,"reconnect":"retry","timeout":110000}, "channel":"/meta/connect"} Subscribing for channel: /u/notifications/ExampleUserChannel Waiting for streamed data from your organization ... [CHANNEL:META_SUBSCRIBE]: { "id":"4", "subscription":"/u/notifications/ExampleUserChannel", "successful":true, "channel":"/meta/subscribe" } [CHANNEL:META_CONNECT]: { "id":"3", "successful":true, "channel":"/meta/connect" } Received Message: { "data": { "event": { "createdDate":"2013-07-30T23:15:59.000+0000" }, "payload":"Broadcast message to all subscribers" }, 78 クイックスタート REST を使用してイベントを生成する "channel":"/u/notifications/ExampleUserChannel", "clientId":"8173z2cplh8q6m1rmud93zygnf8" } [CHANNEL:META_CONNECT]: { "id":"5", "successful":true, "channel":"/meta/connect" } REST を使用してイベントを生成する Streaming Channel Push REST API リソースを使用して、チャネル登録者に対してイベント通知を生成します。 ワークベンチを使用して、REST API にアクセスし、通知を送信します。ワークベンチは、無料のオープンソー スのコミュニティサポートツールです (ワークベンチのヘルプページを参照)。Salesforceは、デモ目的でのみワー クベンチのホスト型インスタンスを提供しています。このワークベンチのホスト型インスタンスを本番データ ベースのデータへのアクセスに使用することはお勧めしません。ワークベンチを本番データベースに使用する 場合は、各自で所有するリソースを使用してワークベンチをダウンロード、ホスト、および設定してくださ い。ワークベンチは、https://github.com/ryanbrainard/forceworkbench/releases からダウンロードできます。 1. ブラウザで、https://developer.salesforce.com/page/Workbench に移動します。 2. [Environment (環境)] で [Production (本番)] を選択します。 3. [API Version (API バージョン)] で 38.0 を選択します。 4. サービスの利用規約に同意し、[Login with Salesforce (Salesforce でログイン)] をクリックします。 5. データベースへの接続が確立されると、[Select (選択)] ページが表示されます。 6. [queries (クエリ)] > [SOQL Query (SOQL クエリ)] をクリックし、SELECT Name, ID FROM StreamingChannel の SOQL クエリを行って、StreamingChannel ID を検索します。/u/notifications/ExampleUserChannel の StreamingChannel ID をコピーします。 7. [utilities (ユーティリティ)] > [REST Explorer] をクリックします。 8. URL 項目に「/services/data/v29.0/sobjects/StreamingChannel/[ストリーミングチャネル ID]/push」と入力します。[ストリーミングチャネル ID] は、ステップ 6 で検索した StreamingChannel の ID です。 9. [POST] を選択して、HTTP メソッドを設定します。[Request Body (リクエストボディ)] に、以下の「POST REST リクエストボディの例」で示す JSON リクエストボディを入力します。 10. Java 登録者クライアントの実行中に[Execute (実行)]をクリックします。これで、チャネルのすべての登録者 にイベントが送信されます。Java クライアントで、ペイロードテキストを含む通知が受信されます。REST メソッド応答は、イベントが送信された登録者数を示します (この場合は、すべての登録者にイベントを送 信するよう設定されているため、–1 になります)。 汎用ストリーミングを使用して、通知が登録者に正常に送信されました。すべての登録者に送信するだけでな く、登録ユーザのリストを指定して特定の登録者に通知を送信することができます。また、Streaming Channel Push REST API リソースの GET メソッドを使用して、チャネルのアクティブな登録者のリストを取得することも できます。 79 クイックスタート REST を使用してイベントを生成する 例: POST REST リクエストボディの例 { "pushEvents": [ { "payload": "Broadcast message to all subscribers", "userIds": [] } ] } 80 リファレンス 第 12 章 PushTopic 組織のレコードへの変更をリスナーに通知するための基礎となるクエリを表します。これは、API バージョン 21.0 以降で使用できます。 サポートされているコール REST: DELETE、GET、PATCH、POST (クエリ要求は URI で指定) SOAP: create()、delete()、describe()、describeSObjects()、query()、retrieve()、update() 特別なアクセスルール • このオブジェクトは、組織でストリーミング API が有効になっている場合にのみ使用できます。 • 「作成」権限を持つユーザのみがこのレコードを作成できます。 項目 項目 データ型 説明 ApiVersion double 必須。Query で指定されるクエリを実行するために使用する API バー ジョン。APIバージョンは 20.0 以降である必要があります。クエリがパッ ケージからのカスタムオブジェクトに適用される場合、この値がパッ ケージの ApiVersion に一致する必要があります。 例の値: 38.0 項目プロパティ: Create、Filter、Sort、Update Description string PushTopic の説明。最大 400 文字です。 項目プロパティ: Create、Filter、Sort、Update ID ID システム項目: レコードを識別するグローバルに一意の文字列。 項目プロパティ: Default on create、Filter、Group、idLookup、Sort isActive boolean レコードが組織の上限に対して現在カウントされているかどうかを示 す。 項目プロパティ: Create、Default on create、Filter、Group、Sort、Update 81 PushTopic 項目 データ型 説明 IsDeleted boolean システム項目: レコードがごみ箱に移動されたか (true)、否か (false) を示す。 項目プロパティ: Default on create、Filter、Group、Sort Name string 必須。MyNewCases や TeamUpdatedContacts などの PushTopic の内容 を説明する名前。最大 25 文字です。この値ではチャネルを特定します。 値は一意である必要があります。 項目プロパティ: Create、Filter、Group、Sort、Update NotifyForFields picklist 通知を生成するために評価される項目を指定します。 有効な値は次のとおりです。 • All • Referenced (デフォルト) • Select • Where 項目プロパティ: Create、Filter、Sort、Update NotifyForOperations picklist 通知を生成できるレコードイベントを指定します。 有効な値は次のとおりです。 • All (デフォルト) • Create • Extended • Update API バージョン 28.0 以前の項目プロパティ: Create、Filter、Sort、Update API バージョン 29.0 以降の項目プロパティ: Filter、Sort API バージョン 29.0 以降では、この項目は参照のみであり、イベントの 削除および復元に関する情報は含まれません。通知を生成するレコード イベントを指定するには、NotifyForOperationCreate、 NotifyForOperationDelete、NotifyForOperationUndelete、 NotifyForOperationUpdate を使用します。 Extended の値は、作成操作と更新操作のいずれもイベントを生成する ように設定されていないことを示します。 NotifyForOperationCreate boolean 作成操作で通知を生成する場合は true、それ以外の場合は false。デ フォルトは true です。この項目は、API バージョン 29.0 以降で使用で きます。 NotifyForOperationDelete boolean 削除操作で通知を生成する場合は true、それ以外の場合は false。デ フォルトは true です。削除および復元イベント通知を取得するには、 クライアントは cometd/29.0 (またはそれ以降) の ストリーミング API 82 PushTopic 項目 データ型 説明 エンドポイントを使用して接続する必要があります。この項目は、API バージョン 29.0 以降で使用できます。 NotifyForOperationUndelete boolean 復元操作で通知を生成する場合は true、それ以外の場合は false。デ フォルトは true です。削除および復元イベント通知を取得するには、 クライアントは cometd/29.0 (またはそれ以降) の ストリーミング API エンドポイントを使用して接続する必要があります。この項目は、API バージョン 29.0 以降で使用できます。 NotifyForOperationUpdate boolean 更新操作で通知を生成する場合は true、それ以外の場合は false。デ フォルトは true です。この項目は、API バージョン 29.0 以降で使用で きます。 Query string 必須。イベントのチャネルへの送信をトリガするレコードへの変更を特 定する SOQL クエリステートメント。 最大 1,300 文字です。 項目プロパティ: Create、Filter、Sort、Update PushTopic と通知 PushTopic は、いつチャネル内で通知を生成するかを定義します。これを指定するには、次の PushTopic 項目を 設定します。 • PushTopic クエリ • イベント • 通知 83 第 13 章 StreamingChannel 汎用ストリーミング APIイベントをリスナーに通知するための基礎となるチャネルを表します。APIバージョン 29.0 以降で使用できます。 サポートされているコール REST: DELETE、GET、PATCH、POST (クエリ要求は URI で指定) SOAP: create()、delete()、describe()、describeLayout()、describeSObjects()、getDeleted()、 getUpdated()、query()、retrieve()、undelete()、update() 特別なアクセスルール • このオブジェクトは、組織でストリーミング API が有効になっている場合にのみ使用できます。 • 「作成」権限を持つユーザのみがこのレコードを作成できます。 • 権限セットを作成し、組織のすべてのストリーミングチャネルに対する参照および作成アクセス権をユー ザに付与できます。このアクセス権は、ユーザ共有などの特定のチャネルには適していません。 • ユーザ共有を StreamingChannel に適用できます。チャネルを特定のユーザまたはグループと共有すること で、チャネルでイベントを送受信するためのアクセス権を制限できます。「公開/参照のみ」または「参 照・更新」アクセス権によって共有されるチャネルでは、そのチャネルに登録しているクライアントのう ち、共有ユーザまたはグループのセットに関連付けられたユーザセッションも使用するクライアントへの イベント送信のみが行われます。共有チャネルに対する「参照・更新」アクセス権を持つユーザのみが、 そのチャネルでのイベント生成または実際の StreamingChannel レコードの変更を行うことができます。 動的ストリーミングチャネル 汎用ストリーミングでは、クライアントが最初にチャネルに登録するときに StreamingChannel が作成される、 動的ストリーミングチャネルもサポートされます。組織内の動的ストリーミングチャネルを有効化するには、 [設定] から [クイック検索] ボックスに「ユーザインターフェース」と入力し、[ユーザインターフェース] を選 択して [動的ストリーミングチャネル作成を有効化] を有効化します。 84 StreamingChannel 項目 項目 データ型 説明 Description string StreamingChannel の説明。最大 255 文字です。 項目プロパティ: Create、Filter、Group、Nillable、Sort、Update 表示ラベル: 説明 ID ID システム項目: StreamingChannel レコードを識別するグローバルに一意の 文字列。 項目プロパティ: Default on create、Filter、Group、idLookup、Sort IsDeleted boolean システム項目: レコードがごみ箱に移動されたか (true)、否か (false) を示す。 項目プロパティ: Default on create、Filter、Group、Sort IsDynamic boolean 必要に応じて登録時にチャネルが動的に作成される場合は true、それ 以外の場合は false。 項目プロパティ: Default on create、Filter、Group、Sort LastReferencedDate date 現在のユーザがこのレコードに関連するレコードを最後に表示したとき のタイムスタンプ。 項目プロパティ: Filter、Sort LastViewedDate date 現在のユーザがこのレコードを最後に表示したときのタイムスタンプ。 この値が null の場合、このレコードは参照 (LastReferencedDate) され ただけで、表示はされていない可能性があります。 項目プロパティ: Filter、Sort Name string 必須。StreamingChannelの内容を説明する名前。最大 80 文字で、英数字、 「_」、「/」文字のみが有効です。「/u/」で開始する必要があります。 この値ではチャネルを特定します。値は一意である必要があります。 項目プロパティ: Create、Filter、Group、idLookup、Sort、Update 表示ラベル: ストリーミングチャネル名 OwnerId reference StreamingChannel の所有者の ID。 項目プロパティ: Create、Default on create、Filter、Group、Sort、Update 表示ラベル: 所有者名 85 Streaming Channel Push 第 14 章 登録者情報を取得し、ストリーミングチャネルの通知を転送します。 構文 URI /vXX.X/sobjects/StreamingChannel/[チャネル ID]/push 適用開始バージョン 29.0 形式 JSON、XML HTTP メソッド GET、POST 認証 Authorization: Bearer token リクエストボディ GET の場合、リクエストボディは不要です。POST の場合は、転送通知ペイロードを指定するリクエストボ ディが必要です。これには、次の項目が含まれます。 名前 型 説明 pushEvents 転送イベントペイロー 通知を送信するためのイベントペイロードのリスト。 ドの配列 それぞれの転送イベントペイロードには、次の項目が含まれます。 名前 型 説明 payload string 通知で送信される情報。3,000 文字 (1 バイト文字) 以下である必要 があります。 userIds ユーザ ID の配列 通知を送信する登録ユーザのリスト。この配列が空の場合は、 チャネルのすべての登録者に通知が送信されます。 86 Streaming Channel Push 要求パラメータ なし 応答データ GET の場合、チャネルおよび登録者に関する情報が次の項目に返されます。 名前 型 OnlineUserIds ユーザ ID の配列 ChannelName string 説明 このチャネルに現在登録されているユーザのユーザ ID。 チャネル名 (/u/notifications/ExampleUserChannel など)。 POST の場合、チャネルおよびペイロード通知結果に関する情報が、転送結果の配列に返されます。それぞ れの結果には、次の項目が含まれます。 名前 型 説明 fanoutCount number イベントが送信された登録者数。これは、オンラインになってい る POST 要求で指定された登録者の数です。要求がすべての登録 者に送信された場合は、fanoutCount が –1 になります。チャネル にアクティブな登録者が存在しない場合は、fanoutCount が 0 にな ります。 userOnlineStatus ユーザのオンライン状 通知が送信されたユーザ ID とそのリスナー状況のリスト。ユー 況情報の配列 ザ ID がアクティブに登録されリスンしている場合は true、それ 以外の場合は false。 例 次に、services/data/v29.0/sobjects/StreamingChannel/0M6D000000000g7KXA/push の GET 要求の JSON 応答の例を示します。 { "OnlineUserIds" : [ "005D0000001QXi1IAG" ], "ChannelName" : "/u/notifications/ExampleUserChannel" } JSON リクエストボディを使用した services/data/v29.0/sobjects/StreamingChannel/0M6D000000000g7KXA/push への POST 要求は、次 のようになります。 { "pushEvents": [ { "payload": "hello world!", "userIds": [ "005xx000001Svq3AAC", "005xx000001Svq4AAC" ] }, { 87 Streaming Channel Push "payload": "broadcast to everybody (empty user list)!", "userIds": [] } ] } JSON 応答データは、次のようになります。 [ { "fanoutCount" : 1, "userOnlineStatus" : { "005xx000001Svq3AAC" : true, "005xx000001Svq4AAC" : false, } }, { "fanoutCount" : -1, "userOnlineStatus" : { } } ] 88 第 15 章 ストリーミング API の制限 制限によって、共有リソースが保護されます。これは、ストリーミング API の基本コンシューマを対象とした デフォルトの制限です。 アプリケーションでこの制限を超えるか、トピックあたりのクライアント数または全トピックの同時クライア ント数を増やす必要がある場合は、Salesforce にお問い合わせください。Salesforce を利用して、毎日、多くのお 客様が数百万ものイベントを処理しています。 次の制限は、すべての API バージョンの PushTopic ストリーミングに適用されます。 説明 Performance Enterprise Edition およ Edition び Unlimited Edition 組織あたりのトピック (PushTopic レコード) の最大数 他のすべて のエディ ション 100 50 40 トピックあたりのクライアント (登録者) の最大数 2,000 1,000 20 全トピックの同時クライアント (登録者) の最大数 2,000 1,000 20 24 時間あたりのイベントの最大数 1,000,000 接続中のソケットタイムアウト (CometD セッション) 接続成功後の再接続までのタイムアウト (keepalive) PushTopic レコードの Query 項目での SOQL クエリの最大長 PushTopic 名の最大長 200,000 50,000 (無料 の組織の場 合は 10,000) 110 秒 110 秒 110 秒 40 秒 40 秒 40 秒 1,300 文字 1,300 文字 1,300 文字 25 文字 25 文字 25 文字 メモ: 無料の組織の場合、24 時間あたりのイベントの最大数は 10,000 です。無料の組織には、Developer Edition 組織、Sandbox、環境ハブを介して作成されたパートナーテスト組織とデモ組織を含むトライアル 組織 (すべてのエディション) があります。 89 ストリーミング API の制限 汎用ストリーミングの制限 Performance Enterprise Edition およ Edition び Unlimited Edition 説明 Professional 無料の組織 Edition 1,000 1,000 1,000 200 汎用ストリーミングを使用した場合の 24 時間以内の イベントの最大数 (API バージョン 36.0 以前) 100,000 100,000 100,000 10,000 デュラブル汎用ストリーミングを使用した場合の 24 時間以内のイベントの最大数 (API バージョン 37.0 以降) 1,000,000 200,000 100,000 10,000 組織あたりのストリーミングチャネルの最大数 メモ: 無料の組織には、Developer Edition 組織、Sandbox、環境ハブを介して作成されたパートナーテスト組 織とデモ組織を含むトライアル組織 (すべてのエディション) があります。 汎用ストリーミングのクライアント最大数と同時クライアントの最大数には PushTopic ストリーミングと同じ 制限があります。汎用ストリーミングとデュラブル汎用ストリーミングには次の制限が適用されます。 説明 Performance Enterprise Edition およ Edition び Unlimited Edition 他のすべて のエディ ション 汎用ストリーミングチャネルあたりのクライアント (登録者) の最大数 2,000 1,000 20 汎用ストリーミングチャネル全体での同時クライアント (登録者) の最 大数 2,000 1,000 20 90