2009 年 2 月
はじめに
「クライアント ライブラリのリストに Ruby はありますか?」
デベロッパーの皆様の強い要望と Ruby on Rails(RoR)の根強い人気に後押しされ、同僚の Jeff Fisher が滅びの山の奥深くから Ruby ユーティリティ ライブラリを鍛え上げました。完全なクライアント ライブラリではありませんが、認証や基本的な XML 操作などの基本事項は処理します。また、REXML モジュールと XPath を使用して Atom フィードを直接操作する必要があります。
オーディエンス
この記事は、Ruby(特に Ruby on Rails)を使用して Google Data APIs にアクセスすることに関心のあるデベロッパーを対象としています。読者が Ruby プログラミング言語と Rails ウェブ開発フレームワークについてある程度の知識を持っていることを前提としています。ほとんどのサンプルでは Documents List API に焦点を当てていますが、同じコンセプトは Data API のいずれにも適用できます。
スタートガイド
要件
Google Data Ruby ユーティリティ ライブラリをインストールする
ライブラリを取得するには、プロジェクト ホスティングからライブラリ ソースを直接ダウンロードするか、gem をインストールします。
sudo gem install gdata
ヒント: 念のため、gem list --local
を実行して、gem が正しくインストールされたことを確認します。
認証
ClientLogin
ClientLogin を使用すると、アプリケーションでユーザーを Google アカウントまたは G Suite アカウントにプログラムでログインさせることができます。ユーザーの認証情報が検証されると、Google は以降の API リクエストで参照される認証トークンを発行します。トークンは、使用している Google サービスによって定義された一定期間有効です。セキュリティ上の理由と、ユーザーに最適なエクスペリエンスを提供するため、ClientLogin はインストール型のデスクトップ アプリケーションを開発する場合にのみ使用してください。ウェブ アプリケーションでは、AuthSub または OAuth を使用することをおすすめします。
Ruby ライブラリには、各 API のクライアント クラスがあります。たとえば、次のコード スニペットを使用して、user@gmail.com
を Documents List Data API にログインします。
client = GData::Client::DocList.new client.clientlogin('user@gmail.com', 'pa$$word')
The YouTube Data API would be:
client = GData::Client::YouTube.new client.clientlogin('user@gmail.com', 'pa$$word')
実装されているサービス クラスの一覧をご覧ください。サービスにクライアント クラスがない場合は、GData::Client::Base
クラスを使用します。たとえば、次のコードでは、ユーザーに G Suite アカウントでのログインを強制します。
client_login_handler = GData::Auth::ClientLogin
.new('writely', :account_type => 'HOSTED')
token = client_login_handler.get_token('user@example.com', 'pa$$word', 'google-RailsArticleSample-v1')
client = GData::Client::Base.new(:auth_handler => client_login_handler)
注: デフォルトでは、ライブラリは accountType
に HOSTED_OR_GOOGLE
を使用します。指定可能な値は HOSTED_OR_GOOGLE
、HOSTED
、GOOGLE
です。
ClientLogin を使用するデメリットの 1 つは、ログイン試行が失敗した場合に、アプリケーションに CAPTCHA チャレンジが送信される可能性があることです。その場合は、追加のパラメータ client.clientlogin(username, password, captcha_token, captcha_answer)
を指定して clientlogin()
メソッドを呼び出すことで、エラーを処理できます。CAPTCHA の処理について詳しくは、インストール済みアプリケーションの認証のドキュメントをご覧ください。
AuthSub
AuthSubRequest URL を生成する
scope = 'http://www.google.com/calendar/feeds/' next_url = 'http://example.com/change/to/your/app' secure = false # set secure = true for signed AuthSub requests sess = true authsub_link = GData::Auth::AuthSub.get_url(next_url, scope, secure, sess)
上記のコードブロックは、authsub_link
に次の URL を作成します。
https://www.google.com/accounts/AuthSubRequest?next=http%3A%2F%2Fexample.com%2Fchange%2Fto%2Fyour%2Fapp&scope=http%3A%2F%2Fwww.google.com%2Fcalendar%2Ffeeds%2F&session=1&secure=0
クライアント オブジェクトの authsub_url
メソッドを使用することもできます。各サービスクラスにはデフォルトの authsub_scope
属性が設定されているため、独自の属性を指定する必要はありません。
client = GData::Client::DocList.new next_url = 'http://example.com/change/to/your/app' secure = false # set secure = true for signed AuthSub requests sess = true domain = 'example.com' # force users to login to a G Suite hosted domain authsub_link = client.authsub_url(next_url, secure, sess, domain)
上記のコードブロックは、次の URL を作成します。
https://www.google.com/accounts/AuthSubRequest?next=http%3A%2F%2Fexample.com%2Fchange%2Fto%2Fyour%2Fapp&scope=http%3A%2F%2Fdocs.google.com%2Ffeeds%2F&session=1&secure=0&hd=example.com
1 回限りのトークンをセッション トークンにアップグレードする
ユーザーがデータへのアクセスを許可すると、AuthSub はユーザーを http://example.com/change/to/your/app?token=SINGLE_USE_TOKEN
にリダイレクトします。URL は、next_url
に 1 回限りのトークンがクエリ パラメータとして追加されたものです。
次に、使い捨てトークンを有効期間の長いセッション トークンと交換します。
client.authsub_token = params[:token] # extract the single-use token from the URL query params session[:token] = client.auth_handler.upgrade() client.authsub_token = session[:token] if session[:token]
Secure AuthSub もよく似ています。トークンをアップグレードする前に秘密鍵を設定する点が追加されただけです。
PRIVATE_KEY = '/path/to/private_key.pem' client.authsub_token = params[:token] client.authsub_private_key = PRIVATE_KEY session[:token] = client.auth_handler.upgrade() client.authsub_token = session[:token] if session[:token]
注: セキュア トークンを使用するには、使い捨てトークンをリクエストするときに secure=true
を設定してください。上記のAuthSubRequest URL の生成をご覧ください。
トークン管理
AuthSub は、トークンを管理するための AuthSubTokenInfo と AuthSubRevokeToken の 2 つの追加ハンドラを提供します。AuthSubTokenInfo
は、トークンの有効性を確認するのに役立ちます。AuthSubRevokeToken
を使用すると、ユーザーはデータへのアクセスを停止できます。アプリでは、ベスト プラクティスとして AuthSubRevokeToken
を使用する必要があります。どちらの方法も Ruby ライブラリでサポートされています。
トークンのメタデータをクエリするには:
client.auth_handler.info
セッション トークンを取り消すには:
client.auth_handler.revoke
AuthSub の詳細については、ウェブ アプリケーション用の AuthSub 認証の完全なドキュメントをご覧ください。
OAuth
この記事の執筆時点では、OAuth は GData::Auth
モジュールに追加されていません。
Rails の oauth-plugin または Ruby の oauth gem を使用する場合、ユーティリティ ライブラリで OAuth を使用するのは比較的簡単です。いずれの場合も、GData::HTTP::Request
オブジェクトを作成し、各ライブラリで生成された Authorization
ヘッダーを渡す必要があります。
フィードへのアクセス
GET(データの取得)
クライアント オブジェクトを設定したら、その get()
メソッドを使用して Google Data フィードをクエリします。XPath を使用して、特定の Atom 要素を取得できます。ユーザーの Google ドキュメントを取得する例を次に示します。
feed = client.get('http://docs.google.com/feeds/documents/private/full').to_xml feed.elements.each('entry') do |entry| puts 'title: ' + entry.elements['title'].text puts 'type: ' + entry.elements['category'].attribute('label').value puts 'updated: ' + entry.elements['updated'].text puts 'id: ' + entry.elements['id'].text # Extract the href value from each <atom:link> links = {} entry.elements.each('link') do |link| links[link.attribute('rel').value] = link.attribute('href').value end puts links.to_s end
POST(新しいデータの作成)
クライアントの post()
メソッドを使用して、サーバー上に新しいデータを作成します。次の例では、ID が doc_id
のドキュメントに共同編集者として new_writer@example.com
を追加します。
# Return documents the authenticated user owns feed = client.get('http://docs.google.com/feeds/documents/private/full/-/mine').to_xml entry = feed.elements['entry'] # first <atom:entry> acl_entry = <<-EOF <entry xmlns="http://www.w3.org/2005/Atom" xmlns:gAcl='http://schemas.google.com/acl/2007'> <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/acl/2007#accessRule'/> <gAcl:role value='writer'/> <gAcl:scope type='user' value='new_writer@example.com'/> </entry> EOF # Regex the document id out from the full <atom:id>. # http://docs.google.com/feeds/documents/private/full/document%3Adfrk14g25fdsdwf -> document%3Adfrk14g25fdsdwf doc_id = entry.elements['id'].text[/full\/(.*%3[aA].*)$/, 1] response = client.post("http://docs.google.com/feeds/acl/private/full/#{doc_id}", acl_entry)
PUT(データの更新)
サーバー上のデータを更新するには、クライアントの put()
メソッドを使用します。次の例では、ドキュメントのタイトルを更新します。これは、前のクエリのフィードがあることを前提としています。
entry = feed.elements['entry'] # first <atom:entry> # Update the document's title entry.elements['title'].text = 'Updated title' entry.add_namespace('http://www.w3.org/2005/Atom') entry.add_namespace('gd','http://schemas.google.com/g/2005') edit_uri = entry.elements["link[@rel='edit']"].attributes['href'] response = client.put(edit_uri, entry.to_s)
削除
サーバーから <atom:entry> などのデータを削除するには、delete()
メソッドを使用します。次の例では、ドキュメントを削除します。このコードは、前のクエリのドキュメント エントリがあることを前提としています。
entry = feed.elements['entry'] # first <atom:entry> edit_uri = entry.elements["link[@rel='edit']"].attributes['href'] client.headers['If-Match'] = entry.attribute('etag').value # make sure we don't nuke another client's updates client.delete(edit_uri)
新しい Rails アプリケーションの作成
通常、新しい Rails アプリを作成する最初の演習では、スキャフォールド ジェネレータを実行して MVC ファイルを作成します。その後、rake db:migrate
を実行してデータベース テーブルを設定します。ただし、このアプリケーションは Google Documents List API にデータをクエリするため、汎用的なスキャフォールディングやデータベースはほとんど必要ありません。代わりに、新しいアプリケーションとシンプルなコントローラを作成します。
rails doclist cd doclist ruby script/generate controller doclist
config/environment.rb
に次の変更を加えます。
config.frameworks -= [ :active_record, :active_resource, :action_mailer ] config.gem 'gdata', :lib => 'gdata'
1 行目は、アプリケーションから ActiveRecord
をフック解除します。2 行目は、起動時に gdata
gem を読み込みます。
最後に、デフォルト ルート(「/
」)を DoclistController
の documents
アクションに接続することにしました。次の行を config/routes.rb
に追加します。
map.root :controller => 'doclist', :action => 'all'
コントローラを起動する
スキャフォールディングを生成していないため、app/controllers/doclist_controller.rb
の DoclistController
に「all
」というアクションを手動で追加します。
class DoclistController < ApplicationController def all @foo = 'I pity the foo!' end end
app/views/doclist/
に all.html.erb
を作成します。
<%= @foo %>
ウェブサーバーを起動して開発を開始する
これで、ruby script/server
を呼び出してデフォルトのウェブサーバーを起動できるようになりました。すべてがうまくいけば、ブラウザで http://localhost:3000/
を指定すると「I pity the foo!
」が表示されます。
ヒント: public/index.html
の削除または名前の変更を忘れないでください。
動作を確認したら、DocList Manager プロジェクトの核心部分である最終的な DoclistController
と ApplicationController
をご覧ください。また、Google Contacts API への呼び出しを処理する ContactsController
もご覧ください。
まとめ
Google Data Rails アプリの作成で最も難しいのは、Rails の構成です。ただし、アプリケーションのデプロイもそれに近いほど重要です。そのため、Apache には mod_rails を強くおすすめします。セットアップ、インストール、実行が非常に簡単です。すぐに使い始められます。
リソース
- Google Data API のリスト
- Google Data Ruby Utility Library プロジェクト ページ
- 記事: Google Data APIs で Ruby を使用する
- Ruby をダウンロードする
- RubyGems と Rails をダウンロードする
付録
例
DocList Manager は、この記事で説明したトピックを示す完全な Ruby on Rails サンプルです。完全なソースコードはプロジェクト ホスティングから入手できます。