Comments
Description
Transcript
Force.com ストリーミング API 開発者ガイド
Force.com ストリーミング API 開発者ガイド バージョン 35.0, Winter ’16 @salesforcedocs 最終更新日: 2015/11/3 本書の英語版と翻訳版で相違がある場合は英語版を優先するものとします。 © Copyright 2000–2015 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 第 2 章: ワークベンチを使用したクイックスタート . . . . . . . . . . . . . . . . . . . . . . . . 5 前提条件 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 ステップ 1: オブジェクトを作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 ステップ 2: PushTopic を作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 ステップ 3: PushTopic チャネルに登録する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 ステップ 4: PushTopic チャネルをテストする . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 コード例 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 第 3 章: 例: 対話型 Visualforce ページ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 前提条件 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 ステップ 1: オブジェクトを作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 ステップ 2: PushTopic を作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 ステップ 3: 静的リソースを作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 ステップ 4: Visualforce ページを作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 ステップ 5: PushTopic チャネルをテストする . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 第 4 章: 例: Visualforce ページ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 前提条件 . . . . . . . . . . . . . . . . . . . . . . . . . . ステップ 1: オブジェクトを作成する . . . . . . ステップ 2: PushTopic を作成する . . . . . . . . ステップ 3: 静的リソースを作成する . . . . . . ステップ 4: Visualforce ページを作成する . . . ステップ 5: PushTopic チャネルをテストする . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 第 5 章: 例: Java クライアント . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 前提条件 . . . . . . . . . . . . . . . . . . . . . . . . . . . ステップ 1: オブジェクトを作成する . . . . . . . ステップ 2: PushTopic を作成する . . . . . . . . . ステップ 3: JAR ファイルをダウンロードする . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 19 19 19 目次 ステップ 4: ソースコードを追加する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 第 6 章: 例: 認証 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 開発者テスト用の認証の設定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 OAuth 2.0 を使用する認証の設定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 ストリーミング API の使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 第 7 章: PushTopic の使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 PushTopic クエリ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 セキュリティと PushTopic クエリ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 サポート対象の PushTopic クエリ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 サポート対象外の PushTopic クエリ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 イベント通知ルール . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 イベント . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 通知 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 一括登録 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 PushTopic の無効化 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 第 8 章: ストリーミング API の考慮事項 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 クライアントとタイムアウト . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 ストリーミング API のクライアントと Cookie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 サポートされるブラウザ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 HTTPS の推奨 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 ストリーミング API アプリケーションのデバッグ . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 イベント使用状況の監視 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 通知メッセージの順序 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 汎用ストリーミング . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 第 9 章: 汎用ストリーミングの概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 第 10 章: クイックスタート . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 ストリーミングチャネルを作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 Java クライアントを作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 REST を使用してイベントを生成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 リファレンス . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 第 11 章: PushTopic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 第 12 章: StreamingChannel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 第 13 章: Streaming Channel Push . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 第 14 章: ストリーミング API の制限 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 Force.com ストリーミング API の開始 第1章 トピック: • プッシュ技術の概 要 • Bayeux プロトコ ル、CometD、およ び long polling ストリーミング API の概要 ストリーミング API を使用すると、Salesforce データへの変更が定義した SOQL クエリ に一致する場合、セキュアで拡張性の高い方法で通知を受け取ることができます。 これらのイベントは次の場所で受信できます。 • Salesforce アプリケーション内のページ。 • Salesforce 外のアプリケーションサーバ。 • Salesforce アプリケーション外のクライアント。 • ストリーミング API 用語 • クライアントの接 続方法 1. SOQL クエリに基づいて PushTopic を作成します。これによりチャネルが定義され ます。 • メッセージの信頼 性 2. クライアントがチャネルに登録します。 ストリーミング API を使用するときのイベントの順序は次のとおりです。 3. レコードが作成、更新、削除、復元されます (イベントが発生)。そのレコードへ の変更が評価されます。 4. レコードの変更が PushTopic クエリの条件に一致した場合、サーバが通知を生成 し、登録しているクライアントがその通知を受信します。 ストリーミング API は、定義した条件に基づいてサーバからクライアントに通知を プッシュする場合に便利です。次のようなアプリケーションでストリーミング API を検討してください。 頻繁にポーリングするアプリケーション Salesforce インフラストラクチャに対して絶えずポーリングし、不必要な API コー ルと処理時間を消費するアプリケーションでストリーミング API を使用すると、 データを返さない要求の数を減らし、効率を高めることができます。 全般的な通知 組織内のデータ変更について全般的な通知が必要なアプリケーションにストリー ミング API を使用すると、API コール数が減り、パフォーマンスが向上します。 メモ: ストリーミング API は、API が有効であればどの組織にも使用できます。 これには、Salesforce 組織と Database.com 組織の両方が含まれます。 1 ストリーミング API の概要 プッシュ技術の概要 プッシュ技術の概要 プッシュ技術とはインターネットベース通信の 1 つのモデルであり、この技術によってサーバからクライアン トへの情報転送が開始されます。この種類の通信は Publish/Subscribe (公開/登録) モデルとも呼ばれ、クライアン トからサーバに対する情報の要求が必要なプル技術とは反対の技術です。サーバが送信する情報は通常、事前 に指定されます。ストリーミング API を使用するときは、PushTopic を作成してクライアントが受け取る情報を 指定します。クライアントは PushTopic チャネルに登録して PushTopic 条件に一致するイベントの通知を受け取 ります。 プッシュ技術では、クライアントが情報のチャネルに登録すると、サーバがクライアントに情報をプッシュ送 信します。クライアントが情報を受け取るには、サーバへの接続を維持する必要があります。ストリーミング API は Bayeux プロトコルと CometD を使用するため、クライアントからサーバへの接続は long polling を使用して 維持されます。 Bayeux プロトコル、CometD、および long polling Bayeux プロトコルと CometD はどちらも long polling を使用します。 • 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 クライ アントは次の 3 段階でストリーミング 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 では、通知の配信の永続性と信頼性は保証していません。ストリーミングサーバは、クラ イアントの状態を維持しておらず、配信された内容を追跡しません。クライアントは、次のようなさまざまな 理由でメッセージを受信しない可能性があります。 • クライアントが初めて登録または再接続した場合、チャネルに登録していなかった間に処理されたメッセー ジは受信しません。 • クライアントが切断し、新たにハンドシェイクを開始した場合は別のアプリケーションサーバを使用する 可能性があります。そのため、その時点からの新しいメッセージのみを受信します。 • システムの使用負荷が高い場合、システムイベントが削除されることがあります。 • アプリケーションサーバが停止した場合、処理中で未送信のメッセージはすべて失われます。そのアプリ ケーションサーバに接続しているクライアントはすべて切断されます。通知を受け取るには、クライアン トは再接続してトピックチャネルに登録する必要があります。 4 第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 開発」権限が必要です。 5 ワークベンチを使用したクイックスタート ステップ 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 オブジェクトの詳細ページに移動します。 6 ワークベンチを使用したクイックスタート ステップ 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 = 35.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 項目は使用できず、通知を生成するレコードイベントの設定には 7 ワークベンチを使用したクイックスタート ステップ 3: PushTopic チャネルに登録する NotifyForOperations 列挙項目が代わりに使用されます。詳細は、「PushTopic」を参照してくださ い。 関連トピック: Salesforce ヘルプ: 開発者コンソールを開く ステップ 3: PushTopic チャネルに登録する このステップでは、前のステップで PushTopic レコードを使用して作成したチャネルに登録します。 重要: ワークベンチは、無料のオープンソースのコミュニティサポートツールです (ワークベンチのヘル プページを参照)。Salesforceは、デモ目的でのみワークベンチのホスト型インスタンスを提供しています。 このワークベンチのホスト型インスタンスを本番データベースのデータへのアクセスに使用することは お勧めしません。ワークベンチを本番データベースに使用する場合は、各自で所有するリソースを使用 してワークベンチをダウンロード、ホスト、および設定してください。 ワークベンチは、http://code.google.com/p/forceworkbench/downloads/list からダウンロードできます。 1. ブラウザで、https://developer.salesforce.com/page/Workbench に移動します。 2. [Environment (環境)] で [Production (本番)] を選択します。 3. [API Version (API バージョン)] で 35.0 を選択します。 4. サービスの利用規約に同意し、[Login with Salesforce (Salesforce でログイン)] をクリックします。 5. データベースへの接続が確立されると、[Select (選択)] ページが表示されます。 6. [queries (クエリ)] > [Streaming Push Topics (ストリーミング転送トピック)] をクリックします。 7. [Push Topic (転送トピック)] 項目で [InvoiceStatementUpdates] を選択します。 8. [Subscribe (登録)] をクリックします。 接続および応答情報と "Subscribed to /topic/InvoiceStatementUpdates" のような応答が表示されます。 このブラウザウィンドウを開いたままにして、接続がタイムアウトしないようにします。次のステップでは、 作成した InvoiceStatement レコードがトリガしたイベント通知を表示できます。 ステップ 4: PushTopic チャネルをテストする ステップ 3: PushTopic チャネルに登録するで使用したブラウザが開いたままで、接続がタイムアウトしていない ことを確認します。このブラウザでイベント通知を表示します。 最後のステップとして PushTopic チャネルをテストするために、ワークベンチで新しい InvoiceStatement レコード を作成し、イベント通知を表示します。 1. 新しいブラウザウィンドウで、ワークベンチのインスタンスを開き、ステップ 3: PushTopic チャネルに登録 するで使用した手順に従い、同じユーザ名を使用してログインします。 メモ: レコードを更新したユーザとチャネルに登録したユーザがレコードを共有していない場合、登 録したユーザは通知を受け取りません。たとえば、組織の共有モデルが非公開の場合などです。 8 ワークベンチを使用したクイックスタート ステップ 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" } } } 9 コード例 第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 開発」権限が必要です。 10 例: 対話型 Visualforce ページ ステップ 1: オブジェクトを作成する ステップ 1: オブジェクトを作成する この例を実行するには、最初に InvoiceStatement オブジェクトを作成する必要があります。このオブジェクトを まだ作成していない場合は、「ステップ 1: オブジェクトを作成する」を参照してください。 ステップ 2: PushTopic を作成する この例を実行するには、PushTopic を作成する必要があります。これをまだ行っていない場合は、「ステップ 2: PushTopic を作成する」を参照してください。 ステップ 3: 静的リソースを作成する 1. http://www.salesforce.com/us/developer/docs/api_streaming_VF_code_sample/streaming_api_interactive_visualforce_demo-v25.zip から、静的リソースファイルの .zip ファイルをダウンロードします。 2. streaming_api_interactive_visualforce_demo-v25.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 11 例: 対話型 Visualforce ページ ステップ 4: Visualforce ページを作成する 静的リソースについての詳細は、「Delivering Static Resources with Visualforce (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> 12 例: 対話型 Visualforce ページ ステップ 5: PushTopic チャネルをテストする </div> </div> </apex:page> 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 レコードが更新されたときの通知データを示します。 [登録解除] をクリックして、チャネルから登録解除し、通知の受信を停止します。 13 第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 開発」権限が必要です。 14 例: 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 15 例: 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> 16 例: 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 ページにイベント通知が表示 されます。 17 第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 開発」権限が必要です。 18 例: 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. URL http://dist.codehaus.org/jetty/jetty-hightide-7.4.4/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; 19 例: Java クライアント import import import import import ステップ 4: ソースコードを追加する 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. **/ 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/35.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 20 例: Java クライアント ステップ 4: ソースコードを追加する (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); } } } }); 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(); 21 例: Java クライアント ステップ 4: ソースコードを追加する 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); 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); } 22 例: Java クライアント ステップ 4: ソースコードを追加する assert pair.length == 2; final String sessionid = pair[0]; String endpoint = pair[1]; System.out.println("Login successful!\nEndpoint: " + endpoint + "\nSessionid=" + 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 の変更は必要ありません)。 23 例: 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"); 24 例: 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) { 25 例: 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! Endpoint: https://www.salesforce.com Sessionid=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" } 26 例: 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" } 27 第6章 例: 認証 開発者テスト用に単純な認証スキームを設定できます。本番システムには、OAuth 2.0 などの強固な認証を使用 してください。 • 開発者テスト用の認証の設定 • OAuth 2.0 を使用する認証の設定 開発者テスト用の認証の設定 開発者テスト用の認証を設定する手順は、次のとおりです。 重要: この認証方法はテスト用にのみ使用し、本番環境では決して使用しないでください。 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 で、[設定] から [クイック検索] ボックスに「アプリケーション」と入力し、[アプリケーション] を 選択します。[接続アプリケーション] 関連リストの [新規] をクリックして、新しい接続アプリケーション を作成します。 ここで指定する [コールバック URL] は、Web アプリケーションのコールバック URL と同じです。Java を使 用する場合、通常はこれはサーブレットです。また、セキュアである必要があります。http:// は機能せ ず、https:// のみが機能します。開発環境では、コールバック URL は https://my-website/_callback 28 例: 認証 OAuth 2.0 を使用する認証の設定 のような形になります。[保存] をクリックすると、[コンシューマ鍵] が作成され、表示されます。また、 [コンシューマの秘密] が作成されます (表示するにはリンクをクリックします)。 メモ: 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); params.setParameter(HttpConnectionParams.CONNECTION_TIMEOUT, 30000); // Set the SID. 29 例: 認証 OAuth 2.0 を使用する認証の設定 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}", "35.0")); } 30 例: 認証 OAuth 2.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/v35.0/ 31 ストリーミング API の使用 第7章 トピック: • PushTopic クエリ • イベント通知ルー ル • 一括登録 • PushTopic の無効化 PushTopic の使用 作成した各 PushTopic レコードは CometD のチャネルに対応します。チャネル名は、 PushTopic 名にプレフィックス「/topic/」を付加した名前です (/topic/MyPushTopic など)。Bayeux クライアントはこのチャネル上でストリーミングされたイベントを受 信できます。 メモ: Bulk API によって実行された更新では、通知の量がチャネルの許容量を超 える可能性があるため通知は生成されません。 PushTopic レコードが作成されるとすぐに、一致するレコード作成、更新、削除、復 元があるかどうかの評価がシステムで開始されます。一致がある場合は常に新しい 通知が生成されます。サーバは、現在登録されているチャネルに新しい通知がある か毎秒ポーリングします。この時間は全体的なサーバ負荷に応じて変動する場合が あります。 PushTopic は、いつチャネル内で通知を生成するかを定義します。これを指定するに は、次の PushTopic 項目を設定します。 • PushTopic クエリ • イベント • 通知 メモ: 通知を受信するには、PushTopic クエリのオブジェクトおよび PushTopic 自 体の両方への参照アクセス権が必要です。 32 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 句で参照されるどの項目へのアクセス権もない場合、登録者は通知を受け 取りません。 33 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; 34 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 クエリでは次の 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 • 集計クエリ (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 • [テキストエリア] 項目の値の検索 35 PushTopic の使用 イベント通知ルール • 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' • 数式項目 • 複合住所項目または複合地理位置情報項目 • 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 にお問い合わせください。 イベント通知ルール レコードイベントの通知は、PushTopic の設定に基づいて生成されます。ストリーミング API 一致ロジックは、 PushTopic レコードの NotifyForOperationCreate、NotifyForOperationUpdate、 NotifyForOperationDelete、NotifyForOperationUndelete、NotifyForFields 項目を使用して通知 を生成するかどうかを判断します。 削除および復元イベント通知を取得するには、クライアントは cometd/29.0 (またはそれ以降) の ストリーミ ング API エンドポイントを使用して接続する必要があります。 イベント 通知が生成されるイベントは、レコードの作成、更新、削除、復元です。PushTopic の NotifyForOperationCreate、NotifyForOperationUpdate、NotifyForOperationDelete、 36 PushTopic の使用 通知 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 以前に書き込 まれたクライアントが、削除通知および復元通知を生成するように設定された Salesforce 組織で動作できるようにするために提供されています。 イベント項目の値と NotifyForFields 値を組み合わせることで、ストリーミング API を使用して通知を生成 するタイミングを柔軟に設定できます。 通知 レコードの作成または更新 (イベント) 後、レコードは PushTopic クエリに対して評価され、必要に応じて通知が 生成されます。通知とは、イベントの結果としてチャネルに送信されるメッセージです。通知は JSON 形式の メッセージです。PushTopic 項目 NotifyForFields では、レコードが PushTopic クエリに対してどのように評 価されるかを指定します。次の NotifyForFields 値があります。 37 PushTopic の使用 通知 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 句に指定された値と一致する レコードが更新される レコード項目値が 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 句の唯一の項目である場合、いずれかの項目値が変更されると通知 が生成されます。 38 PushTopic の使用 PushTopic クエリ 通知 結果 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 日あたりのイベント割り当て制限に達することがありま す。さらに、すべてのレコード変更が評価され、多くの通知が生成されると、システムの負荷が高くな ることがあります。 NotifyForFields を Referenced に設定した場合 PushTopic.NotifyForFields の値を Referenced に設定した場合、レコードのいずれかの項目値が変更さ れると、その項目がクエリの SELECT 句または WHERE 句で参照されていれば、ストリーミング API 一致ロジック がレコードを評価して通知を生成するかどうかを判断します。 PushTopic.NotifyForFields 値が Referenced の場合、PushTopic クエリには ID 以外の項目を 1 つ以上含む SELECT 句か、ID 以外の項目を 1 つ以上含む WHERE 句が必要です。 イベント 通知が生成される条件 レコードが作成される レコード項目値が WHERE 句に指定された値と一致する 39 PushTopic の使用 通知 イベント 通知が生成される条件 レコードが更新される • 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', 'e10R0000000KEU9IAO', 'v32B0000000KWZ7YEP') f1、f2、f3、f4 のいずれかが変更され、かつ f3 および f4 が WHERE 句 の値と一致し、かつ ID が WHERE 句の IN リストに含まれる場合、通 知を生成します。 NotifyForFields を Select に設定した場合 PushTopic.NotifyForFields の値を Select に設定した場合、レコードのいずれかの項目値が変更される と、その項目がクエリの SELECT 句で参照されていれば、ストリーミング API 一致ロジックがレコードを評価し て通知を生成するかどうかを判断します。 PushTopic.NotifyForFields 値が Select の場合、PushTopic クエリには ID 以外の項目を 1 つ以上含む SELECT 句が必要です。 40 PushTopic の使用 通知 イベント 通知が生成される条件 レコードが作成される レコード項目値が 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 リストに含まれる場合、通知を生成し ます。 NotifyForFields を Where に設定した場合 PushTopic.NotifyForFields の値を Where に設定した場合、レコードのいずれかの項目値が変更される と、その項目がクエリの WHERE 句で参照されていれば、ストリーミング API 一致ロジックがレコードを評価し て通知を生成するかどうかを判断します。 PushTopic.NotifyForFields 値が Where の場合、PushTopic クエリには Id 以外の項目を 1 つ以上含む WHERE 句が必要です。 イベント 通知が生成される条件 レコードが作成される レコード項目値が WHERE 句に指定された値と一致する レコードが更新される • PushTopic クエリの WHERE 句で指定されたレコード項目の 1 つ以上が変更さ れ、かつ 41 PushTopic の使用 イベント 通知 通知が生成される条件 • 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 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 42 PushTopic の使用 シナリオ 一括登録 設定 特定のレコードの 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 一括登録 複数のトピックに同時に登録できます。 そのためには、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 Specification」を参照してください。 PushTopic の無効化 PushTopic を削除するのではなく、一時的に無効化するには、isActive 項目を false に設定します。 43 PushTopic の使用 PushTopic の無効化 • ID を指定して PushTopic を無効化するには、次の Apex コードを実行します。 PushTopic pt = new PushTopic(Id='0IFD0000000008jOAA', IsActive = false); update(pt); 44 第8章 トピック: • クライアントとタ イムアウト • ストリーミング API のクライアントと Cookie • サポートされるブ ラウザ • HTTPS の推奨 • ストリーミング API アプリケーション のデバッグ • イベント使用状況 の監視 • 通知メッセージの 順序 ストリーミング API の考慮事項 ストリーミング APIを使用すると、Salesforceデータについてほぼリアルタイムの更新 通知を作成できます。この章では、ストリーミング API の実装に際して留意が必要 な、クライアントおよびトラブルシューティングに関する考慮事項を取り上げます。 45 ストリーミング 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 では、次のブラウザがサポートされます。 46 ストリーミング 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 の制限」を参照してください。 47 ストリーミング 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" } 48 ストリーミング API の考慮事項 通知メッセージの順序 } } 49 汎用ストリーミング 第9章 汎用ストリーミングの概要 汎用ストリーミングでは、ストリーミング API を使用して、Salesforce データの変更に関連付けられていない一 般イベントの通知を送信します。 指定するカスタムイベントに基づいて通知を送受信する場合は、汎用ストリーミングを使用します。汎用スト リーミングは、次に挙げるような、カスタム通知を送信する必要があるすべての状況で使用できます。 • 特定のチームまたは組織全体に通知を送信する • Salesforce の外部で発生するイベントの通知を送信する 汎用ストリーミングを使用するには、以下が必要です。 • チャネルを定義する StreamingChannel • チャネルに登録された 1 つ以上のクライアント • チャネルの転送イベントを監視および呼び出すことができる Streaming Channel Push REST API リソース 50 第 10 章 クイックスタート このクイックスタートでは、ストリーミング 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」と入力し、説明 (省略可能) を入力します。新しい [ストリーミングチャネル] ページは、次のようになります。 51 クイックスタート 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 52 クイックスタート Java クライアントを作成する * against the Salesforce Streaming API with generic notifications. **/ 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/35.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); } 53 クイックスタート 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); } 54 クイックスタート Java クライアントを作成する 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); } assert pair.length == 2; final String sessionid = pair[0]; String endpoint = pair[1]; System.out.println("Login successful!\nEndpoint: " + endpoint + "\nSessionid=" + 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; } 55 クイックスタート Java クライアントを作成する private static String salesforceStreamingEndpoint(String endpoint) 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/"; 56 クイックスタート Java クライアントを作成する 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"); 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()); 57 クイックスタート Java クライアントを作成する 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) { 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; } } } 58 クイックスタート Java クライアントを作成する } } 5. REST リソースを使用してこのクライアントアプリケーションを実行し、通知を生成すると、出力は次のよ うになります。 Running streaming client example.... Login successful! Endpoint: https://www.salesforce.com Sessionid=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" 59 クイックスタート REST を使用してイベントを生成する }, "payload":"Broadcast message to all subscribers" }, "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は、デモ目的でのみワー クベンチのホスト型インスタンスを提供しています。このワークベンチのホスト型インスタンスを本番データ ベースのデータへのアクセスに使用することはお勧めしません。ワークベンチを本番データベースに使用する 場合は、各自で所有するリソースを使用してワークベンチをダウンロード、ホスト、および設定してくださ い。 1. ブラウザで、https://developer.salesforce.com/page/Workbench に移動します。 2. [Environment (環境)] で [Production (本番)] を選択します。 3. [API Version (API バージョン)] で 35.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 60 クイックスタート REST を使用してイベントを生成する Push REST API リソースの GET メソッドを使用して、チャネルのアクティブな登録者のリストを取得することも できます。 例: POST REST リクエストボディの例 { "pushEvents": [ { "payload": "Broadcast message to all subscribers", "userIds": [] } ] } 61 リファレンス 第 11 章 PushTopic 組織のレコードへの変更をリスナーに通知するための基礎となるクエリを表します。これは、API バージョン 21.0 以降で使用できます。 サポートされているコール REST: DELETE、GET、PATCH、POST (クエリ要求は URI で指定) SOAP: create()、delete()、describe()、describeSObjects()、query()、retrieve()、update() 特別なアクセスルール • このオブジェクトは、組織でストリーミング API が有効になっている場合にのみ使用できます。 • 「作成」権限を持つユーザのみがこのレコードを作成できます。「すべてのデータの参照」権限を持つユー ザは、PushTopic レコードを参照し、ストリーミングメッセージを表示できます。 項目 項目 データ型 説明 ApiVersion double 必須。Query で指定されるクエリを実行するために使用する API バー ジョン。APIバージョンは 20.0 以降である必要があります。クエリがパッ ケージからのカスタムオブジェクトに適用される場合、この値がパッ ケージの ApiVersion に一致する必要があります。 例の値: 35.0 項目プロパティ: Create、Filter、Sort、Update Description string PushTopic の説明。最大 400 文字です。 項目プロパティ: Create、Filter、Sort、Update ID ID システム項目: レコードを識別するグローバルに一意の文字列。 項目プロパティ: Default on create、Filter、Group、idLookup、Sort 62 PushTopic 項目 データ型 説明 isActive boolean レコードが組織の上限に対して現在カウントされているかどうかを示 す。 項目プロパティ: Create、Default on create、Filter、Group、Sort、Update 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 以降で使用で きます。 63 PushTopic 項目 データ型 説明 NotifyForOperationDelete boolean 削除操作で通知を生成する場合は true、それ以外の場合は false。デ フォルトは true です。削除および復元イベント通知を取得するには、 クライアントは cometd/29.0 (またはそれ以降) の ストリーミング API エンドポイントを使用して接続する必要があります。この項目は、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 クエリステートメント。 最大 1300 文字です。 項目プロパティ: Create、Filter、Sort、Update PushTopic と通知 PushTopic は、いつチャネル内で通知を生成するかを定義します。これを指定するには、次の PushTopic 項目を 設定します。 • PushTopic クエリ • イベント • 通知 64 第 12 章 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 レコードの変更を行うことができます。 項目 項目 データ型 説明 Description string StreamingChannel の説明。最大 255 文字です。 項目プロパティ: Create、Filter、Group、Nillable、Sort、Update 表示ラベル: 説明 ID ID システム項目: StreamingChannel レコードを識別するグローバルに一意の 文字列。 項目プロパティ: Default on create、Filter、Group、idLookup、Sort 65 StreamingChannel 項目 データ型 説明 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 表示ラベル: 所有者名 66 Streaming Channel Push 第 13 章 登録者情報を取得し、ストリーミングチャネルの通知を転送します。 構文 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 の配列 通知を送信する登録ユーザのリスト。この配列が空の場合は、 チャネルのすべての登録者に通知が送信されます。 67 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" ] }, { 68 Streaming Channel Push "payload": "broadcast to everybody (empty user list)!", "userIds": [] } ] } JSON 応答データは、次のようになります。 [ { "fanoutCount" : 1, "userOnlineStatus" : { "005xx000001Svq3AAC" : true, "005xx000001Svq4AAC" : false, } }, { "fanoutCount" : -1, "userOnlineStatus" : { } } ] 69 第 14 章 ストリーミング API の制限 制限によって、共有リソースが保護されます。これは、ストリーミング API の基本コンシューマを対象とした デフォルトの制限です。 アプリケーションでこの制限を超えるか、トピックあたりのクライアント数または全トピックの同時クライア ント数を増やす必要がある場合は、Salesforce にお問い合わせください。Salesforce を利用して、毎日、多くのお 客様が数百万ものイベントを処理しています。 説明 Performance Enterprise Edition およ Edition び Unlimited Edition 組織あたりのトピック (PushTopic レコード) の最大数 他のすべて のエディ ション 100 50 40 トピックあたりのクライアント (登録者) の最大数 2000 1000 20 全トピックの同時クライアント (登録者) の最大数 2000 1000 20 1 日あたりのイベントの最大数 (24 時間) 1,000,000 接続中のソケットタイムアウト (CometD セッション) 110 秒 110 秒 110 秒 40 秒 40 秒 40 秒 1300 文字 1300 文字 1300 文字 25 文字 25 文字 25 文字 接続成功後の再接続までのタイムアウト (keepalive) PushTopic レコードの Query 項目での SOQL クエリの最大長 PushTopic 名の最大長 200,000 50,000 (無料 の組織の場 合は 10,000) 汎用ストリーミングの制限 汎用ストリーミングには次の制限が適用されます。 説明 Developer Edition Performance Edition、Unlimited Edition、Enterprise Edition、および Professional Edition 組織あたりの StreamingChannel の最 大数 1000 200 70 ストリーミング API の制限 説明 Developer Edition Performance Edition、Unlimited Edition、Enterprise Edition、および Professional Edition 1 日あたりのイベントの最大数 (24 時間) 100,000 10,000 汎用ストリーミングのクライアントの最大数と同時クライアントの最大数に対する制限は、PushTopic ストリー ミングに使用される制限と同じです。 説明 Performance Enterprise Edition およ Edition び Unlimited Edition 他のすべて のエディ ション 汎用ストリーミングチャネルあたりのクライアント (登録者) の最大数 2000 1000 20 汎用ストリーミングチャネル全体での同時クライアント (登録者) の最 大数 2000 1000 20 71