<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>roomanna.com</title>
    <link rel="alternate" type="text/html" href="http://roomanna.com/" />
    <link rel="self" type="application/atom+xml" href="http://roomanna.com/atom.xml" />
    <id>tag:roomanna.com,2008-07-25://1</id>
    <updated>2008-11-07T17:14:27Z</updated>
    
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Personal 4.12</generator>

<entry>
    <title>OpenSocial&apos;s first birthday party</title>
    <link rel="alternate" type="text/html" href="http://roomanna.com/2008/11/opensocials-first-birthday-par.html" />
    <id>tag:roomanna.com,2008://1.9</id>

    <published>2008-11-07T17:11:42Z</published>
    <updated>2008-11-07T17:14:27Z</updated>

    <summary><![CDATA[If anyone is heading to the OpenSocial Birthday party at MySpace next week, I'll be there to give a presentation on the OpenSocial Dev App and to talk to developers about getting their apps running on multiple containers.&nbsp; See you...]]></summary>
    <author>
        <name>Arne Roomann-Kurrik</name>
        
    </author>
    
        <category term="events" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-US" xml:base="http://roomanna.com/">
        <![CDATA[If anyone is heading to the <a href="http://opensocialapis.blogspot.com/2008/11/opensocials-first-birthday-detailed.html">OpenSocial Birthday party at MySpace</a> next week, I'll be there to give a presentation on the <a href="http://osda.appspot.com/">OpenSocial Dev App</a> and to talk to developers about getting their apps running on multiple containers.&nbsp; See you there! ]]>
        
    </content>
</entry>

<entry>
    <title>Presentation from DevFest Beijing</title>
    <link rel="alternate" type="text/html" href="http://roomanna.com/2008/11/presentation-from-devfest-beij.html" />
    <id>tag:roomanna.com,2008://1.8</id>

    <published>2008-11-06T19:53:36Z</published>
    <updated>2008-11-06T20:04:20Z</updated>

    <summary><![CDATA[In October, I was fortunate enough to be able to travel to Shanghai and Beijing for Google's DevFest developer events in those cities.&nbsp; Presenting OpenSocial to developers who hadn't had as much exposure to the technology was a refreshing challenge.&nbsp;...]]></summary>
    <author>
        <name>Arne Roomann-Kurrik</name>
        
    </author>
    
        <category term="presentations" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-US" xml:base="http://roomanna.com/">
        <![CDATA[In October, I was fortunate enough to be able to travel to Shanghai and Beijing for <a href="http://code.google.com/events/apacdevfest/">Google's DevFest developer events</a> in those cities.&nbsp; <br /><br />Presenting OpenSocial to developers who hadn't had as much exposure to the technology was a refreshing challenge.&nbsp; It made me look at our existing slide decks a bit more critically (especially since the slides were going to be translated) and I wound up creating a lot of content to explain the basic OpenSocial concepts.&nbsp; <br /><br />If you're a developer interested in OpenSocial but can't seem to find an overview of the entire technology stack (as of October 2008, at least), check out these slides - hopefully they'll give you some insight:<br /><br />

<div style="text-align: center;" id="__ss_686874"><a style="margin: 12px 0pt 3px; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block; text-decoration: underline;" href="http://www.slideshare.net/kurrik/open-social-tech-talk-beijing-presentation?type=powerpoint" title="Open Social Tech Talk   Beijing">Open Social Tech Talk   Beijing</a><object style="margin: 0px;" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=opensocial-tech-talk-beijing-1224823071621431-8&amp;stripped_title=open-social-tech-talk-beijing-presentation" /><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=opensocial-tech-talk-beijing-1224823071621431-8&amp;stripped_title=open-social-tech-talk-beijing-presentation" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></object><div style="font-size: 11px; font-family: tahoma,arial; height: 26px; padding-top: 2px;">View SlideShare <a style="text-decoration: underline;" href="http://www.slideshare.net/kurrik/open-social-tech-talk-beijing-presentation?type=powerpoint" title="View Open Social Tech Talk   Beijing on SlideShare">presentation</a> or <a style="text-decoration: underline;" href="http://www.slideshare.net/upload?type=powerpoint">Upload</a> your own. (tags: <a style="text-decoration: underline;" href="http://slideshare.net/tag/sns">sns</a> <a style="text-decoration: underline;" href="http://slideshare.net/tag/2008">2008</a>)</div></div>

<p><a href="http://www.slideshare.net/kurrik/opensocial-tech-talk-beijing-chinese-presentation/"><br /></a></p><p><a href="http://www.slideshare.net/kurrik/opensocial-tech-talk-beijing-chinese-presentation/">Here they are translated into Chinese</a>.&nbsp; My goal is to get some of the new images and diagrams into the official documentation soon.<br /></p>]]>
        
    </content>
</entry>

<entry>
    <title>Sending private messages on Friendster</title>
    <link rel="alternate" type="text/html" href="http://roomanna.com/2008/09/sending-private-messages-on-fr.html" />
    <id>tag:roomanna.com,2008://1.7</id>

    <published>2008-09-24T18:09:58Z</published>
    <updated>2008-09-24T18:24:23Z</updated>

    <summary><![CDATA[I had to write a quick sample today to send a private message to the OWNER on Friendster.&nbsp; The following sends a message to your Friendster message inbox:function sendNotification() { var params = {}; params[opensocial.Message.Field.TITLE] = "Title of the notification...]]></summary>
    <author>
        <name>Arne Roomann-Kurrik</name>
        
    </author>
    
        <category term="opensocial-0.7" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="samples" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="friendster" label="friendster" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://roomanna.com/">
        <![CDATA[I had to write a quick sample today to send a private message to the OWNER on Friendster.&nbsp; The following sends a message to your Friendster <a href="http://www.friendster.com/messages.php?folder=Inbox">message inbox</a>:<br /><br /><pre class="code">function sendNotification() {
  var params = {};
  params[opensocial.Message.Field.TITLE] =
      "Title of the notification goes here";
  params[opensocial.Message.Field.TYPE] =
      opensocial.Message.Type.PRIVATE_MESSAGE;
  var body="Text of the notification goes here";
  var message = opensocial.newMessage(body, params);
  var recipient = opensocial.DataRequest.PersonId.OWNER;
  opensocial.requestSendMessage(recipient, message,
      onSendNotification);
};

function onSendNotification(resp) {
  if (!resp.hadError() &amp;&amp; resp.getData().status == "sent") {
    alert("The message was sent to the OWNER");
  } else {
    alert("There was a problem: " + resp.getErrorMessage());
  }
};

sendNotification();<br /></pre>

Note the message type is set to <code>PRIVATE_MESSAGE</code>.&nbsp; Friendster also supports type <code>NOTIFICATION</code>, but I haven't quite figured out where that shows up, and I get a "Insufficient permissions for action 'publicMessage'" error message when trying <code>PUBLIC_MESSAGE</code>.<br /><br />Also note that this is for OpenSocial 0.7.&nbsp; If you're migrating this code to another container on 0.8, you'll need to change the IdSpec stuff (<a href="http://roomanna.com/2008/08/updating-your-apps-to-use-the.html">as I've covered before</a>).<br />]]>
        
    </content>
</entry>

<entry>
    <title>Fetch by ID sample</title>
    <link rel="alternate" type="text/html" href="http://roomanna.com/2008/09/fetch-by-id-sample.html" />
    <id>tag:roomanna.com,2008://1.5</id>

    <published>2008-09-03T07:42:07Z</published>
    <updated>2008-09-03T07:56:24Z</updated>

    <summary><![CDATA[I needed to write the following sample of code to test fetching people by ID number.&nbsp; This is an interesting sample because it demonstrates handling an error condition - namely, the "unauthorized" response that you should get when you try...]]></summary>
    <author>
        <name>Arne Roomann-Kurrik</name>
        
    </author>
    
        <category term="opensocial-0.7" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="samples" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-US" xml:base="http://roomanna.com/">
        <![CDATA[I needed to write the following sample of code to test fetching people by ID number.&nbsp; This is an interesting sample because it demonstrates handling an error condition - namely, the "unauthorized" response that you should get when you try to access an account that you don't have permission to request.&nbsp; On orkut, this means people who don't have your app installed, even if they're your friends.<br /><br />The following runs in <a href="http://roomanna.com/2008/08/introducing-dafos-quick-openso.html">DAfOS</a>:<br /><br /> <pre class="code">function onPersonGot(result) {
  var response = result.get("person");
  if (response.hadError()) {
    output("There was a problem fetching this user: " + 
        response.getErrorCode());
  } else {
    output("Fetched " + 
        result.get("person").getData().getDisplayName());
  }
  gadgets.window.adjustHeight();
};

function closeGetPerson(id) {
  return function() {
    var params = {};
    var req = opensocial.newDataRequest();
    req.add(req.newFetchPersonRequest(id, params), "person");
    req.send(onPersonGot);
  };
};


function closePrintFriend(list) {
  return function(friend) {
    var item = document.createElement("li");
    var link = document.createElement("a");
    var text = document.createTextNode(friend.getDisplayName());
    list.appendChild(item);
    item.appendChild(link);
    item.appendChild(document.createTextNode(" [" + 
        friend.getId() + "]"));
    link.appendChild(text);
    link.onclick = closeGetPerson(friend.getId());
    link.href = "javascript:void(0);";
  };
};

function gotFriends(data) {
  var friends = data.get("of").getData();
  var list = document.createElement("ul");
  var main = document.getElementById("dom_handle")
  main.innerHTML = "";
  main.appendChild(list);
  friends.each(closePrintFriend(list));
  gadgets.window.adjustHeight();
};

function getFriends() {
  var params = {};
  params[opensocial.DataRequest.PeopleRequestFields.MAX] = 1000;
  var req = opensocial.newDataRequest();
  req.add(req.newFetchPeopleRequest(
      opensocial.DataRequest.Group.OWNER_FRIENDS, params), "of");
  req.send(gotFriends);
};

getFriends();</pre>Note that the example lists the friends of the owner as links.&nbsp; Clicking on each name will attempt to retrieve that user by ID number.&nbsp; <br /><br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="fetch_by_ids_2.png" src="http://roomanna.com/2008/09/03/Picture%202.png" class="mt-image-none" style="" width="342" height="17" /></span><br /><br />On orkut, if a user doesn't have DAfOS installed, you'll get an "unauthorized" error:<br /><br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="fetch_by_ids_1.png" src="http://roomanna.com/2008/09/03/Picture%201.png" class="mt-image-none" style="" width="500" height="65" /></span><br />
<div><br />In your applications, make sure to handle cases like this, since you won't always be able to guarantee that all containers will have the same policies around which user accounts you may directly access.<br /></div><div><br /></div>]]>
        
    </content>
</entry>

<entry>
    <title>Updating your apps to use the IdSpec object in OpenSocial 0.8</title>
    <link rel="alternate" type="text/html" href="http://roomanna.com/2008/08/updating-your-apps-to-use-the.html" />
    <id>tag:roomanna.com,2008://1.4</id>

    <published>2008-08-23T00:43:15Z</published>
    <updated>2008-08-28T03:42:52Z</updated>

    <summary><![CDATA[Lately I've been updating some documentation to use version of 0.8 of the OpenSocial specification.&nbsp; If you've developed on the 0.7 version of the API, you'll probably be happy to see that not a lot of breaking changes have been...]]></summary>
    <author>
        <name>Arne Roomann-Kurrik</name>
        
    </author>
    
        <category term="opensocial-0.8" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="samples" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="idspec" label="idspec" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="opensocial08" label="opensocial-0.8" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://roomanna.com/">
        <![CDATA[Lately I've been updating some documentation to use version of 0.8 of the OpenSocial specification.&nbsp; If you've developed on the 0.7 version of the API, you'll probably be happy to see that not a lot of breaking changes have been introduced in the new version, with one major exception: the <code>IdSpec</code> object.<br /><br />In the past, when you wanted to specify a single person or a group of people, you would use one of the following:<br /><br />Single person specifiers (OpenSocial 0.7):<br /><ul><li><code>opensocial.DataRequest.Person.OWNER</code></li><li><code>opensocial.DataRequest.Person.VIEWER</code></li><li>A string representing the OpenSocial ID of a person.</li></ul>Multiple person specifiers (OpenSocial 0.7):<br /><ul><li><code>opensocial.DataRequest.Group.OWNER_FRIENDS</code></li><li><code>opensocial.DataRequest.Group.VIEWER_FRIENDS</code></li><li>An array of strings, each representing the OpenSocial ID of a person.</li></ul>In 0.8, the idea of an <code>IdSpec</code> object was introduced.&nbsp; <code>IdSpec</code> allows you to be much more expressive when specifying groups of people (including friends-of-friends, covered later) but introduces some additional complexity.&nbsp; Single person specifiers still use the <code>OWNER</code> and <code>VIEWER</code> objects, but these have been moved to the <code>opensocial.IdSpec.PersonId</code> namespace.<br /><br />To convert your app, update all functions that take a single person identifier to one of the following:<br /><ul><li><code>opensocial.IdSpec.PersonId.OWNER</code></li><li><code>opensocial.IdSpec.PersonId.VIEWER</code></li><li>A string representing the OpenSocial ID of a person.</li></ul>Note that only the following take a single person modifier: <br /><ul><li><code>opensocial.DataRequest.newFetchPersonRequest</code></li><li><code>opensocial.DataRequest.newUpdatePersonAppDataRequest</code></li><li><code>opensocial.DataRequest.newRemovePersonAppDataRequest</code>&nbsp; <br /></li></ul>The last two only accept the value of <code>opensocial.IdSpec.PersonId.VIEWER</code>, so this is a pretty straightforward change.<br /><br />Seleting a group of people requires a bit more of a code change, though.&nbsp; Where you might write something like this in OpenSocial 0.7:<br /><br />
<pre class="code">var params = {};
var req = opensocial.newDataRequest();
...
req.add(req.newFetchPeopleRequest(
    opensocial.DataRequest.Group.OWNER_FRIENDS, params);
req.send();
</pre>
Now you need to create an <code>IdSpec</code> instead:<br /><br />
<pre class="code">var params = {};
var idspec = opensocial.newIdSpec({ 
    "userId" : "OWNER", 
    "groupId" : "FRIENDS" 
});
...<br />req.add(req.newFetchPeopleRequest(
    idspec, params);
req.send();
</pre> 
You can actually create <code>IdSpec</code> equivalents to all of the old person/people identifiers:<br /><br />
<table class="tabular"><tbody>
  <tr><th>Identifier</th><th><code>IdSpec</code> code</th></tr>
  <tr><td><strong>OWNER</strong></td><td><pre class="code">var idspec = opensocial.newIdSpec({ 
    "userId" : "OWNER",  "groupId" : "SELF" 
});</pre></td></tr>
  <tr class="alt"><td><strong>VIEWER</strong></td><td><pre class="code">var idspec = opensocial.newIdSpec({ 
    "userId" : "VIEWER",  "groupId" : "SELF" 
});</pre></td></tr>
  <tr><td><strong>OWNER_FRIENDS</strong></td><td><pre class="code">var idspec = opensocial.newIdSpec({ 
    "userId" : "OWNER",  "groupId" : "FRIENDS" 
});</pre></td></tr>
  <tr class="alt"><td><strong>VIEWER_FRIENDS</strong></td><td><pre class="code">var idspec = opensocial.newIdSpec({ 
    "userId" : "VIEWER",  "groupId" : "FRIENDS" 
});</pre></td></tr>
</tbody></table>
<br />You can use these for the following functions:<br /><ul><li><code>opensocial.DataRequest.newFetchActivitiesRequest</code></li><li><code>opensocial.DataRequest.newFetchPeopleRequest</code></li><li><code>opensocial.DataRequest.newFetchPersonAppDataRequest</code></li></ul><br />The <code>IdSpec</code> object exposes some additional functionality like <code>NETWORK_DISTANCE</code> that I'll cover later, but for the time being, this should be enough information to get you to start porting your existing code to 0.8. <br /><br /><br />]]>
        
    </content>
</entry>

<entry>
    <title>Introducing DAfOS: Quick OpenSocial testing</title>
    <link rel="alternate" type="text/html" href="http://roomanna.com/2008/08/introducing-dafos-quick-openso.html" />
    <id>tag:roomanna.com,2008://1.3</id>

    <published>2008-08-20T19:38:14Z</published>
    <updated>2008-08-21T02:25:42Z</updated>

    <summary><![CDATA[When teaching myself the OpenSocial API, I found the standard "edit XML file" -&gt; "upload to server" -&gt; "reload gadget" process to be too slow for my liking, especially when working with code that was almost completely client-side JavaScript.&nbsp; A...]]></summary>
    <author>
        <name>Arne Roomann-Kurrik</name>
        
    </author>
    
        <category term="tools" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="dafostestingjavascripttools" label="dafos testing javascript tools" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://roomanna.com/">
        <![CDATA[When teaching myself the OpenSocial API, I found the standard "edit XML file" -&gt; "upload to server" -&gt; "reload gadget" process to be too slow for my liking, especially when working with code that was almost completely client-side JavaScript.&nbsp; <br /><br />A strength (or weakness, depending on who you ask) of JavaScript is that you can compile and execute JavaScript source code at runtime using the <code>eval</code> function.&nbsp; It made sense to create a simple gadget to help developers prototype simple OpenSocial calls, so I released CodeRunner, an OpenSocial application that let developers execute JavaScript snippets inside of a live OpenSocial container.&nbsp; These snippets could also be saved to AppData, which was convenient as long as you didn't run out of quota space (currently 10k on orkut and 1k on MySpace).<br /><br />CodeRunner wound up working quite well, but I wanted more space for storage, and I wanted to offer some capabilities that only a server-side solution would be able to satisfy.&nbsp; Because Google released their App Engine product around this time, I decided to turn CodeRunner into an App Engine application, called the Developer Application for OpenSocial, or DAfOS for short.<br /><br />You can get links to use DAfOS on different containers by visiting <a href="http://dafos.appspot.com/">dafos.appspot.com</a>.&nbsp; Eventually that site will be filled out with more documentation.&nbsp; <br />&nbsp;<br />Here's a shot of DAfOS in action (it looks a lot like CodeRunner at the moment):<br /><br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="DAfOS.png" src="http://roomanna.com/2008/08/20/Picture%202.png" class="mt-image-none" style="" height="250" width="600" /></span><br /><div><br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="DAfOS_execute.png" src="http://roomanna.com/2008/08/20/Picture%204.png" class="mt-image-right" style="margin: 0pt 0pt 20px 20px; float: right;" height="38" width="98" /></span>Samples are entered into the yellow input box.&nbsp; You can run a sample by clicking the "Execute" button in the top right hand corner of the gadget.&nbsp; The JavaScript entered in the box will execute as if it were part of the gadget itself.&nbsp; That means that you can execute social data queries, post Activity Stream entries, send messages, and anything else that the OpenSocial API allows.<br /><br />DAfOS also defines a method called <code>output</code>.&nbsp; Everything you pass to this method will be printed out in an output box at the bottom of the application.&nbsp; If you have <a href="http://getfirebug.com/">Firebug</a> installed (you really should!), then you'll see this output in Firebug's console, as well.<br /><br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="Picture 7.png" src="http://roomanna.com/2008/08/20/Picture%207.png" class="mt-image-none" style="" height="127" width="600" /></span><br /><br />Since DAfOS runs on App Engine, the samples are no longer stored in AppData.&nbsp; When you save a sample, it is actually hosted at dafos.appspot.com, and accessible by clicking on the name of the sample after you save it.&nbsp; This URL can be sent out to help supply code for reporting issues or helping other developers with problems.<br /><br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="DAfOS_controls.png" src="http://roomanna.com/2008/08/20/Picture%206.png" class="mt-image-none" style="" height="72" width="600" /></span><br /><br />Because I use DAfOS to write most of my samples, you'll be able to copy and paste most of the code snippets from this blog directly into DAfOS and watch them run.<br /><br />You can still use CodeRunner by installing <a href="http://opensocial-resources.googlecode.com/svn/samples/coderunner/trunk/coderunner.xml">this gadget XML spec</a> to a container, but there will not be any future development on it, meaning it will likely stop functioning once containers switch to OpenSocial 0.8<br /></div><div><br /></div>]]>
        
    </content>
</entry>

</feed>
