Google Code が利用できる言語: English - Español - 日本語 - 한국어 - Português - Pусский - 中文(简体) - 中文(繁體)
このガイドでは、OpenSocial アプリケーションの構築について解説します。このガイドを十分に活用するには、Gadgets API および JavaScript に関するある程度の知識が必要です。より詳しい情報を参照できるよう、他のドキュメントへのリンクも設定されています。
このガイドには、OpenSocial API の 0.7 更新時の変更点が反映されています。New!や Updated のマークは、コーディング方法が前のバージョンから変更されたことを示します。
OpenSocial アプリケーションをホストできるサイトを OpenSocial コンテナと呼びます。この OpenSocial コンテナで実行するアプリケーションは、単純にソーシャル アプリケーションと呼ばれています。
OpenSocial アプリケーションを記述するには、Javascript に関する実用的な知識が必要です。OpenSocial アプリケーションは、ガジェットとして構築します。そのため、ガジェットの構造、アプリケーションをソーシャル アプリケーションにする方法、および OpenSocial JavaScript API に関する知識が必要になります。ただし、RESTful API や RPC API の方が使いやすい場合は、これらを使用して OpenSocial アプリケーションを記述することも可能です。
コンテナの多くには、OpenSocial 仕様に定義されていない機能が含まれています。こうしたコンテナ固有の機能については、スタート ガイドに示されている各コンテナのドキュメントをご覧ください。また、多くのコンテナには、作成したガジェットを安全にテストするための環境 (サンドボックス) が用意されています。
OpenSocial API は、人に焦点を当てた API です。OpenSocial ガジェットを使用すると、ユーザー間でアクティビティを共有したり、友だちに関する情報にアクセスしたりできます。OpenSocial API の主な機能領域は以下の 3 つです。
OpenSocial API 呼び出しの多くは非同期です。つまり、呼び出しはすぐ返されますが、呼び出しが要求した処理はすぐには実行されません。代わりに、サーバー要求が作成され、これを使って情報を取得したり更新したりします。非同期呼び出しを行う場合は、コールバック関数を渡します。このコールバック関数は、サーバーからデータが返されるときに呼び出されます。
このセクションで説明する概念の詳細については、以下のドキュメントをご覧ください。
すべてのガジェットは、次のような構造になっています。
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Standard gadget structure">
</ModulePrefs>
<Content type="html">
<![CDATA[
Gadget content and features here
]]>
</Content>
</Module>
OpenSocial を使用するガジェットを作成する場合は、ModulePrefs セクションに次の行を追加する必要があります。
<Require feature="opensocial-0.8"/>
これにより、OpenSocial ガジェットの構造は次のようになります。
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Standard gadget structure">
<Require feature="opensocial-0.8"/>
</ModulePrefs>
<Content type="html">
<![CDATA[
Gadget content and features here
]]>
</Content>
</Module>
ここでは、友だちの名前を一覧表示する簡単な例について説明します。まず、OpenSocial API で定義されている以下の役割について理解する必要があります。
ここで説明する「友だちリスト」サンプルでは、閲覧者とその友だちをフェッチし、閲覧者の友だちの一覧を表示します。このサンプルに沿って、OpenSocial アプリケーションでデータをフェッチして操作する方法を説明します。基本的な手順は次のとおりです。
以降では、この手順について詳しく説明します。
まず、標準のガジェット仕様を構築してガジェットを作成します。
<?xml version="1.0" encoding="UTF-8" ?> <Module> <ModulePrefs title="List Friends Example"> <Require feature="opensocial-0.8"/> </ModulePrefs> <Content type="html"> <![CDATA[ <script type="text/javascript"> </script> <div id="message"> </div> ]]> </Content> </Module>
次に、アプリケーションのスケルトンを作成します。スケルトンは、ガジェットで使用する以下の 2 つの JavaScript 関数から構成されます。
request 関数。オーナーとその友だちを要求するために使用します。response コールバック関数。オーナーの友だちの名前で呼び出される関数です。
ここではこれらの関数のスタブを作成し、中身については後で定義することにします。アプリケーション スケルトンのもう 1 つの要素は、request 関数がアプリケーションのロード後に実行されるようにするための関数呼び出しです。
次にアプリケーション スケルトンを示します。
<script type="text/javascript">
/**
* Request the OWNER and OWNER's friends.
*/
function request() {
};
/**
* Parses the response and generates html to list the names of the owner and
* his or her friends.
*
* @param {Object} dataResponse Friend information that was requested.
*/
function response(dataResponse) {
};
// Execute the request function when the application is finished loading.
gadgets.util.registerOnLoadHandler(request);
</script>
次に、request 関数の中身を定義し、OpenSocial を呼び出してオーナーや友だちを取得できるようにします。この関数では以下を行います。
newIdSpec() を呼び出して idspec を作成します。opensocial.newDataRequest() を呼び出して、req 変数内に要求を作成します。req.add() を呼び出して、要求に newFetchPersonRequest() 関数と newFetchPeopleRequest() 関数を追加します。req.send() を呼び出して要求を開始します。その際、コールバック関数として response を渡します。newFetchPeopleRequest 関数を使用する場合は、IdSpec オブジェクトを作成して関数の引数として渡します。使用する IdSpec は、取得するデータによって異なります。次の表に、要求に応じた IdSpec オブジェクトの作成方法を示します。
| 要求の対象 | 使用するコード |
|---|---|
| VIEWER_FRIENDS |
var idspec = opensocial.newIdSpec({ "userId" : "VIEWER", "groupId" : "FRIENDS" });
|
| OWNER_FRIENDS |
var idspec = opensocial.newIdSpec({ "userId" : "OWNER", "groupId" : "FRIENDS" });
|
次に、request() 関数のコードを示します。
/**
* Request the OWNER and OWNER's friends.
*/
function request() {
var idspec = opensocial.newIdSpec({ "userId" : "OWNER", "groupId" : "FRIENDS" });
var req = opensocial.newDataRequest();
req.add(req.newFetchPersonRequest("OWNER"), "get_owner");
req.add(req.newFetchPeopleRequest(idspec), "get_friends");
req.send(response);
};
注: OpenSocial のフィールドやメソッドを表す JavaScript enum の省略表現として文字列リテラルを使用できます。たとえば、上の例では、
opensocial.IdSpec.PersonId.OWNER
と記述する代わりに
"OWNER"
と記述できます。各 enum にどの文字列が対応するかについては、JavaScript API リファレンスの enum に関するドキュメントをご覧ください。
newFetchPersonRequest および newFetchPeopleRequest の詳細については、OpenSocial でのデータの要求 をご覧ください。
ここでは、response 関数を構築します。サーバーから呼び出す response() 関数では、データ (オーナーとその友だち) を以下のように処理します。
dataResponse.get() を呼び出します。each() 関数を使用して、友だちのリストに対して繰り返し処理を行います。getDisplayName() は、友だちの名前を HTML 出力に追加するために呼び出します。person.getDisplayName() の呼び出しを繰り返し、その友だちの名前を HTML に追加します。document.getElementById('message').innerHTML = html を呼び出して、新しく作成した HTML にガジェットの innerHTML プロパティを追加します。
/**
* Parses the response and generates html to list the names of the owner and
* his or her friends.
*
* @param {Object} dataResponse Friend information that was requested.
*/
function response(dataResponse) {
var owner = dataResponse.get('get_owner').getData();
var friends = dataResponse.get('get_friends').getData();
var html = 'Friends of ' + owner.getDisplayName();
html += ':<br><ul>';
friends.each(function(person) {
html += '<li>' + person.getDisplayName() + '</li>';
});
html += '</ul>';
document.getElementById('message').innerHTML = html;
};
ここでは、これまでに示したコードを組み合わせて、友だちを一覧表示するサンプル コード全体を示します。response() 関数では、オーナーとその友だちを取得し、表示するオーナーの名前を HTML 文字列に挿入します。次に、友だちの処理を繰り返し、それぞれの友だちの名前を HTML に追加します。最後に、オーナーとその友だちの名前を追加した HTML を表示するため div タグに挿入します。
サンプル コード全体は次のようになります。
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="List Friends Example">
<Require feature="opensocial-0.8"/>
</ModulePrefs>
<Content type="html">
<![CDATA[
<script type="text/javascript">
/**
* Request the OWNER and OWNER's friends.
*/
function request() {
var idspec = opensocial.newIdSpec({ "userId" : "OWNER", "groupId" : "FRIENDS" });
var req = opensocial.newDataRequest();
req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.OWNER), "get_owner");
req.add(req.newFetchPeopleRequest(idspec), "get_friends");
req.send(response);
};
/**
* Parses the response and generates html to list the names of the owner and
* his or her friends.
*
* @param {Object} dataResponse Friend information that was requested.
*/
function response(dataResponse) {
var owner = dataResponse.get('get_owner').getData();
var friends = dataResponse.get('get_friends').getData();
var html = 'Friends of ' + owner.getDisplayName();
html += ':<br><ul>';
friends.each(function(person) {
html += '<li>' + person.getDisplayName() + '</li>';
});
html += '</ul>';
document.getElementById('message').innerHTML = html;
};
// Execute the request function when the application is finished loading.
gadgets.util.registerOnLoadHandler(request);
</script>
<div id="message"> </div>
]]>
</Content>
</Module>
OpenSocial API では、ユーザーごと、アプリケーションごとにデータを保存したり取得したりできます。ここで示すサンプル コードでは、以下の処理を行います。
data1 (0~5 の乱数)、data2 (0~100 の乱数)、data3 (現時点のタイムスタンプ) の 3 つの変数に格納します。data1 を AppField1 に、data2 を AppField2 に、data3 を AppField3 に保存します。次に、データを共有永続データに保存するコード スニペットを示します。
/**
* Generate 3 fields of random data and saves them to the persistent data store.
*
*/
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));
};
次に示すコードでは、格納したデータを以下の手順で取得しています。
newFetchPersonAppDataRequest 呼び出しを追加し、パラメータとしてキー名を渡します。 req.send を呼び出して、サーバーに要求を送信します。
/**
* Use newFetchPersonAppDataRequest() to read data from the store.
*
*/
function requestMyData() {
var req = opensocial.newDataRequest();
var fields = [ "AppField1", "AppField2", "AppField3" ];
var p = {};
p[opensocial.IdSpec.Field.USER_ID[]] = opensocial.IdSpec.PersonId.VIEWER;
var idSpec = opensocial.newIdSpec(p);
req.add(req.newFetchPersonAppDataRequest(idSpec, fields), "viewer_data");
req.send(handleRequestMyData);
}
ここで、このアプリケーションのコード全体を示します。3 つのフィールドに値を設定して格納した後、それらを取得しています。またこのコードでは、出力を構築するための関数を htmlout 変数に追加してから、その HTML 変数を div に追加して表示しています。
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Data Persistence Example" >
<Require feature="opensocial-0.8"/>
</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);
}
/**
* Handle responses from update person app data requests
*/
function handlePopulateMyAppData(data) {
if (data.hadError()) {
htmlout += data.getErrorMessage();
}
requestMyData();
}
/**
* Fetch app data
*/
function requestMyData() {
var req = opensocial.newDataRequest();
var fields = [ "AppField1", "AppField2", "AppField3" ];
req.add(req.newFetchPersonRequest(opensocial.IdSpec.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.getErrorMessage();
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);
アプリケーションにおいて、永続データからキーを削除したい場合もあります。キーとその値を削除するには、newRemovePersonAppDataRequest メソッドを使用します。
var req = opensocial.newDataRequest();
req.add(
req.newRemovePersonAppDataRequest("VIEWER", "myKey"),
"clear_data");
req.send(set_callback);
この要求を行うと、キー myKey とそれに格納されている値が永続データから削除されます。
このメソッドにキーの配列を渡すと、複数のキーをまとめて削除できます。
var req = opensocial.newDataRequest();
req.add(
req.newRemovePersonAppDataRequest("VIEWER", ["key1", "key2", "key3"]),
"clear_data");
req.send(set_callback);
この要求を行うと、キー key1、key2、key3 と、それぞれのキーに格納されている値が永続データから削除されます。
永続データのクリアの詳細については、永続性に関するドキュメントをご覧ください。
OpenSocial API を使用すると、アクティビティ ストリームを介して友だちとアクティビティを共有できます。アクティビティ ストリームとは、ユーザーのアクションを個別のエントリで表現したフィードです。アクティビティには、アプリケーションの状態の変更から映画のオンライン レビューの書き込みまで、ユーザーのあらゆるアクションが含まれます。
アクティビティの優先度を HIGH にするよう要求すると、アプリケーションがユーザーに対して、ユーザーの代わりにアクティビティを登録する許可を求めます (まだ許可を得ていない場合のみ)。アプリケーションによる登録が許可されていない場合、優先度を LOW にするよう要求しても、その呼び出しでは何も行われません。
newActivity を呼び出して新しいアクティビティを作成します。タイトルにするテキストを指定できます。requestCreateActivity を呼び出して、サーバーにアクティビティを送信します。その際、コールバック関数も渡します。次に、アクティビティを作成する簡単な例を示します。
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Activities - v0.8" >
<Require feature="opensocial-0.8"/>
</ModulePrefs>
<Content type="html">
<![CDATA[
<div id="content_div"></div>
<script type="text/javascript">
var div = document.getElementById('content_div');
/**
* Create the new activity and send it to the server.
*/
function postActivity(text) {
var params = {};
params[opensocial.Activity.Field.TITLE] = text;
var activity = opensocial.newActivity(params);
opensocial.requestCreateActivity(activity, opensocial.CreateActivityPriority.HIGH, callback);
div.innerHTML = "Activity title is: " + activity.getField(opensocial.Activity.Field.TITLE);
};
/**
* Server calls this function to indicate whether the activity post succeeded or failed.
*/
function callback(status) {
if (status.hadError())
{
alert("Error creating activity.");
}
else
{
alert("Activity successfully created.");
}
};
/**
* Start the process of posting an activity.
*/
function startActivity; {
postActivity("This is a sample activity, created at " + new Date().toString());
};
//Call startActivity as soon as the gadget finishes loading.
gadgets.util.registerOnLoadHandler(startActivity);
</script>
]]>
</Content>
</Module>
OpenSocial API では、アプリケーション内での許可のコントロールがサポートされています。アプリケーションがデータ要求を使用してサーバーから閲覧者をフェッチする際、アプリケーションにアクセス権がある場合にのみ閲覧者が返されます。アプリケーションにアクセス権がない場合には、代わりに標準エラー コード opensocial.ResponseItem.Error.UNAUTHORIZED が返されます。新たに追加された opensocial.hasPermission 呼び出しを使用すると、アプリケーションにアクセス権があるかどうかを前もって確認できます。アクセスが拒否された場合は、opensocial.requestPermission を使用して指定の許可を閲覧者に要求できます。閲覧者に常にアクセスを許可するコンテナや、常にアクセスを拒否するコンテナもありますが、この判断はコンテナ側で行います。
次に、この許可コントロール API を使用するコードの抜粋を示します。
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Checking for Permission" >
<Require feature="opensocial-0.8"/>
</ModulePrefs>
<Content type="html">
<![CDATA[
<h2>Owner:</h2>
<div id="owner-output">No data.</div>
<h2>Viewer:</h2>
<div id="viewer-output">No data.</div>
<script type="text/javascript">
/**
* Request permission for the VIEWER if the app does not have it.
*/
function requestPermission() {
if (opensocial.hasPermission(opensocial.Permission.VIEWER)) {
requestData();
} else {
var reason = "To demonstrate permission capabilities";
opensocial.requestPermission(opensocial.Permission.VIEWER, reason, onPermissionRequested);
}
};
/**
* Handle the response for the request for VIEWER information.
*/
function onPermissionRequested(response) {
if (response.hadError()) {
switch(response.getErrorCode()) {
case opensocial.ResponseItem.Error.NOT_IMPLEMENTED :
alert("Requesting permission is not implemented on this container.");
break;
default:
alert("There was a problem requesting permission: " + response.getErrorMessage());
break;
};
}
requestData();
};
/**
* Request the OWNER (and VIEWER if we have permission).
*/
function requestData() {
var req = opensocial.newDataRequest();
req.add(req.newFetchPersonRequest(opensocial.IdSpec.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.IdSpec.PersonId.VIEWER), "viewer");
}
req.send(showData);
};
/**
* Shows the response from the request for Person data.
*/
function showData(data) {
var owner = data.get("owner").getData();
var ownerOutput = document.getElementById("owner-output");
showPerson(owner, ownerOutput);
if (opensocial.hasPermission(opensocial.Permission.VIEWER)) {
var viewer = data.get("viewer").getData();
var viewerOutput = document.getElementById("viewer-output");
showPerson(viewer, viewerOutput);
}
}
/**
* Prints information about a person.
*/
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(requestPermission);
</script>
]]>
</Content>
</Module>
OpenSocial API については、以下の資料も参考にしてください。
| 改訂 | 更新日 | 説明 |
|---|---|---|
| OpenSocial 0.8.1 | 2008 年 9 月 | ほとんどのセクションを更新。Require 文を 0.8 に変更。アクセスの例で IdSpec を使用。永続データの消去に関する情報を追加。許可の例を更新。 |
| OpenSocial 0.7 | 2008 年 4 月 | 新規ドキュメント。 |