Archive for 1月, 2009

1月 25 2009

SocialWeb勉強会 vol.1を開催しました

Published by Eiji under SocialWeb

1月23日に株式会社DeNAオフィスにて、SocialWeb勉強会 vol.1を開催しました。参加者は50名で、キャンセル待ちも出るほどの盛況ぶり。ソーシャルウェブの注目度の高まりを感じる勉強会となりました。

僕からのプレゼンテーションは、主催としてコミュニティの今後の方向性を示すと共に、現在の海外サービスで示されている方向性および、実際にメインプレイヤーたちがどういう形でソーシャルウェブ化に取り組んでいるかという状況を紹介しました。多くの内容は既にこのブログで紹介してきたものでしたが、いいまとめになったのではないかと思います。

スライドはSlideShareにアップしましたので、掲載しておきます。フォントが変わってしまって少々見づらい部分もあるかもしれませんが、ダウンロードもできますのでぜひご覧ください。

SocialWeb勉強会 Vol.1
View more presentations or upload your own. (tags: swj)

他にもよういちろうさんにOpenSocial導入のためのプレゼンテーション、id:ZIGOROuさんによる2009年のOpenIDの動向を紹介するプレゼンをしていただきました。詳しい内容は追ってこちらのページにアップされることと思います。ぜひチェックしてみてください。

最後に、会場を提供してくださったDeNAと、お手伝いしてくださったDeNA社員の皆様にお礼申し上げたいです。ありがとうございました。

追記:神部さんの飛び入り参加によるPaypal + OpenPNEのプレゼンについて書くのを忘れていました。僕のプレゼンの中でも触れた課金によるマネタイズにも絡む、実に興味深いお話でした。

再追記:PowerPointをPDFに変換してからSlideShareに再アップしたら、きれいに表示されるようになりました。

Comments add to hatena hatena.comment (9) add to del.icio.us (0) add to livedoor.clip (0) add to Yahoo!Bookmark (1) Total: 10

1月 12 2009

OpenSocial(Shindig)のサーバーアーキテクチャ

Published by Eiji under OpenSocial

OpenSocialと関わるには

  • コンテナになる
  • ガジェットを開発する
  • RESTを使ったクライアントサービスを作る

といった選択肢が考えられますが、そのいずれを選択するにしても、アーキテクチャについて知っておくことはとても重要です。特にガジェットを開発するに当たっては、アーキテクチャを知っていることでより開発しやすい場面が多々あります。

そこで今回は、OpenSocialに対応するコンテナのほとんどで利用されているオープンソースのリファレンス実装、Shindigのアーキテクチャについて解説したいと思います。

ガジェットとSNSの関係

iGoogle(既にShindigが利用されている)ではどうやって第三者の作ったガジェットを表示しているかご存知でしたか?実は、別ドメイン(iGoogleならgmodules.com)上にレンダリングしたガジェットを、iframe内に表示しているのです。

理由は、同ドメイン上に第三者の書いたJavaScriptを置くことは、セキュリティ上危険だからです。詳しくは以前Cajaについて解説した記事がありますので、そちらをご覧ください。

OpenSocial Gadget Rendering

APIはどこにあるか

OpenSocialにはPeople, Group, Activity, Persistentの4つのソーシャルなAPIが用意されていますが、それぞれRESTfulによるJSON, XML, AtomPub形式と、RPCによるJSON形式が用意されています。ShindigのJavaScript APIでは、この中でもRPCによるJSON形式が使用されています。

先ほど2つのドメインについて説明しましたが、JavaScriptのAPIということはAjaxなので、当然同じドメインということで、エンドポイントはShindigのドメイン上に存在します。

OpenSocial Server Architecture

ガジェット表示の流れ

基本的な構造が分かったところで、実際にガジェットを表示するまでの流れを見てみましょう。

どのガジェットを表示するのか

ガジェットを表示するためには、まずガジェットを表示したいというユーザーの意思が必要です。これはiGoogleであれば、ガジェットディレクトリから好きなガジェットを選び、自分のページを表示する、というサービス側での作業によって行われます。表示したいガジェットが分かったところで、サービス側もガジェットを表示するためのiframeを表示する必要があるため、ガジェットに関する情報を収集します。これはShindigのmetadata APIを使って行われます。

metadataの取得

metadata APIのリクエストを取得したShindigは、キャッシュを参照します。キャッシュにガジェットの情報が残っていない場合は、サービスからのリクエストに基づいてガジェットXMLを取得し、解析します。

iframeのレンダリング

ガジェットに関する情報を取得したサービスは、ガジェットを表示するためiframeをレンダリングします。これにより、iframe内にガジェットを表示するためのリクエストがブラウザからShindigに投げられます。

基本的にガジェットXMLに記述されたContentsの内容はそのまま表示されますが:

  • 指定されたガジェットのfeature(tabやminimessageなど、ガジェットが持つ機能セット)のJavaScriptがHTMLに追記される。
  • 設定によってはJavaScript、CSS、画像などのあらゆる外部コンテンツがShindig上にキャッシュして呼び出される。

という点は覚えておいて損はないでしょう。

これでガジェットの表示は完了です。Firebugなどを使ってAPIを試してみれば、Shindigにリクエストが飛んでいることが分かると思います。

外部サーバーを使うAPI

外部サーバーを使う際、JavaScript APIとしてgadgets.io.makeRequestが使用されます。コンテンツタイプとしてFEEDを選択すると、RSSやRDF、Atomを共通のフォーマットで返してくれたり、JSONを選択すると、データが返ってきた時点ですぐにJSONオブジェクトとして扱えるようになっています。

また、セキュリティ面でもいくつかの選択肢が用意されています。

  • 通常のリクエスト
  • Signed Request
  • OAuth

通常のリクエストは、特に認証等のかかっていないAPIに対して行われるものです。Signed Requestとは、OAuth Consumer Requestを指しており、これを利用することで、外部サーバーはガジェットからのリクエストのみを扱うことができるようになります。OAuthはOAuth Coreを指しており、外部サーバーはガジェットからのリクエストであることだけでなく、誰からのリクエストなのかをセキュアなクレデンシャルで認証した上で扱うことができるようになります。

OAuthについてはこの辺りこの辺りを参考にしてください。

ここで注意しなければならないのが、すべてShindigのproxyを介して行われるということです。先ほど書いた通り、ここでもGETリクエストには強力なキャッシュ機能が利用されるため、若干注意が必要な場合があります。キャッシュについては次回以降まとめて記事にしたいと思います。

Comments add to hatena hatena.comment (17) add to del.icio.us (0) add to livedoor.clip (2) add to Yahoo!Bookmark (0) Total: 19

1月 11 2009

Wordpressを多言語化するWP_Multilingual

Published by Eiji under Wordpress

前々からブログを多言語化したいと思っていたのですが、ちょうどよいプラグインを見つけたので入れてみました。

WP_Multilingualは多言語と言っても、自動翻訳などではなく、自分でそれぞれの言語向けに記事を書いて投稿しなければなりません。ただ、同 じ記事に複数言語を紐付けることができるうえ、リクエストヘッダで言語を自動振り分けしてくれます。これはまさに僕が探していた理想的機能。

ただ、Dean’s FCKEditorという日本語に優しくないエディタも一緒に入れなければならず、困り中。とりあえず、表示はおkてことで。早速この記事も英語版を投稿してみます。

Comments add to hatena hatena.comment (1) add to del.icio.us (0) add to livedoor.clip (0) add to Yahoo!Bookmark (0) Total: 1

1月 08 2009

FriendConnect向けあしあとガジェット公開とコード解説

FriendIntroducerはFriendConnectを試すことに主眼を置いて作ったガジェットだったため、それほど実用的なものではありませんでした。そこで、本格的に使えるガジェットとして、MyBlogLogやgooあしあと、Yahooログール的ガジェットとしてFootprintsを作りました。

Footprintsとは?

Footprintsは、サイトメンバーの訪問を記録するガジェットです。百聞は一見にしかず、このブログの左ペイン一番下にあるガジェットをご覧ください。もしこのサイトのFriendConnectに登録していなければ、Joinしてみてください。ログインしていない場合はしてください。 Footprints1 ご想像通り、ログインした状態でブログを訪問すると、あしあととして訪問記録が残ります。ほかの人が見ると、どのくらい前に訪問したかが分かります。また、最近流行の(?)あしあとを消す機能も実装済みです。 ガジェットXMLはhttp://devlab.agektmr.com/OpenSocial/FriendConnect/Footprints.xmlになりますので、欲しい方はご自由にお持ちください。貼り方はこちらを参考にしてください。

コードと動作の解説

FriendConnectとはいえ、中身はただのOpenSocialガジェットです。OpenSocial本も発売間近、mixigooホームのOpenSocial対応も近いということで、今回はサンプルコード付きでガジェットの内容を解説してみたいと思います。

基本的な動作

まず、あしあとの記録方式ですが、FriendConnectは残念ながらmakeRequest未対応のため、外部サーバーのDBに保存、なんてことはできません。AppData(Persistent API)を使って保存しています。AppDataはガジェット+ユーザーの組み合わせごとに存在するのですが、残念ながらOWNERであるブログ自体のAppDataには保存できないことが判明しました。この辺りはPermissionが絡んでくるのですが、一般的なOpenSocialとは事情が異なるため、特殊な権限の割り振りになっていると思われます。 この問題を解決するために考えたのが、VIEWERごとに自分のAppData領域にデータを保存する、という技。OWNERの友達のAppDataをまとめて取得すれば、似たような状況が作れるはずです。今回はこの方式でうまく実現することができました。 つまり、1つのデータ領域に配列であしあとを記録して行くのではなく、メンバーごとに最終アクセス日時をあしあととして記録し、Persistent APIのnewFetchPeopleAppDataでメンバー全員分をまとめて取得しています。

コード解説

        init:function() {
          // データリクエストオブジェクトを生成
          var req = opensocial.newDataRequest();
          // 閲覧者(viewer)の情報を取得
          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 && 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();
            }
          });
        },

ユーザーごとにAppDataを保存する部分は下記のコードです。

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

OpenSocial的に役立ちそうな部分のみ抜粋していますが、上記コードで基本的な動作を行っています。ソースコード全体を読みたい方はこちらから。

まとめ

FrienConnectの特殊な環境としては、前述のPermission問題。それからmakeRequestの問題が分かってきました。いずれもプライバシーの重要性に配慮した結果と思われます。 Permissionについては、一般的なSNS上のOpenSocialでは、VIEWER自身がガジェットをインストールしているかどうかで挙動が変わりますが、FriendConnectではOWNERが常に仮想人格であることから、そもそもその前提がなりたたないため、特殊な動きをしているようです。 makeRequestについては、技術的な問題は既に解決済みのはずですので、特殊なPermission下で取得されたプライバシーに関わるデータを外部サーバーに安易に保存されることを避ける狙いがあるのではないでしょうか? 何はともあれ、このガジェットを使うと、「ああ、ブログをコミュニティに変えるってこういうことなのか」と、(少しだけ)感じることができます。ぜひお試しください。

Comments add to hatena hatena.comment (6) add to del.icio.us (0) add to livedoor.clip (1) add to Yahoo!Bookmark (0) Total: 7

1月 06 2009

Google FriendConnect対応ガジェットが完成

Published by Eiji under FriendConnect

FriendConnectのメンバーが友達を紹介し合う文章が書けるFriend Introducerというガジェットを公開しました。このブログの画面左側に表示していますので、メンバーになってくれている方はぜひ、遊んでみてください。(なっていない方はメンバーになって遊んでください!)

FriendIntroducerとは

主に3つのビューが存在します。1つはブログ上で表示されるprofileビュー。

FriendConnect4

FriendConnectメンバーの紹介文を最大5件表示します。ページングが可能で、それぞれのメンバーに書かれた紹介文がランダムで表示されます。

メンバーのサムネイル画像をクリックするとdetailビュー(OpenSocial的なビューではないですけどね)に切り替わります。

FriendConnect5

一人に対して複数の人が紹介文を書いている場合がありますので、detailビューでは、その人に関する紹介文をすべて閲覧することができます。

ガジェット上部のボタンをクリックするとcanvasビューに切り替わります。

FriendConnect6

canvasビューでは、ログインユーザーの友達の紹介文を書くことができます。友達がいない方は、同じFriendConnect上の誰かを友達に加えてください。

FriendIntroducerをブログに貼付けるには

まずはこちらでFriendConnectに登録してください。サイト登録済みの状態で・・・

FriendConnect1

Social gadgetsをクリックします。

FriendConnect2

一番下にあるCustom gadgetリンクをクリックします。

FriendConnect3

Gadget URLをhttp://devlab.agektmr.com/OpenSocial/FriendConnect/FriendIntroducer.xmlとしてください。

ガジェットの横幅を調整し、Generate CodeをクリックするとHTMLコードが出力されますので、これをブログ等に貼付けます。

所感

以前のエントリにも書きましたが、FriendConnectガジェット作成のミソは:

  • OWNERはブログという仮想人格
  • requestNavigateToでcanvasビューとprofileビューを行き来できる
  • canvasビューのバックグラウンドは、サイト作成時に取り込んだcanvas.htmlをいじることで変更可能

といったところでしょうか。

今のところOpenSocialにコミュニティ的な考えはないのですが、FriendConnectはちょっとひねったコミュニティ的な応用、と思うと分かりやすいかもしれません。

また、FriendConnectの面白いところは、複数のSNSからインポートした友達リストをマージして利用できることです。例えば僕はorkut、Google、Plaxo、Twitterをインポートしていますが、同じブログに登録している人がこれらのSNS上で友達であれば、FriendConnect上でも友達になります。

いつかGoogleがiGoogleをSNS化する際、これらの友達リストがそのまま利用できるようになるかもしれませんね。

Comments add to hatena hatena.comment (2) add to del.icio.us (0) add to livedoor.clip (0) add to Yahoo!Bookmark (0) Total: 2