アンケートに答える (英語) | 日本語 | サイト ディレクトリ
注意: 一部のページは英語でのみご利用いただけます。

OpenSocial API デベロッパー ガイド (v0.7)

このガイドでは、OpenSocial アプリケーションの構築について解説します。Gadgets API や JavaScript についてある程度の知識をお持ちのデベロッパーを対象としていますが、詳しい情報が必要な箇所では他の資料へのリンクを示します。

このドキュメントには、OpenSocial API の 0.7 更新時の変更点が反映されています。New更新とマークされている項は、コーディング方法が前のバージョンから変更されたことを示します。

目次

  1. ソーシャル アプリケーションの記述
  2. OpenSocial ライブラリのインポート
  3. 人やプロファイルへのアクセス
    1. 基本情報の取得
    2. 友人を一覧表示するサンプル コード
  4. 永続的データの操作
  5. アクティビティの登録
  6. コンテナとの連携
    1. ビュー間の移動
    2. 環境のクエリ
    3. 複数のコンテンツ セクションを含める
  7. リモート コンテンツのフェッチ
    1. キャッシュ
    2. XML の例
    3. JSON の例
    4. POST メソッドの使用
    5. 認可タイプの設定
  8. 許可のコントロール
  9. 関連情報

ソーシャル アプリケーションの記述

ソーシャル アプリケーションとは、簡単に言えば、OpenSocial JavaScript API をサポートするコンテナ上で実行されるアプリケーションです。

ソーシャル アプリケーションを記述するには以下が必要です。

  • OpenSocial JavaScript API をサポートするコンテナ (たとえば orkut.com) へのアクセス。詳しくは、はじめにをご覧ください。
  • ガジェットを構築するための実用的な基礎知識。Google ガジェット API 開発ガイドをご覧ください。

OpenSocial API は、人に焦点を当てた API です。ユーザー間でアクティビティを共有したり、友人に関する情報にアクセスしたりできます。OpenSocial API の機能は、以下の 3 つの領域に分けることができます。

  • 人と関係
  • 永続性
  • アクティビティ

API 呼び出しの多くは非同期です。これは、情報を取得したり更新したりする上で、サーバー要求が必要になることがあるためです。したがって、サーバーからデータが返されたときに実行されるコールバック関数を渡す必要があります。

OpenSocial JavaScript API のクラスやメソッドの詳細については、API リファレンスをご覧ください。

OpenSocial ライブラリのインポート

OpenSocial API を使用するには、アプリケーションに次のような Requires セクションを追加します。

<ModulePrefs title="Title of Your Application">
  <Require feature="opensocial-0.7"/>
</ModulePrefs>

ガジェット XML 仕様の構造とコンテンツの詳細については、Gadgets API デベロッパー ガイド をご覧ください。

人やプロファイルへのアクセス

ここでは、友人の名前を一覧表示する簡単な例について説明します。まずは、OpenSocial API で定義されている以下の役割について理解する必要があります。

  • ビューア (Viewer): ブラウザにログインしているユーザー。ビューアは、自分のページを見ている場合もあれば、他のユーザーのプロファイルを見ている場合もあります。
  • オーナー (Owner): 対象となるプロファイルやアプリケーションを所有するユーザー。
  • 友人 (Friends): オーナーまたはビューアが、友人としてコンテナに追加したユーザー。

この項で説明する「友人リスト」サンプルでは、ビューアとビューアの友人をフェッチし、ビューアの友人の一覧を表示します。このサンプルに沿って、OpenSocial アプリケーションでデータをフェッチして操作する方法を説明します。基本的な手順は次のとおりです。

  1. データを取得します。
    • opensocial.newDataRequest() を呼び出して DataRequest を作成します。
    • 取得するデータの型ごとに 1 回ずつ DataRequest.add(request) を呼び出します。
    • DataRequest オブジェクトに個別の要求をすべて追加したら、DataRequest.send(callback) を呼び出します。
  2. 取得したデータを処理するコールバック関数を実装します。
    • サーバー要求の処理が完了すると、コールバック関数が実行されます。この関数は、要求の結果を格納する DataResponse パラメータを取ります。「友人リスト」では、DataResponse にビューアとビューアの友人が格納されます。コールバック関数は、この DataResponse に格納されているデータを処理します。

以降では、この手順について詳しく説明します。

データの取得

ビューアやその友人の一覧に関する情報を取得するには、次のように新しい DataRequest オブジェクトを作成し、取得するデータの型ごとに要求を追加します。

 /**
  * Request for friend information when the page loads.
  */
  function getData() {
    var req = opensocial.newDataRequest();
    req.add(req.newFetchPersonRequest(opensocial.DataRequest.PersonId.VIEWER), 'viewer');
    req.add(req.newFetchPeopleRequest(opensocial.DataRequest.Group.VIEWER_FRIENDS), 'viewerFriends');
    req.send(onLoadFriends);
  };

newFetch*Request() 呼び出しの最後のパラメータは、応答内のデータの取得に使用する文字列キーです。

コールバック関数によるデータの処理

すでに前の項のサンプルを作成したとします。ここでは、返されたデータ (型は opensocial.DataResponse) に対して何らかの処理を行います。次に示す onLoadFriends() コールバック関数は、パラメータとして取る DataResponse を解析し、ビューアとその友人の名前を表示します。

 /**
  * Parses the response to the friend information request and generates
  * html to list the friends by their display name.
  *
  * @param {Object} dataResponse Friend information that was requested.
  */
  function onLoadFriends(dataResponse) {
    var viewer = dataResponse.get('viewer').getData();
    var html = 'Friends of ' + viewer.getDisplayName(); 
    html += ':<br><ul>';
    var viewerFriends = dataResponse.get('viewerFriends').getData();
    viewerFriends.each(function(person) {
      html += '<li>' + person.getDisplayName() + '</li>';
    });
    html += '</ul>';
    document.getElementById('message').innerHTML = html;
  };

newFetch*Request() に渡した文字列キーでDataResponse.get(key) を呼び出すと、要求の結果を格納した ResponseItem が返されます。

dataResponse.get(key).getData() を呼び出すと、正常に実行された要求に対する実際の応答データが返されます。以下に、一般的な要求に対応する応答データ型を示します。

  • ビューアまたはオーナーを要求すると、opensocial.Person オブジェクトが返されます。
  • 友人のグループを要求すると、opensocial.Person オブジェクトの opensocial.Collection が返されます。

要求が正常に実行されなかった場合は、DataResponse.get(key).hasError() によって true が返されます。

友人を一覧表示するサンプル コード

この項では、前の項で紹介した「友人リスト」アプリケーションのサンプル コード全体を示します。

まずは、アプリケーションで必要になるデータを要求することから始めるのが一般的です。このコードにも、次のような行が含まれています。

gadgets.util.registerOnLoadHandler(getData);

これにより、getData() がアプリケーションのオンロード ハンドラとして登録されます。つまり、アプリケーションは最初に、getData() でビューアとその友人のデータをフェッチするということです。

次に、サンプル コード全体を示します。このコードの出力は、ID が "message"<div> に書き込まれます。

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
 <ModulePrefs title="List Friends Example">
   <Require feature="opensocial-0.7"/>
 </ModulePrefs>
 <Content type="html">

 <![CDATA[

 <script type="text/javascript">

 /**
  * Request for friend information.
  */
  function getData() {    
    var req = opensocial.newDataRequest();
    req.add(req.newFetchPersonRequest(opensocial.DataRequest.PersonId.VIEWER), 'viewer');
    req.add(req.newFetchPeopleRequest(opensocial.DataRequest.Group.VIEWER_FRIENDS), 'viewerFriends');
    req.send(onLoadFriends);
  };

 /**
  * Parses the response to the friend information request and generates
  * html to list the friends along with their display name.
  *
  * @param {Object} dataResponse Friend information that was requested.
  */
  function onLoadFriends(dataResponse) {
    var viewer = dataResponse.get('viewer').getData();
    var html = 'Friends of ' + viewer.getDisplayName(); 
    html += ':<br><ul>';
    var viewerFriends = dataResponse.get('viewerFriends').getData();
    viewerFriends.each(function(person) {
      html += '<li>' + person.getDisplayName() + '</li>';
    });
    html += '</ul>';
    document.getElementById('message').innerHTML = html;
  };

  gadgets.util.registerOnLoadHandler(getData);

  </script>
  <div id="message"> </div>
  ]]>
  </Content>
</Module>

更新 永続的データの操作

OpenSocial API では、ユーザーごと、アプリケーションごとにデータを保存したり取得したりできます。OpenSocial v0.5 および v0.6 では、アプリケーションごとのインスタンスやグローバル アプリケーション データもサポートされていましたが、これらは 0.7 ではサポートされなくなりました。

次に、データを共有ストアに保存するコード スニペットを示します。

function populateMyAppData() {
  var req = opensocial.newDataRequest();
  var data1 = Math.random() * 5;
  var data2 = Math.random() * 100;
  var data3 = new Date().getTime();
  
  req.add(req.newUpdatePersonAppDataRequest("VIEWER", "AppField1", data1));
  req.add(req.newUpdatePersonAppDataRequest("VIEWER", "AppField2", data2));
  req.add(req.newUpdatePersonAppDataRequest("VIEWER", "AppField3", data3));
  req.send(handlePopulateMyAppData);
};

上のコード スニペットで格納したデータは、次の方法で取得できます。

var req = opensocial.newDataRequest();
//Request the following three app fields
var fields = [ "AppField1", "AppField2", "AppField3" ];
req.add(req.newFetchPersonAppDataRequest("VIEWER", fields), "viewer_data");
req.send(handleRequestMyData);

次に、このアプリケーションのコード全体を示します。このアプリケーションでは、ビューアの値を設定してからそれらを取得しています。

<?xml version="1.0" encoding="UTF-8" ?> 
<Module>
  <ModulePrefs title="Data Persistence Example" > 
    <Require feature="opensocial-0.7"/>
  </ModulePrefs>
  <Content type="html">
  <![CDATA[

  <script type="text/javascript"> 
   gadgets.util.registerOnLoadHandler(populateMyAppData);
   var htmlout = "";
   var me = null;

   /************************************************************************
    * Set user data
    */
   function populateMyAppData() {
     var req = opensocial.newDataRequest();
     var data1 = Math.random() * 5;
     var data2 = Math.random() * 100;
     var data3 = new Date().getTime();
     htmlout += "Setting AppField1 to " + data1 + "<br />";
     req.add(req.newUpdatePersonAppDataRequest("VIEWER", "AppField1", data1)) + "<br />";
     htmlout += "Setting AppField2 to " + data2 + "<br />";
     req.add(req.newUpdatePersonAppDataRequest("VIEWER", "AppField2", data2)) + "<br />";
     htmlout += "Setting AppField3 to " + data3 + "<br />";
     req.add(req.newUpdatePersonAppDataRequest("VIEWER", "AppField3", data3)) + "<br />";
     req.send(handlePopulateMyAppData, "update_appdata");
   }

   /************************************************************************
    * Handle responses from update person app data requests
    */
   function handlePopulateMyAppData(data) {
     if (data.hadError()) {
       htmlout += data.getError();
     }
     requestMyData();
   }
   
   /************************************************************************
    * Fetch app data
    */
   function requestMyData() {
     var req = opensocial.newDataRequest();
     var fields = [ "AppField1", "AppField2", "AppField3" ];
     req.add(req.newFetchPersonRequest(opensocial.DataRequest.PersonId.VIEWER), "viewer");
     req.add(req.newFetchPersonAppDataRequest("VIEWER", fields), "viewer_data");
     req.send(handleRequestMyData);
   }

   /************************************************************************
    * Handle responses from app data requests
    */
   function handleRequestMyData(data) {
     var mydata = data.get("viewer_data");
     var viewer = data.get("viewer");
     me = viewer.getData();

     if (mydata.hadError()) {
       htmlout += data.getError();
       return;
     }
     // Do something with the returned data - note the getData call
     doSomethingWithMyData(mydata.getData());
   }

   /************************************************************************
   * Operate on user data
   */
   function doSomethingWithMyData(data) {
     //Data is indexed by user id, and represents an object where keys 
     //correspond with the app data fields.
     var mydata = data[me.getId()];
     var div = document.getElementById('content_div');
     htmlout += "My AppField1 data is: " + mydata["AppField1"] + "<br />";
     htmlout += "My AppField2 data is: " + mydata["AppField2"] + "<br />";
     htmlout += "My AppField3 data is: " + mydata["AppField3"] + "<br />";
     div.innerHTML = htmlout;
   }
   
 </script>
 <div id="content_div"></div>
  ]]> 
  </Content>
</Module>

注: OpenSocial アプリケーションでは、データは常に文字列として格納されます。これを JSON エンコードの文字列にしておくと、ほとんどの用途に対応できます。OpenSocial では、アプリケーション データを含め、返されるすべてのデータに対して自動的に HTML エスケープが実行されるため、解析前に appdata ストア内の文字列化された JSON オブジェクトをアンエスケープする必要があります。次に例を示します。

var unescapedString = gadgets.util.unescapeString(jsondata); 
var obj = gadgets.json.parse(unescapedString);

アクティビティ

OpenSocial API を使用すると、アクティビティ ストリームを介してアクティビティを友人と共有できます。アクティビティ ストリームとは、ユーザーのアクションを個別のエントリで表現したフィードです。アクティビティには、アプリケーションの状態の変更から映画のオンライン レビューの書き込みまで、ユーザーのあらゆるアクションが含まれます。

アクティビティの優先度を HIGH にするよう要求すると、アプリケーションがユーザーに対して、ユーザーの代わりにアクティビティを登録する許可を求めます (まだ許可を得ていない場合のみ)。アプリケーションによる登録が許可されていない場合、優先度を LOW にするよう要求しても、その呼び出しでは何も行われません。

次に、アクティビティを作成する簡単な例を示します。

<?xml version="1.0" encoding="UTF-8" ?> 
<Module>
  <ModulePrefs title="Activities" >
    <Require feature="opensocial-0.7"/>
  </ModulePrefs> 
  <Content type="html">
  <![CDATA[ 
  <div id="content_div"></div>
  <script type="text/javascript">

  var div = document.getElementById('content_div');

  function postActivity(text) {  
    var params = {};  
    params[opensocial.Activity.Field.TITLE] = text;
    var activity = opensocial.newActivity(params); 
    opensocial.requestCreateActivity(activity, opensocial.CreateActivityPriority.HIGH, callback);
  };        
  
  function callback(data) {
    var title = data.getField(opensocial.Activity.Field.TITLE);
    title = gadgets.util.unescapeString(title);
    div.innerHTML = title;
  };
  
  postActivity("This is a sample activity, created at " + new Date().toString());

  </script>
  ]]> 
  </Content>
</Module>

更新 コンテナとの連携

OpenSocial API では、以下の方法でアプリケーションとコンテナを連携させることができます。

  • アプリケーションを、コンテナ内のあるビューから別のビューに (たとえばプロファイル ビューからキャンバス ビューに) 移動させることができます。
  • アプリケーションからコンテナに対してクエリを実行し、コンテナの環境に関する情報を取得したり、それらの情報に基づいてコンテナの動作を修正したりできます。たとえば、以下に関する情報を取得できます。
    • コンテナのドメイン。
    • コンテナが特定のメソッドをサポートしているかどうか。
    • 特定のオブジェクトがコンテナのどのフィールドでサポートされているか。たとえば、Person オブジェクトであれば、コンテナで「趣味」がサポートされているかもしれません。

更新 ビュー間の移動

gadgets.views.requestNavigateTo を使用すると、アプリケーションをコンテナ内のあるページから別のページに移動させる (たとえばプロファイルからキャンバス ページへリンクさせる) ことができます。

このサンプル コードでは、API を使用してビュー間を移動する方法を示します。このコードを実行すると、リンクの一覧が表示されます。ユーザーは、いずれかのリンクをクリックすることで、コンテナの各ビューに移動できます。

<?xml version="1.0" encoding="UTF-8" ?>
<Module>  
  <ModulePrefs title="Navigating Between Views (0.7)" description="Navigates between views">    
    <Require feature="opensocial-0.7" />    
    <Require feature="views" />  
  </ModulePrefs>  
  <Content type="html">  
  <![CDATA[    
  <div id="main"></div>    
  <script type="text/javascript">

  /** 
   * Create the list of links to the other views 
   */
  function createLinks() {  
    //Get the environment, current view and an object containing the supported views  
    var env = opensocial.getEnvironment();  
    var views = gadgets.views.getSupportedViews();  
    var currentview = gadgets.views.getCurrentView();  
    var text = [ "You are currently on the ", 
        currentview.getName(), 
	    " view.  Other views: " ].join("");  

    //Set up some DOM  
    var outputdom = document.getElementById("main");  
    outputdom.appendChild(document.createTextNode(text));  
    var ol = document.createElement("ol"); 
    outputdom.appendChild(ol);  
    //Iterate over each view  
    for (var viewname in views) {    
      var view = views[viewname];    
      // Make some DOM to present each link    
      var li = document.createElement("li");    
      var a = document.createElement("a");    
      ol.appendChild(li);    
      li.appendChild(a);    
      a.href = "javascript:void(0);";    
      //Put the name of the view in the link    
      a.appendChild(document.createTextNode("Link to " + view.getName()));    
      //Handle when the user clicks a link to the other server    
      a.onclick = getNavigateClosure(view);  
    }
  };
  /** 
   * Returns a function that navigates to the supplied view 
   */
    function getNavigateClosure(view) {  
      return function() { gadgets.views.requestNavigateTo(view); };
    };

  //Execute createLinks when the page is done loading
  gadgets.util.registerOnLoadHandler(createLinks);    
  </script>  
  ]]>  
  </Content>
</Module>

上のサンプルに含まれている次の関数に注目してください。

function getNavigateClosure(view) { 
   return function() { gadgets.views.requestNavigateTo(view); };
};

このサンプルでは、クロージャという手法が使用されています。クロージャとは、外部関数のローカル変数にアクセスできる別の関数内から呼び出される関数です。ここでは、クロージャを使用することで、ユーザーがビューへのリンクをクリックしたときに、そのビューの名前を requestNavigateTo() メソッドに渡しています。

更新 環境のクエリ

Environment クラスの getDomain メソッドを使用すると、現在アクセスしているサイト (orkut.commyspace.com) がわかります。これにより、アプリケーションから、別の環境に別の方法で応答することが可能になります。getDomain メソッドは、API から相対 URL のみが返される場合に、絶対 URL を作成するために使用します。ただし、機能面で何らかの変更を行う場合は、通常は hasCapability, という別のメソッドを使用することをお勧めします。hasCapability メソッドは関数名を取り、その関数が現在のコンテナで使用できるかどうかを返します。これにより、デベロッパーは、コンテナ固有の拡張を常に同じ仕組みで OpenSocial に追加できます。supportsField メソッドも、このようなコンテナ固有の拡張性を備えています。コンテナ プロバイダでこのメソッドを使用すると、プロバイダ固有の Person フィールドや Activity フィールドを追加できます。OpenSocial 仕様に準拠するには、このフィールドを opensocial 名前空間の外でドキュメント化する必要があります。

このサンプル アプリケーションでは、ユーザーがプロファイルにいるかキャンバスにいるかに応じてその表示を変更しています。


<?xml version="1.0" encoding="UTF-8" ?>
  <Module> 
    <ModulePrefs title="My 0.7 Environment">
    <Require feature="opensocial-0.7"/>
  </ModulePrefs> <Content type="html">
  <![CDATA[
  
  <script type="text/javascript">
  /**  
   * Request for friend information when the page loads.  
   */
  function getData() {    
    var req = opensocial.newDataRequest();
    req.add(req.newFetchPersonRequest(opensocial.DataRequest.PersonId.VIEWER), 'viewer');
    req.send(greetUser);  
  }
  
  /**  
   * Change the display of the user greeting depending on whether the
   * user is in the profile or the canvas. 
   */
  function greetUser(dataResponse) {
    var viewer = dataResponse.get('viewer').getData();
    // Determine whether the getCurrentView feature is supported
    var isAble = gadgets.util.hasFeature("gadgets.views.getCurrentView");
    var html = '<h2>Greetings,  ' + viewer.getDisplayName() + '!</h2>';
    // If the container supports the getEnvironment method, determine whether the user
    // is in the canvas or profile
    if (isAble)
    {      
      var currView = gadgets.views.getCurrentView();
    // If the user is in the canvas, display the canvas view of the greeting 
    if (currView.getName() == 'canvas')
      {
        showCanvasView(html);
      }
    // Otherwise, display the profile view of the greeting
    else
    {
      // If the container supports the field THUMBNAIL_URL for PERSON objects,
      // include it in the profile view greeting page
      var myenv = opensocial.getEnvironment();
      if (myenv.supportsField(opensocial.Environment.ObjectType.PERSON, opensocial.Person.Field.THUMBNAIL_URL))
        {
          var thumb = viewer.getField(opensocial.Person.Field.THUMBNAIL_URL); 
        html += "<img src=" + thumb + "/>";
        }
      // Display the greeting in the profile and include the user's thumbnail
      document.getElementById('profile-div').innerHTML = html;
    }

    }
    // Default: just display the greeting with no image
    else {
      document.getElementById('profile-div').innerHTML = html;
    }
  }

  /** If the user is in canvas, change the display to take advantage of
   * additional screen area
   */
  function showCanvasView(str) {
    var div = document.getElementById('canvas-div');
    div.style.display="";
    str += "<img src='http://gadget-doc-examples.googlecode.com/svn/trunk/my-canvas-photo.jpg' />";
    div.innerHTML = str;
  }
  gadgets.util.registerOnLoadHandler(getData);
  </script>
  <div id="profile-div"> </div>
  <div id="canvas-div" style="display:none; font-family:Tahoma; background-color: #FFC0CB; margin: 5px; height: 570px; text-align: center;"></div>

  ]]>  
  </Content>
</Module>

New 複数のコンテンツ セクションを含める

1 つのガジェット XML ファイルには、複数の <Content> セクションを含めることができます。各 <Content> セクションは、それぞれがレンダリングするビューを宣言します。ドキュメント内のすべての <Content> セクションは兄弟関係にあり、レンダリングするビューをオプション パラメータ view= を使用して定義することもできます。

2 つのコンテンツを含むセクション

ここでは、2 つのコンテンツ セクションからなるガジェットを表示する単純な例を示します。

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Multiple Content Sections (version 1)">
    <Require feature="opensocial-0.7" />
  </ModulePrefs>
  <Content type="html" view="profile">
  <![CDATA[
    <h1>Profile</h1>
  ]]>
  </Content>
  <Content type="html" view="canvas">
  <![CDATA[
    <h1>Canvas</h1>
  ]]>
  </Content>
</Module>

出力は以下のようになります。

プロファイル ビュー

<h1>Profile</h1>

キャンバス ビュー

<h1>Canvas</h1>

キャンバスまたはプロファイル以外のビュー

コンテンツは表示されない

複数のビューが指定されたコンテンツ セクション

コンテンツ セクションには、複数のビューをカンマ区切りで指定できます。

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Multiple Content Sections (version 2)">
    <Require feature="opensocial-0.7" />
  </ModulePrefs>
  <Content type="html" view="canvas,profile">
  <![CDATA[
    <h1>Canvas and Profile</h1>
  ]]>
  </Content>
</Module>

出力は以下のようになります。

プロファイル ビュー

<h1>Canvas and Profile</h1>

キャンバス ビュー

<h1>Canvas and Profile</h1>

キャンバスまたはプロファイル以外のビュー

コンテンツは表示されない

ビューは指定されているがデフォルト コンテンツ セクションが指定されていないコンテンツ セクション

コンテンツ セクションにビュー パラメータを指定した場合、そのコンテンツ セクションはそのビューにのみ表示されます。他のビューには、デフォルト コンテンツ セクションを指定しない限りコンテンツは表示されません。

<?xml version="1.0" encoding="UTF-8" ?>
<Module>  
  <ModulePrefs title="Multiple Content Sections (version 3)">
    <Require feature="opensocial-0.7" />
  </ModulePrefs>
  <Content type="html" view="profile">
  <![CDATA[
    <h1>Profile</h1>
  ]]>        
  </Content>
</Module>

出力は以下のようになります。

プロファイル ビュー

<h1>Profile</h1>

キャンバス ビュー

コンテンツは表示されない

キャンバスまたはプロファイル以外のビュー

コンテンツは表示されない

ビューとデフォルト コンテンツ セクションが指定されているコンテンツ セクション

デフォルト コンテンツを指定するには、次のようにビュー パラメータのないコンテンツ セクションを定義します。

<Module>  
  <ModulePrefs title="Multiple Content Sections (version 4)">
    <Require feature="opensocial-0.7" />
  </ModulePrefs>
  <Content type="html" view="profile">
  <![CDATA[
    <h1>Profile</h1>
  ]]>        
  </Content>
  <Content type="html">
  <![CDATA[
    <h1>Default</1>
  ]]>
  </Content>
</Module>

出力は以下のようになります。

プロファイル ビュー

<h1>Profile</h1>

キャンバス ビュー

<h1>Default</h1>

キャンバスまたはプロファイル以外のビュー

<h1>Default</h1>

サンプル コード全体

これらすべての手法を 1 つのガジェットにまとめると次のようになります。

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Multiple Content Sections (version 5)">
    <Require feature="opensocial-0.7" />
  </ModulePrefs>
  <Content type="html" view="profile">
  <![CDATA[
    <h1>Profile</h1>
  ]]>
  </Content>
  <Content type="html" view="canvas">
  <![CDATA[
    <h1>Canvas</h1>
  ]]>
  </Content>
  <Content type="html" view="canvas,profile">
  <![CDATA[
    <h2>This shows up in canvas and profile views</h2>
  ]]>
  </Content>
  <Content type="html">
  <![CDATA[
    <h1>Default</h1>
    <h2>The content in this section only shows up if no other content sections are applicable</h2>
  ]]>
  </Content>
</Module>

出力は以下のようになります。

プロファイル ビュー

<h1>Profile</h1>
<h2>This shows up in canvas and profile views</h2>

キャンバス ビュー

<h1>Canvas</h1>
<h2>This shows up in canvas and profile views</h2>

キャンバスまたはプロファイル以外のビュー

<h1>Default</h1>
<h2>The content in this section only shows up if no other content sections are applicable</h2>

更新 リモート コンテンツのフェッチ

gadgets.io.makeRequest() メソッドを使用すると、他のウェブ サーバーやウェブ ページから、コンテンツをリモートにフェッチできます。gadgets.io.makeRequest() は、以前のガジェット API の IG_Fetch... メソッドの拡張で、GET だけでなく POST にも使用できます。また、要求の署名や認証を行うかどうかを指定することもできます。

gadgets.io.makeRequest() は、以下のパラメータを取ります。

  • リモート コンテンツをフェッチする URL。
  • フェッチしたコンテンツを処理するコールバック関数。
  • コンテンツをフェッチする方法についての追加情報を指定するパラメータ。コンテンツのタイプ、コンテンツの表示方法などを指定できます。

makeRequest() は、デフォルトでは GET メソッドを使用してデータをフェッチします。デフォルトのコンテンツ タイプは TEXT です (この場合、ウェブ ページのコンテンツは未加工のテキストとしてフェッチされます)。

次に、この API を使用した単純な例を示します。この例では、www.google.com の冒頭の 400 文字をフェッチし、それを <div> に出力しています。

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Fetch Content as Text">
    <Require feature="opensocial-0.7"/>
  </ModulePrefs>
  <Content type="html">
  <![CDATA[
    <div id="content_div"></div>
    <script type="text/javascript">

    function makeNormalRequest() {    
      var params = {};  
      params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.TEXT;  
      var url = "http://www.google.com";  
      gadgets.io.makeRequest(url, response, params);
    };

    function response(obj) {  
      //obj.text contains the text of the page that was requested  
      var str = obj.text;
      var html =  str.substr(0,400);  
      document.getElementById('content_div').innerHTML = html;
    };

    makeNormalRequest();
    </script>
  ]]>
  </Content>
</Module>

New キャッシュ

makeRequest に対する呼び出しは、デフォルトでキャッシュされます。下の例のラッパー関数は makeRequest と同じパラメータを取りますが、もう 1 つ別に refreshInterval というパラメータを取ります。このパラメータを使用することで、キャッシュの期間を指定できます。キャッシュは便利な機能ですが、あまり頻繁に更新するとパフォーマンスが低下するおそれがありますので注意してください。キャッシュを行うことで、データをすばやくフェッチできるようになります。また、リモート コンテンツをホストするサードパーティ サーバーへの負荷を軽減することもできます。0 を指定すると、キャッシュが完全に無効になってしまいます。このような設定は、できる限り避けてください。このトピックについて詳しくは、Gadgets API Developers Guide をご覧ください。

function makeCachedRequest(url, callback, params, refreshInterval) {
  var ts = new Date().getTime();
  var sep = "?";
  if (refreshInterval && refreshInterval > 0) {
    ts = Math.floor(ts / (refreshInterval * 1000));
  }
  if (url.indexOf("?") > -1) {
    sep = "&";
  }
  url = [ url, sep, "nocache=", ts ].join("");
  gadgets.io.makeRequest(url, response, params);
}

更新 XML の例

この例では、DOM コンテンツ タイプを使用して XML データを処理する方法を示します。DOM をコンテンツ タイプを指定すると、指定した XML ドキュメントが makeRequest() によって DOM オブジェクトとして取得されます。取得した DOM オブジェクトは、標準の DOM JavaScript 関数を使用して操作できます。このトピックについて詳しくは、Gadgets API Developers Guide をご覧ください。

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Fetch XML">
    <Require feature="opensocial-0.7"/>
  </ModulePrefs>
  <Content type="html">
  <![CDATA[
    <div id="content_div"></div>
    <script type="text/javascript">

    function makeDOMRequest() {    
      var params = {};  
      params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.DOM;  
      var url = "http://doc.examples.googlepages.com/breakfast-data.xml";  
      gadgets.io.makeRequest(url, response, params);
    };

    function response(obj) { 
      // obj.data contains a Document DOM element corresponding to the
      // page that was requested
      var domdata = obj.data;
      var title = domdata.getElementsByTagName("menu").item(0).getAttribute("title");
      var html = "<h2>" + title + "</h2>";
		
      // Get a list of the <food> element nodes in the file
      var itemList = domdata.getElementsByTagName("food");
 
      // Loop through all <food> nodes
      for (var i = 0; i < itemList.length ; i++) { 
        // For each <food> node, get child nodes.
        var nodeList = itemList.item(i).childNodes;

        // Loop through child nodes. Extract data from the text nodes that are
        // the children of the associated name, price, and calories element nodes.
        for (var j = 0; j < nodeList.length ; j++) {
          var node = nodeList.item(j);
          if (node.nodeName == "name") {
            var name = node.firstChild.nodeValue;
          }
          if (node.nodeName == "price") {
            var price = node.firstChild.nodeValue;
          }
        }
        html += name + " - ";
        html += price + "<br />";
      }
      html += "</div>";
      document.getElementById('content_div').innerHTML = html;
    };
    makeDOMRequest();
    </script>
  ]]>
  </Content>
</Module>

New JSON の例

JSON コンテンツ タイプを使用すると、JSON エンコードのコンテンツを JavaScript オブジェクトとしてフェッチできます。

下に示すアプリケーションでは、次の JSON エンコード文字列を含むサンプル PHP ページからコンテンツをフェッチしています。

{"validated":"This request was spoofed","query":[],"url":"http:\/\/graargh.returnstrue.com\/buh\/fetchme.php","signature":"","signature_len":1}

この文字列を含む PHP ページからコンテンツをフェッチすると、キー/値ペア (キーと値が結合された配列) を格納した JavaScript オブジェクトが返されます。この例では、オブジェクトを取得し、それに格納されているキー/値ペアを出力しています。

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Fetch JSON 8">
    <Require feature="opensocial-0.7"/>
  </ModulePrefs>
  <Content type="html">
  <![CDATA[
    <div id="content_div"></div>
    <script type="text/javascript">

    function makeJSONRequest() {    
      var params = {};
      params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
      // This URL returns a JSON-encoded string that represents a JavaScript object
      var url = "http://graargh.returnstrue.com/buh/fetchme.php";
      gadgets.io.makeRequest(url, response, params);
    };

    function response(obj) { 
      var jsondata = obj.data;
      var html = "<strong>Values: </strong><br /><br />";
      // Returned JS object can be processed as an associative array
      for (var key in jsondata) {    
        var item = jsondata[key];
        html += key + ": ";
        html += item + "<br />";
      }	   	    
      document.getElementById('content_div').innerHTML = html;
     };
     makeJSONRequest();
     </script>
  ]]>
  </Content>
</Module>

New JSON について

JSON (JavaScript Object Notation) は、特定のタイプのオブジェクト (キー/値ペアの配列およびコレクション) を交換しやすいデータにエンコードするためのデータ交換形式です。

ガジェット API には、オブジェクトを JSON 文字列にエンコードするための gadgets.json.stringify() メソッドと、JSON 文字列をオブジェクトに変換するための gadgets.json.parse() メソッドが用意されています。OpenSocial では、アプリケーション データを含め、返されるすべてのデータに対して自動的に HTML エスケープが実行されるため、解析前に appdata ストア内の文字列化された JSON オブジェクトをアンエスケープする必要があります。たとえば、gadgets.util.unescapeString(jsondata) のようにします。

この例では、まず JavaScript 配列を作成し、これを JSON 文字列としてエンコードしてから Array オブジェクトに変換し直しています。

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="JSON Example">
    <Require feature="opensocial-0.7"/>
  </ModulePrefs>
  <Content type="html">
  <![CDATA[
     <div id="content_div"></div>
     <script type="text/javascript">
     var html = "";
     // Create Array object
     var myfriends = new Array();
     myfriends[0] = "Touki";
     myfriends[1] = "Rowan";
     myfriends[2] = "Trevor";

     // Encode array as JSON string
     var jsonString = toJSON(myfriends);
     html += "The JSON string is " + jsonString + "<br />";
     html += "The type of jsonString is " + typeof(jsonString) + "<br />";

     // Convert JSON string back to an object
     var arr_obj = toObject(jsonString);
     html += "The type of arr_obj is " + typeof(arr_obj);
     document.getElementById('content_div').innerHTML = html;

     // Encode object as JSON string
     function toJSON(obj) { 
       return gadgets.json.stringify(obj); 
     }

     // Convert JSON string into an object
     function toObject(str) {
       return gadgets.json.parse(str);
    }
    </script>
  ]]>
  </Content>
</Module>

このガジェットからの出力は以下のようになります。

The JSON string is ["Touki","Rowan","Trevor"]
The type of jsonString is string
The type of arr_obj is object

Updated POST メソッドの使用

リモート コンテンツは、デフォルトでは GET メソッドでフェッチされます。コンテンツを POST メソッドでフェッチしたい場合は、POST_DATA パラメータを使用します。次に例を示します。

function makePOSTRequest() {
  var params = {};
  var postdata = {
    data1 : "test",
    data2 : 1234566
  };
  params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST;
  params[gadgets.io.RequestParameters.POST_DATA] = gadgets.io.encodeValues(postdata);
  var url = "http://graargh.returnstrue.com/buh/makerequest.php";
  gadgets.io.makeRequest(url, response, params);
};

function response(obj) {
  // do something
};

makePOSTRequest();

Updated 認可タイプの設定

ガジェット API では、以下の認可タイプがサポートされます。

  • gadgets.io.AuthorizationType.AUTHENTICATED (コンテナで完全な認証を実施する)
  • gadgets.io.AuthorizationType.SIGNED (コンテナが要求に署名する)
  • gadgets.io.AuthorizationType.NONE (デフォルト)

これらのメソッドの使用方法は、コンテナによって異なります。Orkut の場合の署名認可タイプの使用例も参考にしてください。

Updated 許可のコントロール

OpenSocial API では、アプリケーション内での許可のコントロールがサポートされています。アプリケーションがデータ要求を使用してサーバーからビューアをフェッチする際、アプリケーションにアクセス権がある場合にのみビューアが返されます。アプリケーションにアクセス権がない場合には、代わりに標準エラー コード opensocial.ResponseItem.Error.UNAUTHORIZED が返されます。新たに追加された opensocial.hasPermission 呼び出しを使用すると、アプリケーションにアクセス権があるかどうかを前もって確認できます。アクセスが拒否された場合は、opensocial.requestPermission を使用して指定の許可をビューアに要求できます。ビューアに常にアクセスを許可するコンテナや、常にアクセスを拒否するコンテナもありますが、この判断はコンテナ側で行います。

次に、この許可コントロール API を使用するコードの抜粋を示します。

/**
 * Request the VIEWER and OWNER objects
 */
function requestData() {
  var req = opensocial.newDataRequest();
  req.add(req.newFetchPersonRequest(opensocial.DataRequest.PersonId.OWNER), "owner");
  
  // If we have permission to see the viewer's info, then add it to the request.
  if (opensocial.hasPermission(opensocial.Permission.VIEWER)) {
    req.add(req.newFetchPersonRequest(opensocial.DataRequest.PersonId.VIEWER), "viewer");
  }
  req.send(showData);
}

function showData(data) {
  var viewer = data.get("viewer").getData();
  var owner = data.get("owner").getData();
  var ownerOutput = document.getElementById("owner-output");
  var viewerOutput = document.getElementById("viewer-output");

  showPerson(owner, ownerOutput);
  if (opensocial.hasPermission(opensocial.Permission.VIEWER)) {
    showPerson(viewer, viewerOutput);
  }
}

function requestPermission() {
  var reason = "To demonstrate permission capabilities";
  opensocial.requestPermission(opensocial.Permission.VIEWER, reason, requestData);
}

function showPerson(person, div) {
  var name = person.getDisplayName();
  var thumb = person.getField(opensocial.Person.Field.THUMBNAIL_URL);
  var html = '<img src="' + thumb + '"/>' + name; 
  div.innerHTML = html;
}

//Execute requestData when the page is done loading
gadgets.util.registerOnLoadHandler(requestData);

関連情報

OpenSocial API については、以下の資料も参考にしてください。

トップへ戻る