RailsでAmazonの商品を, 署名認証に対応した上で扱う
今朝こんなメールがきました.
【重要】Product Advertising API (旧 AmazonアソシエイトWebサービス)の署名認証に関するお知らせ
内容をサラッと言うと:
うちが調べてみたところ, おたくのAWSAccessKeyIDから送られてくるリクエストに電子署名がついていないんですよー.
んでー, 8月15日までに電子署名つけてくれないと, リクエスト受け付けなくなっちゃうんですよー.
だからそれまでにつけておいてね!
です.
いやー, やっぱり催促されちゃいますよね. というわけで署名認証に対応したのもメモメモ.
ruby-aawsのインストール
前回のバージョンで使ったamazon-ecsは署名認証に対応していない(だからメールがきたんだけど)ので, 別のRubyGemsを用意. 前回のバージョンのブコメでid:takahashimさんが:
対応済みをうたっている(未確認)ruby-aawsの方がいいような
とおっしゃっていたので, 早速ruby-aawsをインストール.
$ sudo gem install ruby-aaws
ちなみにruby-awsというのもあって, それを間違えて入れていたのは内緒. ruby-awsではなく, ruby-aawsなので注意(自分に言い聞かせるように).
デフォルトの設定を書く
いつものようにこのRubyGemsを使いますよー, っていうのを書く.
# config/environment.rb config.gem 'ruby-aaws', :lib => 'amazon'
あとデフォルトの設定(AWSAccessKeyIDなど)を書く. 専用のファイルに書くので:
# config/amazonrc [global] key_id = APIを使うために必要なアクセスキー secret_key_id = 秘密キー locale = jp cache = true cache_dir = tmp/amazon
って書いて:
# config/initializers/amazon_aws_env.rb ENV['AMAZONRCDIR'] = 'config' ENV['AMAZONRCFILE'] = 'amazonrc'
そのファイルを読みにいくよう, 環境変数を設定しておく.
何気に素敵なのが, このRubyGems自体にキャッシュの機能がついているコト. config/amazonrcのcacheとcache_dirがそれ. キャッシュの保存場所はtmp/amazonにしたので:
$ mkdir tmp/amazon
そのためのディレクトリを作っておく.
モデルを書く
class AmazonItem < ActiveRecord::Base validates_presence_of :asin def method_missing(name, *args) lookup unless @looked @item.send name, *args end protected def validate lookup unless @looked errors.add :asin, "can't find the item from Amazon" unless @item end private def lookup page = Amazon::AWS::Search::Request.new.search( Amazon::AWS::ItemLookup.new('ASIN', 'ItemId' => asin), Amazon::AWS::ResponseGroup.new('Medium') ) @item = page.item_lookup_response.items.item @looked = true end end
amazon_item = AmazonItem.find_by_asin '4797336617' puts amazon_item.item_attributes.title.to_s # => たのしいRuby 第2版 Rubyではじめる気軽なプログラミング
リクエストされたURLは:
http://ecs.amazonaws.jp/onca/xml ?AWSAccessKeyId=XXX &AssociateTag=calibanorg-20 &IdType=ASIN &ItemId=4797336617 &Operation=ItemLookup &ResponseGroup=Medium &Service=AWSECommerceService &Timestamp=2009-06-17T09%3A46%3A55Z &Version=2009-03-31 &Signature=g42E4Xoj%2F9c1peqybJxnN0iuxB8Cr4ZVPwggPcI0SHw%3D
なので, ちゃんと電子署名(Signatureパラメーター)が付与されていますよ, と*1.
ちなみにmemcachedを使わなくても, キャッシュを使うように設定すればruby-aawsだけでもそこそこ速い. あとItemLookup以外のオペレーションもキャッシュするので何かと便利かも.
ただ速度はオンメモリなmemcachedに及ばない(未確認)だろうし, ネットワークを介すこともできないのでそこはケースバイケースかな.
あと気になるのが:
Amazon::AWS::Search::Request.new.search( Amazon::AWS::ItemSearch.new('Books', 'Keywords' => 'ruby'), Amazon::AWS::ResponseGroup.new('Medium'), 5 )
ってやると, 1ページ目から5ページ目までの検索結果が返ってくる点. 5ページ目だけじゃなくて?
*1:ちなみになんでAssociateTagがついてんの? つけていないのに……