My favorites | 中文(简体) | Sign in

OpenSocial API 开发人员指南

(OpenSocial API v0.8.1)

该指南将帮助您构建 OpenSocial 应用程序。为充分利用该指南,您应当对小工具 API 和 JavaScript 有一定的了解。该指南还提供了指向其他含有更多信息的文档的链接。

该指南已进行了修改,以反映 OpenSocial API 0.7 版更新所进行的更改。章节标记为新增!更新来帮助您识别相对于上个版本而进行更改的编码实例。

目录

  1. 编写社交应用程序
  2. 导入 OpenSocial Library
  3. 访问用户和个人资料
    1. 获取基本信息
    2. 列出好友的完整代码
  4. 使用持久化数据
  5. 发布活动
  6. 许可控制
  7. 了解更多

更新编写社交应用程序

可托管 OpenSocial 应用程序的站点称为 OpenSocial 容器社交应用程序只是在 OpenSocial 容器上运行的应用程序。

要编写 OpenSocial 应用程序,您需要了解 JavaScript 的工作知识。OpenSocial 应用程序会作为小工具进行构建,因此您需要了解小工具如何构建,如果要想让您的应用程序用于社交网络,则您需要了解 OpenSocial JavaScript API。(如果您愿意,可使用 RESTfulRPC 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 应用程序中的数据。基本步骤如下:

  1. 构建小工具规范。
  2. 创建应用程序结构。
  3. 构建请求。
  4. 构建响应。

下面将详细讨论这些步骤。

构建小工具规范

我们通过构建标准小工具规范来开始创建小工具:

<?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 参考中的枚举的文档。

有关 newFetchPersonRequestnewFetchPeopleRequest 的更多信息,请参阅文章请求 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);

当进行该请求时,密钥 key1key2key3 以及它们存储的值都会从持久化数据中删除。

有关清除持久化数据的更多信息,请参阅有关持久化存储的该文章

更新活动

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());
  };

  //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 月 新文档。