<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tender Surrender &#187; Widget</title>
	<atom:link href="http://devlog.agektmr.com/ja/archives/category/widget/feed" rel="self" type="application/rss+xml" />
	<link>http://devlog.agektmr.com</link>
	<description>未来のソーシャルウェブを夢見るブログ</description>
	<lastBuildDate>Tue, 10 Aug 2010 15:55:50 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>JA</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="http://superfeedr.com/hubbub"/>		<item>
		<title>FriendConnect向けあしあとガジェット公開とコード解説</title>
		<link>http://devlog.agektmr.com/ja/archives/325</link>
		<comments>http://devlog.agektmr.com/ja/archives/325#comments</comments>
		<pubDate>Wed, 07 Jan 2009 16:07:32 +0000</pubDate>
		<dc:creator>Eiji</dc:creator>
				<category><![CDATA[FriendConnect]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[OAuth]]></category>
		<category><![CDATA[OpenSocial]]></category>
		<category><![CDATA[SocialWeb]]></category>
		<category><![CDATA[Widget]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://devlog.agektmr.com/ja/?p=325</guid>
		<description><![CDATA[
topsyWidgetPreload({ "url": "http%3A%2F%2Fdevlog.agektmr.com%2Fja%2Farchives%2F325", "style": "big", "title": [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: left;margin-right: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fdevlog.agektmr.com%252Fja%252Farchives%252F325%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22FriendConnect%E5%90%91%E3%81%91%E3%81%82%E3%81%97%E3%81%82%E3%81%A8%E3%82%AC%E3%82%B8%E3%82%A7%E3%83%83%E3%83%88%E5%85%AC%E9%96%8B%E3%81%A8%E3%82%B3%E3%83%BC%E3%83%89%E8%A7%A3%E8%AA%AC%22%20%7D);"><script type="text/javascript">topsyWidgetPreload({ "url": "http%3A%2F%2Fdevlog.agektmr.com%2Fja%2Farchives%2F325", "style": "big", "title": "FriendConnect向けあしあとガジェット公開とコード解説" });</script></div>
<p><a href="http://devlog.agektmr.com/archives/310">FriendIntroducer</a>はFriendConnectを試すことに主眼を置いて作ったガジェットだったため、それほど実用的なものではありませんでした。そこで、本格的に使えるガジェットとして、MyBlogLogやgooあしあと、Yahooログール的ガジェットとしてFootprintsを作りました。</p>
<h2>Footprintsとは？</h2>
<p>Footprintsは、サイトメンバーの訪問を記録するガジェットです。百聞は一見にしかず、このブログの左ペイン一番下にあるガジェットをご覧ください。もしこのサイトのFriendConnectに登録していなければ、Joinしてみてください。ログインしていない場合はしてください。  <img width="223" height="211" class="alignnone size-full wp-image-326" title="Footprints1" src="http://devlog.agektmr.com/wp-content/uploads/2009/01/e38394e382afe38381e383a3-5.png" alt="Footprints1" />  ご想像通り、ログインした状態でブログを訪問すると、あしあととして訪問記録が残ります。ほかの人が見ると、どのくらい前に訪問したかが分かります。また、最近流行の(?)あしあとを消す機能も実装済みです。  ガジェットXMLは<a href="http://devlab.agektmr.com/OpenSocial/FriendConnect/Footprints.xml" target="_blank">http://devlab.agektmr.com/OpenSocial/FriendConnect/Footprints.xml</a>になりますので、欲しい方はご自由にお持ちください。貼り方は<a href="http://devlog.agektmr.com/archives/310">こちら</a>を参考にしてください。</p>
<h2>コードと動作の解説</h2>
<p>FriendConnectとはいえ、中身はただのOpenSocialガジェットです。<a href="http://www.amazon.co.jp/dp/4774137480/" target="_blank">OpenSocial本</a>も発売間近、<a href="http://developer.mixi.co.jp/appli/example" target="_blank">mixi</a>、<a href="http://home.goo.ne.jp/" target="_blank">gooホーム</a>のOpenSocial対応も近いということで、今回はサンプルコード付きでガジェットの内容を解説してみたいと思います。</p>
<h3>基本的な動作</h3>
<p>まず、あしあとの記録方式ですが、FriendConnectは残念ながら<strong>makeRequest未対応</strong>のため、外部サーバーのDBに保存、なんてことはできません。AppData(Persistent API)を使って保存しています。AppDataはガジェット+ユーザーの組み合わせごとに存在するのですが、残念ながらOWNERであるブログ自体のAppDataには保存できないことが判明しました。この辺りはPermissionが絡んでくるのですが、一般的なOpenSocialとは事情が異なるため、特殊な権限の割り振りになっていると思われます。  この問題を解決するために考えたのが、VIEWERごとに自分のAppData領域にデータを保存する、という技。OWNERの友達のAppDataをまとめて取得すれば、似たような状況が作れるはずです。今回はこの方式でうまく実現することができました。  つまり、1つのデータ領域に配列であしあとを記録して行くのではなく、メンバーごとに最終アクセス日時をあしあととして記録し、Persistent APIのnewFetchPeopleAppDataでメンバー全員分をまとめて取得しています。</p>
<h4>コード解説</h4>
<pre>
<pre class="brush: jscript;">
        init:function() {
          // データリクエストオブジェクトを生成
          var req = opensocial.newDataRequest();
          // 閲覧者(viewer)の情報を取得
         &nbsp;var params = {};
          params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = [opensocial.Person.Field.PROFILE_URL];
          req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER, params), 'viewer');
          // メンバー(OWNERの友達)のAppDataをまとめて取得
          var idspec = opensocial.newIdSpec({'userId':opensocial.IdSpec.PersonId.OWNER,
                                             'groupId':opensocial.IdSpec.GroupId.FRIENDS});
          req.add(req.newFetchPersonAppDataRequest(idspec, 'footprint'), 'footprint');

          // 上記2つの取得リクエストをまとめて投げ、callback関数で受け取ります
          req.send(function(response) {
            if (!response.get('viewer').hadError()) {
              fp.viewer = response.get('viewer').getData();
            }
            if (response.get('footprint').hadError()) {
              fp.footprints = [];
            } else {
              var footprints = response.get('footprint').getData();
              var exist = false;
              // AppDataはユーザーごとに返ってきますので、ループで回します
              $.each(footprints, function(footprint) {
                // AppDataは文字列しか受け付けませんので、取得時にJSONオブジェクトに戻してやります
                var json = gadgets.util.unescapeString(this.footprint);
                var foot = gadgets.json.parse(json);
                if (fp.viewer !== null) {
                  // 閲覧者と一致した場合は上書き
                  if (foot.id == fp.viewer.getId()) {
                    exist = true;
                    foot.id = fp.viewer.getId();
                    foot.name = fp.viewer.getDisplayName(),
                    foot.thumbnail = fp.viewer.getField(opensocial.Person.Field.THUMBNAIL_URL),
                    foot.profile = fp.viewer.getField(opensocial.Person.Field.PROFILE_URL),
                    foot.timestamp = (new Date()).getTime();
                    // 新しいあしあとをAppDataに記録
                    fp.setFootprint(foot);
                  }
                }
                fp.footprints.unshift(foot);
              });
              if (!exist &amp;&amp; fp.viewer !== null) {
                // 今まで一度もあしあとを記録したことがない人の場合、追加します
                var foot = {'id':         fp.viewer.getId(),
                            'name':       fp.viewer.getDisplayName(),
                            'thumbnail':  fp.viewer.getField(opensocial.Person.Field.THUMBNAIL_URL),
                            'profile':    fp.viewer.getField(opensocial.Person.Field.PROFILE_URL),
                            'timestamp':  (new Date()).getTime()};
                fp.footprints.unshift(foot);
                fp.setFootprint(foot);
              }
              // 時系列でソート
              fp.footprints.sort(function(a, b) {
                return b.timestamp - a.timestamp;
              });
              // レンダリングします
              fp.showFootprints();
            }
          });
        },
</pre>
</pre>
<p>ユーザーごとにAppDataを保存する部分は下記のコードです。</p>
<pre>
<pre class="brush: jscript;">
        setFootprint:function(foot) {
          // あしあとのデータオブジェクトを文字列に変換
          var str = gadgets.json.stringify(foot);
          var req = opensocial.newDataRequest();
          // 閲覧者のAppDataに記録
          req.add(req.newUpdatePersonAppDataRequest(opensocial.IdSpec.PersonId.VIEWER, 'footprint', str));
          req.send();
        },
</pre>
</pre>
<p>OpenSocial的に役立ちそうな部分のみ抜粋していますが、上記コードで基本的な動作を行っています。ソースコード全体を読みたい方は<a href="http://devlab.agektmr.com/OpenSocial/FriendConnect/Footprints.xml" target="_blank">こちら</a>から。</p>
<h2>まとめ</h2>
<p>FrienConnectの特殊な環境としては、前述のPermission問題。それからmakeRequestの問題が分かってきました。いずれもプライバシーの重要性に配慮した結果と思われます。  Permissionについては、一般的なSNS上のOpenSocialでは、VIEWER自身がガジェットをインストールしているかどうかで挙動が変わりますが、FriendConnectではOWNERが常に仮想人格であることから、そもそもその前提がなりたたないため、特殊な動きをしているようです。  makeRequestについては、技術的な問題は既に解決済みのはずですので、特殊なPermission下で取得されたプライバシーに関わるデータを外部サーバーに安易に保存されることを避ける狙いがあるのではないでしょうか？  何はともあれ、このガジェットを使うと、「ああ、ブログをコミュニティに変えるってこういうことなのか」と、(少しだけ)感じることができます。ぜひお試しください。</p>

]]></content:encoded>
			<wfw:commentRss>http://devlog.agektmr.com/ja/archives/325/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>OpenSocialアプリケーションを作る(2)</title>
		<link>http://devlog.agektmr.com/ja/archives/41</link>
		<comments>http://devlog.agektmr.com/ja/archives/41#comments</comments>
		<pubDate>Wed, 16 Apr 2008 17:37:50 +0000</pubDate>
		<dc:creator>Eiji</dc:creator>
				<category><![CDATA[OpenSocial]]></category>
		<category><![CDATA[Widget]]></category>
		<category><![CDATA[Gadget]]></category>
		<category><![CDATA[Orkut]]></category>

		<guid isPermaLink="false">http://devlog.agektmr.com/ja/?p=41</guid>
		<description><![CDATA[
topsyWidgetPreload({ "url": "http%3A%2F%2Fdevlog.agektmr.com%2Fja%2Farchives%2F41", "style": "big", "title":  [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: left;margin-right: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fdevlog.agektmr.com%252Fja%252Farchives%252F41%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22OpenSocial%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E4%BD%9C%E3%82%8B%282%29%22%20%7D);"><script type="text/javascript">topsyWidgetPreload({ "url": "http%3A%2F%2Fdevlog.agektmr.com%2Fja%2Farchives%2F41", "style": "big", "title": "OpenSocialアプリケーションを作る(2)" });</script></div>
<p><a rel="bookmark" href="http://devlog.agektmr.com/archives/22">OpenSocialアプリケーションを作る(1)</a>では、ガジェットの仕組みと、Orkutでアカウントを取得するところまで書きました。今回は、<a href="http://devlab.agektmr.com/OpenSocial/Orkut/FriendIntroducer.xml" target="_blank">前回紹介したアプリケーション</a>のコードを解説します。</p>
<p>このアプリケーション(FriendIntroducer)は、自分が見た場合は友達の紹介文を書くことができ、他人が見た場合はその人に向けて書かれた紹介文を読むことができる、というmixiなどにもよくある簡単なアプリケーションです。JavaScriptやjQuery的にはもっと賢い実装方法があると思いますが、今回はOpenSocialのコードにフォーカスしますので、アホなコードは大目に見てください。</p>
<h2>ガジェットXML</h2>
<pre>&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
&lt;Module&gt;
&lt;ModulePrefs title="Friend Introducer" title_url="" description="Introduce your friend!" height="100"&gt;
  &lt;Require feature="opensocial-0.7" /&gt;
  &lt;Require feature="views" /&gt;
  &lt;Require feature="dynamic-height" /&gt;
 &lt;/ModulePrefs&gt;
&lt;Content type="html" view="canvas"&gt;
  &lt;![CDATA[
  &lt;link href="http://devlab.agektmr.com/OpenSocial/css/FriendIntroducer.css" rel="stylesheet" type="text/css"&gt;
  &lt;script type="text/javascript" src="http://devlab.agektmr.com/OpenSocial/js/jquery.js"&gt;&lt;/script&gt;
  &lt;script type="text/javascript" src="http://devlab.agektmr.com/OpenSocial/js/FriendIntroducer.js"&gt;&lt;
/script&gt;
  &lt;script type="text/javascript"&gt;
    gadgets.util.registerOnLoadHandler(FriendIntroducer.init);
  &lt;/script&gt;
  &lt;div id="title"&gt;&lt;/div&gt;
  &lt;div id="friends"&gt;&lt;/div&gt;
  &lt;div id="message"&gt;&lt;/div&gt;
  ]]&gt;
 &lt;/Content&gt;
&lt;/Module&gt;</pre>
<p>ここでは</p>
<ul>
<li>ガジェットの設定</li>
<li>外部のCSSやJavaScriptを読み込み</li>
<li>初期化スクリプトの呼び出し</li>
<li>表示用DIV指定</li>
</ul>
<p>を行っています。</p>
<pre>&lt;Content type="html" view="profile"&gt;</pre>
<p>Contentはhtmlタイプ、profileビューと指定しました。typeにはhtmlとurlが選択可能ですが、htmlとして内容をContentタグで囲まれた部分に記述しています。viewはOpenSocialの仕様上profile、canvasが想定されていますが、コンテナによってhomeやpreviewが存在するようです。ここでは例としてcanvasを使用しています。</p>
<p>また、viewを指定しない場合はdefaultビューとして扱われます。コンテナは表示場面(コンテキスト)によってビューを切り替えますが、Content内でviewを取り出してJavaScriptで処理を分ける方法もあります。</p>
<h2>Contentの内容</h2>
<p>Contentの内容は、基本的に通常のウェブページと同じように扱うことができ、HTMLで書くことができますが、</p>
<pre>  &lt;script type="text/javascript"&gt;
    gadgets.util.registerOnLoadHandler(FriendIntroducer.init);
  &lt;/script&gt;</pre>
<p>このようにgadgets.util.registerOnLoadHandlerを使って初期化処理を入れることができます。</p>
<p>このアプリケーションでは、表示テンプレートとして空のdivタグを3つ用意しています。</p>
<h2>JavaScriptのコード</h2>
<p>JavaScriptのソースコードは<a href="http://devlab.agektmr.com/OpenSocial/js/FriendIntroducer.js" target="_blank">ここ</a>にありますが、抜粋して紹介します。</p>
<pre>    $('#friends').html('Requesting friends...');
    var req = opensocial.newDataRequest();
    req.add(req.newFetchPersonRequest('VIEWER'), 'viewer');
    req.add(req.newFetchPeopleRequest('VIEWER_FRIENDS'), 'friends');
    req.add(req.newFetchPersonAppDataRequest('VIEWER', 'Introduction'), 'intro');
    req.send(FriendIntroducer.onLoadViewerFriends);</pre>
<p>最も基本的な処理となる、閲覧者、閲覧者の友達、保存したデータを取り出す処理です。</p>
<p>opensocial.newDataRequest()でデータリクエストオブジェクトを作り、addで3種類のリクエストを追加、最後にsendでコールバック関数を指定した上、データリクエストを送信しています。3種類のリクエストにはそれぞれ後で区別するためviewer, friends, introという名前(キー)を付けています。</p>
<pre>   var viewer    = response.get('viewer').getData();
   var friends   = response.get('friends').getData();
   var intro     = response.get('intro').getData();</pre>
<p>コールバック関数では、引数(response)を使って、response.get(キー名).getData()でリクエストしていたデータを取り出すことができます。</p>
<pre>    var viewer_id = viewer.getId();
    var json = null;
    if (intro[viewer_id]) {
      if (intro[viewer_id].Introduction) {
        var json_str = gadgets.util.unescapeString(intro[viewer_id].Introduction);
        var json = eval(json_str)[0];
      }
    }</pre>
<p>introは、このアプリケーションを使ってコンテナのデータ保存領域に予め保存しておいた内容、つまり「以前保存した友達の紹介文」です。</p>
<pre>    $('#title').html('&lt;p&gt;Friends of '+viewer.getDisplayName()+':&lt;/p&gt;');
    var html = '';
    if (friends.size() == 0) {
      $('#message').html("&lt;p&gt;You don't have any friends yet!&lt;/p&gt;");
    }</pre>
<p>友達が誰もいない場合を考慮して、メッセージを表示しています。</p>
<pre>    friends.each(function(person) {
      var t = FriendIntroducer.template.friend_list_canvas;
      t = t.replace('##thumbnail_url##', person.getField(opensocial.Person.Field.THUMBNAIL_URL));
      t = t.replace('##profile_url##',   person.getField(opensocial.Person.Field.PROFILE_URL));
      t = t.replace('##display_name##',  person.getDisplayName());
      t = t.replace('##input_id##',      'input_'+person.getId());
      if (json) {
        t = t.replace('##intro_text##',  json[person.getId()] ? json[person.getId()] : '');
      } else {
        t = t.replace('##intro_text##', '');
      }
      html += t;
    });
    $('#friends').html('&lt;ul&gt;'+html+'&lt;/ul&gt;');</pre>
<p>OpenSocialでは配列をなめる、いわゆるiterationも仕様に含まれていて、eachを使うことができます。ここでは、友達のリストをループして、友達の名前やサムネイル画像、保存されていた紹介文をHTMLテンプレートに埋め込んでいきます。</p>
<p style="text-align: center;"><a href="http://devlog.agektmr.com/wp-content/uploads/2008/03/orkut5.jpg"><img title="Orkut5" src="http://devlog.agektmr.com/wp-content/uploads/2008/03/orkut5.jpg" alt="" width="300" height="264" /></a></p>
<p>ここまでで、友達の紹介文を書き込むことができるcanvasページの表示することができました。次に、友達の紹介文をユーザーが書き込んだものと想定し、投稿して保存するところまでを解説します。</p>
<h2>データの保存</h2>
<p>OpenSocialはコンテナにデータ保存領域を持っており、アプリケーションがデータを保存することができます。これはパーシステントデータ(Persistant data)や、アプリケーションデータ(AppData)と呼ばれています。アプリケーションデータはバージョン0.7では<strong>エスケープした文字列のみ</strong>サポートしています(次のバージョンではJSONそのものの保存も可能になるようです)。</p>
<pre>    var list = $('#friends ul li');
    var intro = "{result:[{";
    for (var i=0; i &lt; list.length; i++) {
      var textarea = list[i].lastChild.lastChild;
      var uid = textarea.id.substring(6);
      var intro_text = textarea.value.replace("'", "'");;
      intro += "'"+uid+"':'"+intro_text+"'";
      intro += (list.length-1)==i ? "" : ",";
    };
    intro += '}]};';
    var req = opensocial.newDataRequest();
    intro = gadgets.util.escapeString(intro);</pre>
<p>この処理は、ユーザーが友達の紹介文を書き終わって「投稿ボタン」を押すことでトリガーされるものです。DOMを辿って各友達のユーザーIDと紹介文の内容を取得する、普通のJavaScriptです。取得した内容はJSONの文字列になるよう連結し、エスケープすることで、アプリケーションデータとして保存が可能になります。</p>
<pre>    req.add(req.newUpdatePersonAppDataRequest('VIEWER', 'Introduction', intro));
    req.send(function() {
      $('#message').html('&lt;p&gt;Your introduction has been submitted.&lt;/p&gt;');
    });</pre>
<p>最後に、JSON形式になった文字列をデータリクエストオブジェクトに追加して送信して、完了です。</p>
<h2>まとめ</h2>
<p>解説というよりはソースコード並べただけみたいな記事になってしまいましたが、OpenSocialアプリケーションのほとんどがJavaScriptでできてしまうということは、分かったかと思います。次回は外部サーバーとの連携を行うmakeRequestに触れたいと思います。</p>

]]></content:encoded>
			<wfw:commentRss>http://devlog.agektmr.com/ja/archives/41/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FriendFeedのDashboard用ウィジェットを作ってみた</title>
		<link>http://devlog.agektmr.com/ja/archives/33</link>
		<comments>http://devlog.agektmr.com/ja/archives/33#comments</comments>
		<pubDate>Wed, 02 Apr 2008 17:30:24 +0000</pubDate>
		<dc:creator>Eiji</dc:creator>
				<category><![CDATA[Widget]]></category>
		<category><![CDATA[Dashboard]]></category>
		<category><![CDATA[FriendFeed]]></category>

		<guid isPermaLink="false">http://devlog.agektmr.com/ja/?p=33</guid>
		<description><![CDATA[
topsyWidgetPreload({ "url": "http%3A%2F%2Fdevlog.agektmr.com%2Fja%2Farchives%2F33", "style": "big", "title":  [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: left;margin-right: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fdevlog.agektmr.com%252Fja%252Farchives%252F33%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22FriendFeed%E3%81%AEDashboard%E7%94%A8%E3%82%A6%E3%82%A3%E3%82%B8%E3%82%A7%E3%83%83%E3%83%88%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%9F%22%20%7D);"><script type="text/javascript">topsyWidgetPreload({ "url": "http%3A%2F%2Fdevlog.agektmr.com%2Fja%2Farchives%2F33", "style": "big", "title": "FriendFeedのDashboard用ウィジェットを作ってみた" });</script></div>
<p><a href="http://devlog.agektmr.com/wp-content/uploads/2008/04/friendfeeder.jpg"></a><img class="alignnone size-medium wp-image-34" title="FriendFeeder" src="http://devlog.agektmr.com/wp-content/uploads/2008/04/friendfeeder.jpg" alt="" width="209" height="239" /></p>
<p>最近話題のFriendFeedに対応したMac OS XのDashboardウィジェット、FriendFeeder(仮称)を作ったので公開します。まだいっぱい不具合あると思うんですが、とりあえず動いてるので勢いで。</p>
<h2>FriendFeedとは？</h2>
<p><img class="alignleft alignnone size-medium wp-image-35" style="float: left;" title="friendfeedservices" src="http://devlog.agektmr.com/wp-content/uploads/2008/04/friendfeedservices-186x300.jpg" alt="" width="186" height="300" /></p>
<p><a href="http://friendfeed.com/" target="_blank">FriendFeed</a>は<a href="http://jp.techcrunch.com/tag/friendfeed/" target="_blank">TechCrunch</a>辺りで最近話題のウェブサービス。Twitterの次はコレと言われているものです。内容は一言で言うなら、<strong>SNSアグリゲータ</strong>。数多あるSNSをまとめあげるSNSといったところでしょうか。</p>
<p>SNSと言っても、FacebookのようなSNSそのものではなく、一般的なブログやTwitterやFlickr、Youtube、del.icio.us、Last.fmなど、SNSに類するサービスの最新情報をまとめる、ということに特化しています。エントリにコメントを付けたり、スター的な機能もあります。</p>
<h2 style="clear:left;">なぜFriendFeedがアツいのか？</h2>
<p>ずばり、このサービスが明らかにTwitterの存在を意識し、その延長線上にあるためです。</p>
<p>Twitterは今や多くの人のデスクトップ常駐アプリ/サービスになりました(僕はTwitterBoardというDashboardウィジェットを愛用してます)。面白いのは、Twitterという味気ないインターフェースのサービスが、多くのディベロッパーによって開発されたアプリ群によりバラエティを増しているという現象です。FriendFeedの味気ないインターフェースと充実したAPIはTwitterをヒントに、それ以上のものを目指していると思わずにはいられません。</p>
<p>もう一つ、Twitterを意識していると思える点は、コメント機能です。FriendFeedではTwitter上でのReplyを並べ替えて、会話の流れを分かりやすく表示してくれます。また、FriendFeed上でのコメントを、そのままTwitterにUpdateするオプションがあります。</p>
<p>そういう意味ではSNSアグリゲータというよりはむしろ、Twitter+αと言った方が適切かもしれません。少なくとも個人的には、そういう使い方がメインになりそう。</p>
<p><a href="http://devlog.agektmr.com/wp-content/uploads/2008/04/friendfeedscreen.jpg"><img class="alignnone size-full wp-image-36" title="friendfeedscreen" src="http://devlog.agektmr.com/wp-content/uploads/2008/04/friendfeedscreen.jpg" alt="" width="500" height="330" /></a></p>
<h2>ただのフィードアグリゲータではない</h2>
<p>これまでフィードアグリゲータといえばRSSリーダーだったわけですが、FriendFeedは単なるフィードアグリゲータではありません。それは<strong>認証認可</strong>を取り扱うからです。</p>
<p>通常RSSは一般公開されているものですので、特にプライバシーを気にする必要はありません。同じものを見る人が多数いることも想定されますから、キャッシュを用いることでかなりの効率化を図ることが出来ました。ところが、FriendFeedが扱う外部サービスにはGmailなど、認証を必要とするものも含まれます。これはつまり、ユーザーひとりにつき一回のフィードアクセスを要する、ということです。</p>
<p>これはTwitterの比ではない大仕事に思えます。ユーザーが増えれば増えるほど、どんどんしんどくなっていく。どんなアーキテクチャなんでしょうか？</p>
<h2>FriendFeedの今後</h2>
<p><span style="font-weight: normal; "><a href="http://jp.techcrunch.com/archives/adobe-air-desktop-app-for-friendfeed-coming/" target="_blank">Adobe AIRを使ったデスクトップアプリケーションがリリース</a>される予定とのこと。また、現在は規定されたサービスしか登録できませんが、サービス事業者が自らFriendFeedにAPIを作れる仕組みを用意するとか。</span></p>
<p>ユーザーインターフェースにバラエティがあって(API)、友達申請が気軽に出来る(Follow)という点を除いて、Facebookの方向性に近いのは偶然ではないでしょう。ソーシャルグラフの集約は既定路線ですが、どのパスを通って行くのが最も集客できるのか、興味深いところです。</p>
<h2>FriendFeederのダウンロードと使い方</h2>
<p>ようやく本題です(笑)</p>
<p style="text-align: center; "><a href="http://devlab.agektmr.com/DashboardWidget/FriendFeeder.zip"><strong>ダウンロードはこちら<br />
</strong></a><span style="color: #888888;"><strong>要Mac OS X 10.4.3以降のはず。</strong></span></p>
<h3>既知の不具合</h3>
<p>スクロールバーが出ないです！マウスホイール使ってください。</p>
<h3>使い方</h3>
<p>まずはFriendFeedでアカウントを取得してください。<br />
ウィジェットの裏面(設定画面)で自分のIDとRemote Keyを入力します(パスワードではありません)。Remote Keyは<a href="http://friendfeed.com/remotekey" target="_blank">http://friendfeed.com/remotekey</a>で取得できます。</p>
<h3>フィードバック</h3>
<p>今後コメント機能と、Twitter投稿機能の追加を検討しています。他にも何かあればこのエントリにコメントするか、<a href="http://twitter.com/agektmr" target="_blank">Twitter</a>で教えてください。</p>
<p>また、僕のFriendFeedアカウントは<a href="http://friendfeed.com/eiji" target="_blank">http://friendfeed.com/eiji</a>にありますので、Follow歓迎です。</p>

]]></content:encoded>
			<wfw:commentRss>http://devlog.agektmr.com/ja/archives/33/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>OpenSocialアプリケーションを作る(1)</title>
		<link>http://devlog.agektmr.com/ja/archives/22</link>
		<comments>http://devlog.agektmr.com/ja/archives/22#comments</comments>
		<pubDate>Sun, 30 Mar 2008 07:01:26 +0000</pubDate>
		<dc:creator>Eiji</dc:creator>
				<category><![CDATA[OpenSocial]]></category>
		<category><![CDATA[Widget]]></category>
		<category><![CDATA[Gadget]]></category>
		<category><![CDATA[Orkut]]></category>

		<guid isPermaLink="false">http://devlog.agektmr.com/ja/archives/22</guid>
		<description><![CDATA[
topsyWidgetPreload({ "url": "http%3A%2F%2Fdevlog.agektmr.com%2Fja%2Farchives%2F22", "style": "big", "title":  [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: left;margin-right: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fdevlog.agektmr.com%252Fja%252Farchives%252F22%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22OpenSocial%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E4%BD%9C%E3%82%8B%281%29%22%20%7D);"><script type="text/javascript">topsyWidgetPreload({ "url": "http%3A%2F%2Fdevlog.agektmr.com%2Fja%2Farchives%2F22", "style": "big", "title": "OpenSocialアプリケーションを作る(1)" });</script></div>
<p>OrkutとMySpaceで自作アプリを動かしてみたので、そのレポートです。</p>
<p>まだ仕様が固まっていないのでグレーな部分も多いのですが、OpenSocialはGoogleGadgetと相性が良いらしく、OrkutもMySpaceも、hi5もGoogleGadget前提となっています。というわけで、今回はGoogleGadgetの基本的な作り方とOrkutへのアプリケーション追加方法の解説です。</p>
<h2>ガジェットとは何か</h2>
<p>GoogleGadgetは<a href="http://www.google.com/ig?hl=ja" target="_blank">iGoogle</a>で動くJavaScriptとHTMLで記述された簡単なアプリケーションです。JavaScriptとHTMLはXML上に埋め込み、設定内容もXMLに記述します。</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
&lt;Module&gt;
 &lt;ModulePrefs
  title="Blah Blah Gadget"
  description="Gadget Example"
  author_email="***@***.com"
 &gt;
 &lt;/ModulePrefs&gt;
 &lt;Content type="html"&gt;
.....
 &lt;/Content&gt;
&lt;/Module&gt;</pre>
<p>XMLはこんな感じ。Contentの中にJavaScriptとHTMLを記述することで、その内容がiGoogle上やMySpace等のOpenSocialアプリケーションとして表示されます。</p>
<p>ガジェットはJavaScriptを許可していることから、XSSなどの脆弱性を回避するため、iframeを使って別ドメインで動作するようになっています(iGoogleの場合、gmodules.com)。Contentの属性であるtypeを&#8221;html&#8221;から&#8221;url&#8221;に変更し、hrefでURL指定すると、iframe内に自分の管理するサーバーを表示することも可能です。</p>
<p>GoogleGadget自体の仕様は掘り下げるとキリがないのでこの辺りで。詳細は<a href="http://code.google.com/intl/ja/apis/gadgets/docs/reference.html" target="_blank">リファレンス</a>をご覧ください。</p>
<h2>OrkutのSandboxアカウントを取得する</h2>
<p>OrkutはGoogle直結ということもあり、OpenSocialの仕様が最も早く反映されるようです。そのOrkutのOpenSocial実験環境は<a href="http://sandbox.orkut.com/" target="_blank">Sandbox</a>と呼ばれ、通常のOrkutアカウントを拡張したSandboxアカウントを取得することで、利用可能となります。</p>
<p>アカウントを取得するには<a href="http://code.google.com/support/opensocialsignup/">コチラ</a>から申請を行ってください。申請が受理されるまでには数日を要するようです。</p>
<h2>OrkutにOpenSocialアプリを追加する</h2>
<p>無事アカウントの取得ができたら、実際にアプリケーションを試すことができるようになります。ちなみに、どこかのサーバーにGoogleGadgetのXMLファイルを置いておく必要がありますので、Geocitiesでも何でもいいはずですので、ファイルをアップできるところを用意しておきましょう。</p>
<p><a href="http://devlog.agektmr.com/wp-content/uploads/2008/03/orkut1.jpg" title="Orkut1"><img src="http://devlog.agektmr.com/wp-content/uploads/2008/03/orkut1.jpg" alt="Orkut1" /></a><a href="http://devlog.agektmr.com/wp-content/uploads/2008/03/orkut1.jpg" title="Orkut1"> </a></p>
<p>Sandboxにログインするとこんな感じ。一見通常のログイン画面と変わりませが、一点だけ：</p>
<p><a href="http://devlog.agektmr.com/wp-content/uploads/2008/03/orkut2.jpg" title="Orkut2"><img src="http://devlog.agektmr.com/wp-content/uploads/2008/03/orkut2.jpg" alt="Orkut2" /></a></p>
<p>画面左にアプリケーションを追加するリンクがあります。クリックすると・・・</p>
<p><a href="http://devlog.agektmr.com/wp-content/uploads/2008/03/orkut3.jpg" title="Orkut3"><img src="http://devlog.agektmr.com/wp-content/uploads/2008/03/orkut3.jpg" alt="Orkut3" /></a></p>
<p>URLでXMLファイルを指定してアプリケーションを追加することが出来ます。(ちなみにアプリケーションディレクトリはいつもほとんどアプリがありません)</p>
<p>ここでは、僕の作ったアプリケーションで試してみましょう。URLに下記を入力します：</p>
<pre>http://devlab.agektmr.com/OpenSocial/FriendIntroducer.xml</pre>
<p>「アプリケーションを追加」ボタンを押すと、次の画面に遷移します。</p>
<h2><a href="http://devlog.agektmr.com/wp-content/uploads/2008/03/orkut4.jpg" title="Orkut4"><img src="http://devlog.agektmr.com/wp-content/uploads/2008/03/orkut4.jpg" alt="Orkut4" /></a></h2>
<p>ここでも「アプリケーションを追加」ボタンを押すことで、アプリケーションの追加が完了します。</p>
<p><a href="http://devlog.agektmr.com/wp-content/uploads/2008/03/orkut5.jpg" title="Orkut5"><img src="http://devlog.agektmr.com/wp-content/uploads/2008/03/orkut5.jpg" alt="Orkut5" /></a></p>
<p>こんな感じの画面が表示されたら成功。Orkut上に友達がいない方は、<a href="http://sandbox.orkut.com:80/Profile.aspx?uid=2129608995524995619" target="_blank">僕のアカウント</a>に友達申請してくれてもOKです。</p>
<p>ひとまず、第一回はここまで。</p>
<p><a href="http://devlog.agektmr.com/wp-content/uploads/2008/03/orkut4.jpg" title="Orkut4"> </a></p>

]]></content:encoded>
			<wfw:commentRss>http://devlog.agektmr.com/ja/archives/22/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Shindigのphp版を試す</title>
		<link>http://devlog.agektmr.com/ja/archives/11</link>
		<comments>http://devlog.agektmr.com/ja/archives/11#comments</comments>
		<pubDate>Mon, 17 Mar 2008 05:35:14 +0000</pubDate>
		<dc:creator>Eiji</dc:creator>
				<category><![CDATA[OpenSocial]]></category>
		<category><![CDATA[Widget]]></category>
		<category><![CDATA[Gadget]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Shindig]]></category>

		<guid isPermaLink="false">http://devlog.agektmr.com/ja/archives/11</guid>
		<description><![CDATA[
topsyWidgetPreload({ "url": "http%3A%2F%2Fdevlog.agektmr.com%2Fja%2Farchives%2F11", "style": "big", "title":  [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: left;margin-right: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fdevlog.agektmr.com%252Fja%252Farchives%252F11%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Shindig%E3%81%AEphp%E7%89%88%E3%82%92%E8%A9%A6%E3%81%99%22%20%7D);"><script type="text/javascript">topsyWidgetPreload({ "url": "http%3A%2F%2Fdevlog.agektmr.com%2Fja%2Farchives%2F11", "style": "big", "title": "Shindigのphp版を試す" });</script></div>
<p>先日のGoogleディベロッパー交流会でShindigのphp版が公開されていることを知り、試してみました。</p>
<h2>Shindigをチェックアウトする</h2>
<pre>&gt; svn co http://svn.apache.org/repos/asf/incubator/shindig/trunk .</pre>
<p>Shindigのソースがチェックアウトされます。(今回試したリビジョンは637739)</p>
<pre>&gt; ln -s ~/Development/Shindig/php/gadgets /Library/WebServer/Documents/gadgets</pre>
<p>これでローカルホスト上で見れるはず。ブラウザに下記のURLを入力します。</p>
<pre>http://localhost/gadgets/ifr?url=http://www.labpixies.com/campaigns/todo/todo.xml</pre>
<p><a href="http://devlog.agektmr.com/wp-content/uploads/2008/03/notfound.jpg" title="NotFound"><img src="http://devlog.agektmr.com/wp-content/uploads/2008/03/notfound.jpg" alt="NotFound" /></a><a href="http://devlog.agektmr.com/wp-content/uploads/2008/03/notfound.jpg" title="NotFound"> </a></p>
<p>見れません、、、</p>
<h2>httpd.confを修正</h2>
<p>どうやら、Mac OS X(Leopard)のhttpd.confのデフォルト 設定が邪魔している模様。</p>
<pre>/etc/apache2/httpd.conf</pre>
<p>を書き換えます。/etc/httpd/httpd.confではないことに注意。(Tigerはこれだった)</p>
<pre>&lt;Directory "/Library/WebServer/Documents"&gt;</pre>
<p>内の</p>
<pre>AllowOverride None</pre>
<p>を</p>
<pre>AllowOverride All</pre>
<p>に変更します。これでいけるはず。。。</p>
<p><a href="http://devlog.agektmr.com/wp-content/uploads/2008/03/todogadget.jpg" title="ToDoGadget"><img src="http://devlog.agektmr.com/wp-content/uploads/2008/03/todogadget.jpg" alt="ToDoGadget" /></a></p>
<p>できた！これで、色々いじれますよ・・・</p>

]]></content:encoded>
			<wfw:commentRss>http://devlog.agektmr.com/ja/archives/11/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenSocialの疑問がひとつ解決した</title>
		<link>http://devlog.agektmr.com/ja/archives/10</link>
		<comments>http://devlog.agektmr.com/ja/archives/10#comments</comments>
		<pubDate>Sat, 15 Mar 2008 14:02:43 +0000</pubDate>
		<dc:creator>Eiji</dc:creator>
				<category><![CDATA[OpenSocial]]></category>
		<category><![CDATA[Widget]]></category>
		<category><![CDATA[Gadget]]></category>
		<category><![CDATA[Orkut]]></category>

		<guid isPermaLink="false">http://devlog.agektmr.com/ja/archives/10</guid>
		<description><![CDATA[
topsyWidgetPreload({ "url": "http%3A%2F%2Fdevlog.agektmr.com%2Fja%2Farchives%2F10", "style": "big", "title":  [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: left;margin-right: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fdevlog.agektmr.com%252Fja%252Farchives%252F10%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22OpenSocial%E3%81%AE%E7%96%91%E5%95%8F%E3%81%8C%E3%81%B2%E3%81%A8%E3%81%A4%E8%A7%A3%E6%B1%BA%E3%81%97%E3%81%9F%22%20%7D);"><script type="text/javascript">topsyWidgetPreload({ "url": "http%3A%2F%2Fdevlog.agektmr.com%2Fja%2Farchives%2F10", "style": "big", "title": "OpenSocialの疑問がひとつ解決した" });</script></div>
<p><strong>前提：Google Gadgetでurlタイプを指定した場合、iframe内にはリモートサーバーの内容がそのまま表示されるため、Ajaxで友達情報等を取得しようとすると、ドメイン超えが必要となり、プロキシ経由でサーバー間通信となりRESTful APIがないと役に立たない</strong></p>
<p>どうやらOrkutでは、Content Type=&#8217;url&#8217;を許可していない模様。</p>
<p><a href="http://groups.google.com/group/opensocial-orkut/browse_thread/thread/f6de89397dc56576/70f57151180b87cb?lnk=gst&amp;q=content+type+url#70f57151180b87cb" target="_blank">MYSQL database connection using PHP for my gadget ? &#8211; Orkut Developer Forum | Google グループ</a></p>
<p>Content Type=&#8217;url&#8217;を指定すると404が返るらしい。 404が返ること自体はバグとのことですが、Content Type=&#8217;url&#8217;が動くようになったところで、ドメインを超えてOpenSocialを利用するにはプロキシを介したRESTful APIによるアクセスが必須であることは確認できました。これがRESTful APIが正式に登場するまでの暫定措置なのかどうかは未確認ですが、前提は誤っていなかったようです。</p>

]]></content:encoded>
			<wfw:commentRss>http://devlog.agektmr.com/ja/archives/10/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Googleディベロッパー交流会</title>
		<link>http://devlog.agektmr.com/ja/archives/9</link>
		<comments>http://devlog.agektmr.com/ja/archives/9#comments</comments>
		<pubDate>Sat, 15 Mar 2008 01:07:36 +0000</pubDate>
		<dc:creator>Eiji</dc:creator>
				<category><![CDATA[OpenSocial]]></category>
		<category><![CDATA[Widget]]></category>
		<category><![CDATA[Gadget]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Shindig]]></category>

		<guid isPermaLink="false">http://devlog.agektmr.com/ja/archives/9</guid>
		<description><![CDATA[
topsyWidgetPreload({ "url": "http%3A%2F%2Fdevlog.agektmr.com%2Fja%2Farchives%2F9", "style": "big", "title": " [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: left;margin-right: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fdevlog.agektmr.com%252Fja%252Farchives%252F9%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Google%E3%83%87%E3%82%A3%E3%83%99%E3%83%AD%E3%83%83%E3%83%91%E3%83%BC%E4%BA%A4%E6%B5%81%E4%BC%9A%22%20%7D);"><script type="text/javascript">topsyWidgetPreload({ "url": "http%3A%2F%2Fdevlog.agektmr.com%2Fja%2Farchives%2F9", "style": "big", "title": "Googleディベロッパー交流会" });</script></div>
<p>表参道のダイヤモンドホールで行われたGoogleディベロッパー交流会に参加してきました。今回はOpenSocialがテーマということで、ドンピシャ。 色々な疑問を解決することが出来ました。</p>
<h2>OpenSocialアプリケーション(ガジェット)はSNS間を持ち回れない？</h2>
<p>とても基本的な疑問ですが、。OpenSocialは異なるSNS間でAPIを共通化することで、アプリケーション開発者の負担を軽くすることが目的のため、互換性は保証されるものと考えていましたが、どうもそういう訳でもないらしい。<strong>なぜなら、OpenSocialはアプリケーションを乗せるもの(OrkutではGoogle Gadget)について規定していないから。 </strong></p>
<p>OpenSocialの仕様書を見ると、サンプルコードはすべてGoogle Gadgetを想定して書かれていますが、実際の仕様にGoogle Gadgetが要件であるとは書いていません。つまり、別にOpera WidgetだろうとYahoo! WidgetだろうとDashboard Widgetだろうと、乗せられるところに乗せてよい訳です。そこでこの辺りをはっきりさせるため、プレゼンをしてくれたクリスさん(ラストネームは忘れた)に聞いてみました。</p>
<ul>
<li>ガジェットはGoogle Gadgetのみを想定している訳ではない。</li>
<li>MySpaceAppやhi5、OrkutはGoogle Gadget形式で提供される(未確認)</li>
<li>アプリケーションは基本的にSNS間で共有できるが、拡張機能に対応していると、別のSNSでは動かない可能性もある。</li>
</ul>
<p>僕の拙い英語力だと、なんだか釈然としない答えしか得られませんでした。なんだかまだもやもや感が残ってますが、個人的にこう思ってます。</p>
<ul>
<li>ガジェットはGoogle Gadgetである必要はない</li>
<li>アプリケーション開発者は、コア機能は共通かできるが、ガジェット部分についてはSNSごとに用意する必要がある。</li>
</ul>
<h2>OpenSocialはRESTful APIの仕様が出るまで役に立たない?</h2>
<p>OpenSocialはSNSから友達の情報を取得できることが目玉な訳ですが、当然認証認可が必要になります。JavaScriptのAPIでは、単純にnewDateRequestを使って簡単に取得できるように書いてはありますが、コンテナ側の実装はそう単純ではありません。</p>
<p>Google Gadgetを前提とした場合、コンテンツタイプとして2つの選択肢があります。1つはGadget XML中にHTMLも記述するhtmlモード。もうひとつはGadget XML中にリモートURLを記述するurlモードです。htmlモードはGoogleの管理するgmodules.comというドメイン上で動作しますが、urlモードの場合は、サードパーティーの管理する全く別のドメインで動作することになります。察しの良い人はこの時点で気付くかと思います。</p>
<p><strong>リモートサーバーからOpenSocialのSNS情報にアクセスするには、そのリモートサーバーのプロキシを介して、SNSのRESTful APIを叩く以外、方法がない</strong></p>
<p>これは単純にAjaxがドメイン超えできないということに起因していますが、とても重要なこと。RESTful APIがまだ正式に用意されていないOpenSocialなだけに、これがないと使い物にならないんじゃないの？MySpaceのRESTful APIってなによ！？ OrkutのiLikeアプリってリモートじゃね！？という疑問が募ってしまったのでした。(あれ？AjaxってJavaScript自体の置いてあるドメインだったら直接リクエスト投げられるのか!?)</p>
<h2> Shindigについて</h2>
<p>先日インストールしたShindigですが、まだJavaしか対応していないものだとばかり思い込んでました。そしたら、Javaよりも実装は遅れているけど、PHPもあるというじゃないですか！！早速帰ってコードを見てみると、、、確かにありました。お作法がJavaっぽいのでアレレな感じですけど、PHPメインの僕にとってはありがたい発見。</p>
<h2>他にも</h2>
<ul>
<li>リクルートの方が作ったというShindigを使った<a href="http://beta.doko.jp/sandbox/" target="_blank">OpenSocial対応のドコイクβサービス</a></li>
<li><a href="http://commusuke.eisbahn.jp/" target="_blank">こみゅすけ</a>のOrkutアプリ版</li>
<li>OpenSocialアプリコーディング環境CodeRunner(Orkut上のアプリ)</li>
<li>Orkut上に<a href="http://sandbox.orkut.com/Community.aspx?cmm=47213793" target="_blank">OpenSocial Japanというコミュニティ</a></li>
</ul>
<p>などなど、、、子供がうるさいので今日はこの辺で。</p>

]]></content:encoded>
			<wfw:commentRss>http://devlog.agektmr.com/ja/archives/9/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
