编写社交应用程序
可托管 OpenSocial 应用程序的站点称为 OpenSocial 容器。社交应用程序只是在 OpenSocial 容器上运行的应用程序。
要编写 OpenSocial 应用程序,您需要了解 JavaScript 的工作知识。OpenSocial 应用程序会作为小工具进行构建,因此您需要了解小工具如何构建,如果要想让您的应用程序用于社交网络,则您需要了解 OpenSocial JavaScript API。(如果您愿意,可使用 RESTful 或 RPC API 编写 OpenSocial 应用程序。)
许多容器提供了可能要在您的小工具中使用的 OpenSocial 规范之外的功能。要了解有关这些容器特有的功能的更多信息,请查看在《使用入门指南》中列出的容器文档。此外,许多容器提供名为沙盒的测试环境,您可在其中安全测试您的小工具。
OpenSocial API 主要针对用户。OpenSocial 小工具可帮助用户相互共享各自的活动,并访问有关好友的信息。在 OpenSocial API 中有三个主要功能区:
- 用户和关系。社交网络的成员都有好友。OpenSocial 应用程序会使用用户及其好友之间的连接。
- 持久化存储。OpenSocial 应用程序可充分利用持久化存储,这是用来存储应用程序在以后再次运行时可以检索到的数据的功能。
- 活动。用户可使用社交应用程序告知其他人自己正在做什么,比如正要观看影片、张贴照片等等。
许多 OpenSocial API 调用都是异步的:也就是说,调用会立即返回,但是调用请求的操作却不会立即发生。而且,调用会创建服务器请求以检索或更新信息。当进行异步调用时,您会传入回调函数。当数据从服务器返回时,OpenSocial 会调用您的回调函数。
有关本节所述概念的更多信息,请参阅以下文档:
更新导入 OpenSocial Library
每个小工具都有以下结构:
<?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>
创建应用程序结构
接下来,我们创建应用程序的结构。这包括我们将在小工具中使用的两种 JavaScript 函数:
request
函数,我们将使用该函数寻找所有者和所有者的好友。response
回调函数,OpenSocial 进行调用,参数中含有所有者好友的姓名。
我们将在这里为这些函数创建存根,后面的章节中会进行详细介绍。应用程序结构的最后元素是函数调用,用于确保在应用程序加载后执行 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);
};
注意:您可以使用作为 JavaScript 枚举(代表 OpenSocial 字段和方法)的缩写的字符串文字。例如,不用编写
opensocial.IdSpec.PersonId.OWNER
您只需编写
"OWNER"
(如以上示例中所示)。要查找与枚举相对应的字符串,请参阅有关 JavaScript API 参考中的枚举的文档。
有关 newFetchPersonRequest
和 newFetchPeopleRequest
的更多信息,请参阅文章请求 OpenSocial 中的数据。
构建响应
在该节中,我们将构建 response
函数。服务器调用 response()
以处理数据 -- 所有者和所有者的好友,如下所示:
- 创建所有者和好友变量,并调用
dataResponse.get()
来使用服务器返回的值初始化这些变量。 - 开始创建包含所有者和好友姓名的 HTML。
- 通过使用
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
:当前时间戳。 - 将数据保存到查看者的个人资料,在 AppField1 下保存
data1
,在 AppField2 下保存data2
,在 AppField3 下保存data3
。 - 发送请求。
该代码段显示了将数据保存到共享持久化数据中的方式:
/**
* 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);
}
此处是应用程序的完整代码,它会设置、存储并检索这三个字段的值。该列表还会添加函数以在 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(对所有包括应用程序数据的返回数据进行编码),所以必须在解析它们之前对持久化数据中字符串化的 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 使您可以通过活动流与好友共享活动。活动流是一种供稿,其中的每个条目都表示用户执行的操作。活动可以是任何形式(从修改应用程序状态到编写电影的在线评论)。
如果请求高活动优先级,则当应用程序没有有许可时,应用程序会要求用户提供其代表用户发布活动的许可。如果请求低优先级,则当应用程序没有发布许可时,该调用无效。
- 调用
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());
};
//CallstartActivity
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 文章和教程。
- 有关参考信息,请参阅 OpenSocial JavaScript API 参考。
- 如果您正在开发特定容器所专用的应用程序,则请查看该容器的站点。《使用入门指南》包含有指向所有容器站点的链接。
- 最后,请务必访问开发人员论坛以获得支持和通告。
修订历史记录
修订 | 更新 | 说明 |
---|---|---|
OpenSocial 0.8.1 | 2008 年 9 月 | 大部分章节均已更新。Require 语句已更改为 0.8。访问示例现在使用 IdSpec 。已添加了有关清除持久化数据的信息。已更新了权限示例。 |
OpenSocial 0.7 | 2008 年 4 月 |
新文档。
|