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

12月 10 2008

FriendConnect実験中

Published by Eiji under FriendConnect, Google, OpenSocial

本ブログ左サイドバーの下の方に、Friend Introducerという以前作ったOpenSocialガジェットをFriendConnect用に若干修正して追加してみました(2008/12/9時点)。

元々このガジェットは、キャンバスビューで自分の友達の紹介文を書き、プロフィールビューでその人に書かれた紹介文が読める、というものです(コードはかなりいい加減ですが)。

しかし今回FriendConnectでガジェットを試して明確に分かったことがいくつか。

  • ビューはprofileまたはcanvasから選択。FriendConnectのSocialGadget設定画面で決めることができます。
  • friendconnectフィーチャーというものがあるようです。具体的に何をするものなのかは不明。
  • Ownerはサイト。そういえば、FriendConnectガジェットを入れた時点では、自動的に自分がメンバーになったりはしていませんでした。Ownerは貼付けたサイトという仮想人格が担うようです。

ビューに関しては、profileビューにするとサイトがオーナーとして表示されるので、よくわからない状態。プロフィールを取るとどうなるかも未検証です。現在はcanvasビューで表示していますが、自分で自分の友達の紹介文を書くだけで、誰にも見せられないというしょーもないものになっています(–;。

そういえば他のFriendConnectガジェットは右上にキャンバスビューに移行するボタンがありますね。どうやってこれを使うことができるんでしょう?時間があるときにでも追いかけてみたいと思います。

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

5月 14 2008

SNSのオープン化

Published by Eiji under DataPortability

SNSをオープン化する動き

Facebookの開発者向けプラットフォーム公開に始まったSNSのオープン化は、さらに加速度を増しています。Facebookの対抗と言わんばかりに登場したGoogle主導のOpenSocial。Facebookが自社サービスをプロプライエタリな基盤にする動きであったのに対し、Googleはその他大勢の連合を擁して、基盤の標準といえる規格を作りました。

両者のこの動きは、外部サービスをSNSの一部であるかのように取り込むという意味で共通しています。

SNSアグリゲートサービス

日本でSNSというとmixiを代表とした日記交換サイトがイメージされがちですが、Twitterのように一方通行の「Follow」が可能なものや、Flickr、Lastfm等のジャンルに特化したものもSNSと呼ぶことができます。

最近FriendFeedのように、こういった各種SNSをアグリゲートすることに特化したサービスも登場してきました。サービスに各種SNSのIDを預けることで、フィードのアグリゲーションが行われ、ユーザーはそのサイトさえ追いかけていれば必要な時だけ連携サービスを見に行くことができるようになります。

このように、ウェブの求める方向性はSNSの登場以降、IDがウェブ上のあちこちにあったとしても、使っている本人は一人であり、友達も同じなのだから、まとめちゃえばいいじゃん、にシフトしてきています。

DataPortability

DataPortabilityはそんな各SNSサービスに囲い込まれつつあるデータを解放して相互に利用できるようにしよう、という動きです。


DataPortability – Connect, Control, Share, Remix from Smashcut Media on Vimeo.

DataPortability – Join The Conversation from Smashcut Media on Vimeo.

詳細は僕もつかみきれていませんが、MySpaceのData Availability, FacebookのFacebook Connect, GoogleのFriend Connectと役者が揃ってきました。それぞれがどういう特徴を持っているのかを、追って紹介していきます。

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