速攻で作る OpenSocialアプリ

新年明けましておめでとうございます。

mixiアプリも採用の Open Social

日本最大のSNSである mixiが mixiアプリ にOpen Socialを採用したことにより、今年2009年は他社のサービスでもOpenSocialを採用するところが一気に増えてくるではないでしょうか。

そこで弊社Banana Systemsが2009年最初にお届けする記事は「速攻で作るOpenSocialアプリ」です。

OpenSocialの詳細につきましては、オフィシャル・ページ にて説明されていますのでここでは割愛します。

まず前提として、

Orkut用のソーシャル・アプリ
  今現在 mixiアプリはまだβ版であり一般には公開されていませんので、
  GoogleのSNSであるOrkutにてソーシャル・アプリを開発します。

自社サーバからデータの取得、保存
  HTML, Javascriptのみを用いたシンプルなソーシャル・アプリではなく、
  実際のサービスを考えた時には外部(自社)サーバからコンテンツ、
  データの取得、また逆に保存を行いますので、↓のような形式とします。
  外部サーバ <-> Orkut(OpenSocialコンテナ) <-> ソーシャル・アプリ

OpenSocial Client Libraryの使用
  2008年12月17日に OpenSocial Blog にてPHP, Java, Ruby, Python用のOpenSocial Client Library が発表されました。
  このライブラリはサーバ間(外部サーバ <-> OpenSocialコンテナ)通信の複雑なやり取りを隠ぺいしてくれます。
  Ruby用のものには Railsアプリのサンプルが入っていますので、今回はそのRailsアプリを動作させるまでを説明します。

OpenSocialアプリの構築

それでは始めていきましょう!

Getting started with the Ruby Client Library に大まかな説明がされているので、それに沿って進めていきますが、Orkut(OpenSocialコンテナ)から外部サーバへ通信する際に必要となるSigned 通信の設定方法が記述されていなかったり、migration
ファイルに誤りがありそのままでは動作しませんので、補足しながら説明していきます。

1. 必要なライブラリのインストール

 # gem install oauth json mocha rails

2. opensocial ライブラリのダウンロードとインストール

 ダウンロード ページ からopensocial-X.X.X.gem をダウンロードします。

 ダウンロードしたgemをインストールします。

 # gem install opensocial-X.X.X.gem

3. サンプルの Railsアプリのダウンロード

 ダウンロード ページ から gifts_sample_X.X.zip をダウンロードします。

 ダウンロードしたzipファイルを展開すると gifts_sampleディレクトリ(Railsアプリのトップ)が作成されますので、Railsアプリを設置する適切なディレクトリに移動してください。

4. DB設定

 GIFT_SAMPLE/config/database.ymlの設定を適切なものに変更し、DBにデータベースを作成してください。
 ※GIFT_SAMPLE は 当Railsアプリのトップディレクトリとします。

今回はMySQLを使用しました。
※database, username, password はサンプルですので適宜変更してください。

development:
  adapter: mysql
  encoding: utf8
  database: gifts_development
  pool: 5
  username: banana
  password: banana
  host: localhost

test:
  adapter: mysql
  encoding: utf8
  database: gifts_test
  pool: 5
  username: banana
  password: banana
  host: localhost

production:
  adapter: mysql
  encoding: utf8
  database: gifts_production
  pool: 5
  username: banana
  password: banana
  host: localhost

MySQL コンソールにて ( GRANT文は適宜変更してください )

> GRANT ALL PRIVILEGES ON *.* TO banana@localhost IDENTIFIED BY 'banana' WITH GRANT OPTION;
> flush privileges;
> create gifts_development DEFAULT CHARSET=utf8;
> create gifts_test DEFAULT CHARSET=utf8;
> create gifts_production DEFAULT CHARSET=utf8;

5. migrationファイルの修正

 GIFT_SAMPLE/config/20081201192139_create_gifts.rb に note カラムを追加します。

class CreateGifts < ActiveRecord::Migration
  def self.up
    create_table :gifts do |t|

      t.integer :gift_name_id
      t.string :sent_by
      t.string :received_by
      t.boolean :viewed
      
      # note カラムの追加
      t.string :note
      
      t.timestamps
    end
  end

  def self.down
    drop_table :gifts
  end
end

※通常はmigrationファイルを直接編集せずに ruby script/generate migration AddNoteToGift note:string コマンドにて新しい migrationファイルを作成しますが、DBにまだテーブルを作成していないので今回は migration ファイルを直接編集しました。↓の migration ファイルも同様に直接編集しています。

 GIFT_SAMPLE/config/20081201203248_create_gift_names.rb に ギフトを追加します。
 ※ Gift アプリはギフトを友達に贈ったりするものなのですが、ギフトはDBに保存しておかないといけません。

class CreateGiftNames < ActiveRecord::Migration
  def self.up
    create_table :gift_names do |t|
      t.string :name
      t.timestamps
    end
    
    # ギフトの追加
    
    GiftName.create(:id => 1, :name => 'book')
    GiftName.create(:id => 2, :name => 'coffee')
    GiftName.create(:id => 3, :name => 'candy')
    GiftName.create(:id => 4, :name => 'icecream')
    
    
  end

  def self.down
    drop_table :gift_names
  end
end

6. DBにテーブル作成

 Gift sample アプリのトップディレクトリにて
 # rake migrate

7. サーバの起動

 Gift sample アプリのトップディレクトリにて
 # ruby script/server

 上記コマンドにより、本アプリは http://www.example.com/にて動作しているとし以降の説明を進めます。

OrkutにてGiftsアプリのインストール

1. Orkutにアカウントのない方は、ここから アカウントを作成してください。

2. デベロッパー サンドボックスへの登録

 Orkutにてサンプルのアプリをインストールするには、サンドボックスに登録する必要があります。

 Orkutにログイン後、ここから 登録します。

 ※以前は登録が承認されるまでに数日要しましたが、現在はすぐに完了します。

3. Giftsアプリのインストール

 サイドメニューのアプリの編集をクリックします。

orkut_sidemenu_1

 URLに本Giftsアプリの下記URLを入力し、「アプリケーションを追加」ボタンをクリックします。

 http://www.example.com/gifts.xml

orkut_add_sample_app_1

 アプリケーション追加をクリックします。

orkut_add_sample_app_2

 これでGiftsアプリのサンドボックスへのインストールは完了です。

外部サーバにてOrkut(OpenSocialコンテナ)からの署名付きのリクエストを受け付ける

 Gifts アプリでは、Orkutと外部サーバ間にてデータの改ざんが行われないように、Orkutから外部サーバへの通信には署名付けられるように実装されています。
 (GIFT_SAMPLE/public/gifts.xml の 13行目辺り params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED; )
 実サービスにおいても、署名付きリクエストは必須となるでしょう。

追記: 2009-01-10 05:30 (コメント参照) ———
また、署名方式には HMAC-SHA1 を用いるように指定されています。
(GIFT_SAMPLE/public/gifts.xml の 14行目辺り params[“OAUTH_SERVICE_NAME”] = “HMAC”; )
追記ここまで ————

この署名方式では Consumer Key と Consumer Secret Key が必要となります。

1. Consumer Key と Consumer Secret Key の取得

 Orkutでは、Consumer Key と Consumer Secret Keyを発行する際に、本アプリの所有者があなたか確認するためにトークンを発行します。

 下記ページにGiftsアプリのURL( http://www.example.com/gifts.xml )を入力し、「submit」ボタンをクリックします。
 https://www.google.com/gadgets/directory/verify

 すると、 <!– ALm6fM2iKDPf9qY5 … gMjzbD1cwDBifBX5w== –> といったトークンが発行されます。
 ※ブラウザは閉じずにそのままにしておいてください。

 GIFT_SAMPLE/public/gifts.xml の Content タグ内(CDATA開始タグとscriptタグの間)に発行されたトークンを挿入し、保存します。
 

<?xml version="1.0" encoding="UTF-8"?>
<Module>
  <ModulePrefs title="Gifts">
	  <Require feature="opensocial-0.8" />
	  <Require feature="dynamic-height"/>
  </ModulePrefs>
  <Content type="html">
    <![CDATA[
    <!-- ALm6fM2iKDPf9qY5 ... gMjzbD1cwDBifBX5w== -->
	    <script>
  	    // Sends a signed makeRequest to a specified remote server to load the iframe
  	    function sendSignedRequest(server) {

 さきほどのページにて「Verify」ボタンをクリックします。
 Giftsアプリの所有者があなたであることが確認されると、下記のように Consumer Key と Consumer Secret Key が発行されます。

OAuth Consumer Key: 294828716828
OAuth Consumer Secret: xw/zDlw3y4p4yRFZo2mCQCID

2. Controller の修正

 Gifts アプリの gifts controller にて、署名付きリクエストを受け付けられるようにします。

 GIFT_SAMPLE/app/controllers/gifts_controller.rb を開き、KEYS定数に先ほどのConsumer KeyとConsumer Secretを追加します。

  # Declares the keys for your app on different containers. The index is the
  # incoming consumer key sent in the signed makeRequest from the gadget.
  # These are sample gadget credentials and should be replaced with the HMAC
  # keys granted to your own gadget.
  KEYS = {
    # ↓追加
    
    '294828716828' => {
      :secret => 'xw/zDlw3y4p4yRFZo2mCQCID',
      :outgoing_key => 'orkut.com:294828716828',
      :container => OpenSocial::Connection::ORKUT
    },
    
    # ↓削除してしまってかまいません
    '649048920060' => {
      :secret => '2rKmqUigMbFqK783szqzzOky',
      :outgoing_key => 'orkut.com:649048920060',
      :container => OpenSocial::Connection::ORKUT
    },
    'http://opensocial-resources.googlecode.com/svn/samples/rest_rpc/sample.xml' => {
      :secret => '6a838d107daf4d09b7d446422f5e7a81',
      :outgoing_key => 'http://opensocial-resources.googlecode.com/svn/samples/rest_rpc/sample.xml',
      :container => OpenSocial::Connection::MYSPACE
    }
  }

 KESY定数はHashになっています。HashのKeyに先ほどの Consumer Key を指定します。そのkeyのvalueもHashになっていますので、secretには先ほどのConsumer Secretを指定します。また、outgoing_keyには orkut.com: に続けて再度 Consumer Key を指定します。

 SERVER 定数も変更します。
 

# Declares where your application lives. Points to the page where users are
  # redirected after loading the iframe.
  SERVER = 'http://www.example.com/'

 これにて署名付きリクエストが受け付けられるようになります。

 Giftsアプリが署名付きリクエストを外部サーバに送信する(実際には、リクエストを送信するのはOpenSocialコンテナ(今回はOrkutのサーバ))のはユーザが本アプリにアクセスした初めの一度だけです。
 これは Giftsアプリがコンテンツをiframeにて表示するからです。

 よって、iframe内にて表示するコンテンツのURLを指定する必要があります。

 GIFT_SAMPLE/public/gifts.xml を開いて、30行目辺りの sendSignedRequest メソッドへの引数を下記のように gifts controller の iframe アクションへのURLに変更します。
 

    sendSignedRequest('http://www.example.com/gifts/iframe');

 最後にサーバを再起動して終了です。

 今回は OpenSocialコンテナ(Orkut) -> 外部サーバへの一方的な通信でしたが、OAuthを用いて外部サーバ -> OpenSocialコンテナへの通信も可能となります。
 mixi では mixi connect がそれに当ります。

 今回の記事のタイトルが「速攻で作る OpenSocialアプリ」でありながら全くもって速攻では終わりませんでしたが、実サービスにて必須となるであろう署名付きリクエストの受付方法を示すことができましたのでご参考になれば幸いです。

 
 本年もBananan Systemsをどうぞ宜しくお願い申し上げます。