Amazon Product Advertising APIで使うシークレットアクセスキーを取得する

2014/4/21よりAWS(Amazon Web Service)の仕様が変わりルートアカウントのシークレットキーが表示されなくなりました。AmazonJS(Amazon Product Advertising API)では以前としてルートアカウントのアクセスキーとシークレットアクセスキーが必要なようなので取得方法を調べました。

この記事はAmazon Product Advertising API(AWS)のアカウントをとったがシークレットアクセスキーの取得方法がわからないという人向けです。この問題にぶち当たるまでの道は他のサイトを見てたどり着いてください。。。

では、AWSのコンソールに移動して取得したAWSアカウント・パスワードを入力してください。

コンソールの右上の自分の名前のプルダウンして出てくるメニューからSecurity Credentialsという項目をクリックします。

aws-acount-for-product-advertising-api-01.png

IAM Userを始めるか聞かれるのですが、今は不要なので閉じます。

aws-acount-for-product-advertising-api-02.png

右側の上から3つ目くらいのAccess Keys (Access Key ID and Secret Access Key) を開いて、Create New Access Key ボタンを押します。(2つまでしか作成できないようなので、既に2つ作成している場合はどちらかを諦めて削除してください)

aws-acount-for-product-advertising-api-03.png

作成すると Access Key IDとSecret Access Keyが表示される のでコピーして保管します。(Secret Access Keyは作成時しか表示されないので紛失した場合は再度作りなおすことになります)

aws-acount-for-product-advertising-api-04.png

上記の二つの値をAmazonJSの設定画面で設定してください。

IAM UserはProduct Advertising APIに対応していない?

そもそも仕様変更の意図としてAWSアカウントの元でユーザ(IAM User)が作成でき、「個別のユーザに適切な権限を与えよ」と理解していたのでその通りに試したのですが、何故かIAM UserでProduct Advertising APIは使えませんでした。

まずProduct Advertising APIに対する権限ポリシーが存在しない。Administration Policyを渡してみたけどそのユーザのアクセスキーを使うとコード AWS.InvalidAccount のエラーになって

お客様の AccessKey Id は Product Advertising API に登録されていません。https://affiliate-program.amazon.com/gp/flex/advertising/api/sign-in-jp.html で登録後に得られる AccessKey ID をご使用ください。

とか怒られる。

ちょっと焦ってForumなどを検索して見つかったから助かった。
Your AccessKey Id is not registered for Product Advertising API.
https://forums.aws.amazon.com/thread.jspa?threadID=151500

でもそのうち解決されるかもしれないのでそれまでの繋ぎということで。

サーバのデータバックアップをAmazon S3に置く

以前は自宅サーバからさくらのVPSのバックアップをrsyncなどで取得していたんだけど、自宅サーバをRaspberry Piに置き換えた機会に自宅サーバの事業仕分けを行った結果、バックアップはさくらのVPSから直接Amazon S3に置くことにした。

Amazon S3を使う

AWSを使うにはAmazonのアカウントが必要になるけど、もともと商品検索API(Product Advertising API)でアカウントを持っていた。

Amazon S3では Bucket という単位でストレージを管理する。BucketはS3 Management Consoleから生成、管理できる。

Bucketを作る際のポイントとしては、

  • Bucket Name全ユーザで一意 である必要がある
  • Bucketにあるファイルを独自ドメインで公開したい場合は、 Bucket Nameをホスト名を一致させる必要がある
    • 例えば、static.example.com というホスト名で運用したい場合、Bucket Nameを static.example.com にする
  • RegionTokyo にする

といったあたりか。今回のバックアップデータ置き場としてはHTTPで公開しないのでBucket Nameは com-example-backup のようにドメインを逆向きにして使った。

Chefでs3cmdをセットアップ

Amazon S3へのバックアップ方法を調べると、s3syncやs3cmdといったツールを使う記事が見つかる。結局、どっちがメジャーなのかよくわからなかったんだけどDebianだと apt-get install s3cmd で入るので s3cmd を使うことにした。というかChefのレシピ書いた。

s3cmdはまず s3cmd --configure~/.s3cfg に構成ファイルを作って使うので、その代わりとしてChefのtemplateリソースでファイルを配置するようにした。このテンプレートは1.1.0-beta3のs3cmd --configureでできたファイルを元にした。具体的にはキーの所を変数を参照するようにして、locationをap-northeast-1に変更した。

templates/default/s3cmd/s3cfg.erb
[default]
access_key = <%= node[:aws][:access_key] %>
bucket_location = ap-northeast-1
cloudfront_host = cloudfront.amazonaws.com
default_mime_type = binary/octet-stream
delete_removed = False
dry_run = False
enable_multipart = True
encoding = UTF-8
encrypt = False
follow_symlinks = False
force = False
get_continue = False
gpg_command = /usr/bin/gpg
gpg_decrypt = %(gpg_command)s -d --verbose --no-use-agent --batch --yes --passphrase-fd %(passphrase_fd)s -o %(output_file)s %(input_file)s
gpg_encrypt = %(gpg_command)s -c --verbose --no-use-agent --batch --yes --passphrase-fd %(passphrase_fd)s -o %(output_file)s %(input_file)s
gpg_passphrase =
guess_mime_type = True
host_base = s3-ap-northeast-1.amazonaws.com
host_bucket = %(bucket)s.s3-ap-northeast-1.amazonaws.com
human_readable_sizes = False
invalidate_on_cf = False
list_md5 = False
log_target_prefix =
mime_type =
multipart_chunk_size_mb = 15
preserve_attrs = True
progress_meter = True
proxy_host =
proxy_port = 0
recursive = False
recv_chunk = 4096
reduced_redundancy = False
secret_key = <%= node[:aws][:secret_key] %>
send_chunk = 4096
simpledb_host = sdb.amazonaws.com
skip_existing = False
socket_timeout = 300
urlencoding_mode = normal
use_https = True
verbosity = WARNING
website_endpoint = http://%(bucket)s.s3-website-%(location)s.amazonaws.com/
website_error =
website_index = index.html
recipes/s3cmd.rb
package 's3cmd'

template "/home/#{node[:aws][:user]}/.s3cfg" do
  source "s3cmd/s3cfg.erb"
  mode 0600
  owner node[:aws][:user]
  group node[:aws][:user]
end

Debian(Vagrant)上で動作確認済み。

attributes/default.rb
default[:aws][:user] = ''
default[:aws][:access_key] = ''
default[:aws][:secret_key] = ''

あたりを設定してください。

バックアップ

s3cmd ls でBucket一覧が取れる。

s3cmd putscpのようなものだと思う。rsyncのようなs3cmd syncもあるようだ。

ファイルを置くには以下のようにコマンドを実行する。

s3cmd put <file> s3://<bucket-name>[/<prefix>]

とりあえず動いた。S3の料金体系は便利な計算ページがあるんだけど、それでもよくわからない。Amazon S3はそんなに高くはなさそうだけど通信量で計算されるので週一くらいの間隔でcron回してバックアップしようかと思う。

まぁさくらのVPS自体もさくらインターネット側でバックアップしてくれてると思うしね。

Kindle Fire HDX 8.9買った

Kindle Fire HDX買っちゃった☆8.9インチ。

iPad miniは依然として優秀。優秀なのでサブディスプレイ、サブコンピュータ扱いになっている。それ故にiPad miniで本を長時間読むとその間メールチェックしないとか作業に支障がでたりして、本専用のタブレットが欲しいと思った次第。

Kindle本はFontのサイズが変更できるのでディスプレイが小さくても調整できるけど、iPad miniも含めて7インチではスキャンしたPDFでは文字が小さくて拡大しないと読みにくい本があるので8.9インチにした。これでさらに374gカバンが重くなった。

で、粛々とBookscanでKindle向けチューニングをやり直した。チューニング結果がiPad(非Retina)チューニングと比べて1.5倍くらいのファイルサイズになり解像度の分クオリティが上がっているようだ。

もともと初代iPad miniの16GBにはいきらなくなったのでRetina iPad miniや今回Kindleを32GBにしたのだけど、ファイルサイズが1.5倍になったことで32GBでも足らなくなり全部を転送することは諦めた。こんなことならRetina iPad miniは16GBにして今回Kindleの64GB買うべきだったかなぁ。

とは言えBookscanに依頼したファイルも1,000個ぐらいあって、もはやファイル管理では支障をきたすレベル。音楽ファイルの管理みたいにジャンルをつけてグループ化できないときつい。とりあえずなんかあった時に目を通したい技術書メインで残りは自宅のNASからダウンロードできるようにしておくことにした。

MacからKindle Fireへの本の転送は専用ツールが必要でAndroid File Transferを使っている。
http://android-file-transfer.softonic.jp/mac

Kindle FireはAndroidベースなのだけど、AndroidのStoreには繋げず、Amazonが提供するStoreからアプリをインストールすることになる。PDFを見るアプリとしてはPerfect Viewerというアプリが優秀らしいので有料だけど購入した。サムネイルで表示してくれたりひと通り必要な機能は備えているようだ。なおPerfect ViewerでPDFを見るにはPerfect ViewerとPerfectViewer PDF Pluginの二つをインストールしないといけなかった。

Perfect Viewer

メリットでもあり、デメリット(?)でもあるのだけど、Kindle Fireだと本をデバイスで買えるのでこれでオーナーライブラリも活用できる。iPad miniでコミックスを読んでたけど次の巻が見たくてもiOSのKindleアプリでは購入ができないのでわざわざPCで買ったり面倒なことをしていた。デメリットは歯止めが聞かず買いまくってしまうおそれがあることだが、最近は基本的に紙の本で買うようにしているので今のところは大丈夫である。というのも物理的に積読しないとキューを管理できなくなっている。

やっぱりTrelloみたいな緩い積読(タスク)管理アプリ作りたい。

AmazonJSでAmazonの商品画像をWordPressのアイキャッチ画像に設定したい

AmazonJSプラグインでAmazonの商品画像をアイキャッチ画像に使いたい。という要望があったので調べてみた。結論から言うと難しそうだ。

アイキャッチ画像

アイキャッチ画像はWordPress 2.9, 3.0あたりから追加された機能で原文ではFeatured Imagesと呼ばれている。要するにブログの記事の目を惹くために記事ごとにサムネイル画像をつける機能のことである。一時期使ってみたい気もあったが、このブログだと過去のエントリーが多すぎて今更サムネイル画像ありきのレイアウトにするのが難しいので諦めていた。

ただ商品画像をアイキャッチ画像に使えると本や製品の紹介などをする記事ではだいぶ効果がありそう俺も使いたいと思い、完全に失念しているのでアイキャッチ画像の仕様について調べてみた。

アイキャッチ画像が表示されるまで

アイキャッチ画像を表示するには以下のような流れになる。

  • 使う画像がWordPressのメディアライブラリにある
  • アイキャッチ画像としてその投稿に設定されている
  • テーマが投稿に設定されているアイキャッチ画像を取り出して表示する

1番目、2番目がブログを書く人の作業で、3番目がテーマのお仕事となる。テーマが対応していないといくら投稿者がアイキャッチ画像を設定しても表示はされない。

課題

AmazonJSプラグインがアイキャッチ画像を設定するには技術的な課題と、契約的な問題がある。

アイキャッチ画像はテーマが表示するサイズを決めることができる、画像リサイズもあるせいかWordPressのメディア機能に関連しておりアイキャッチ画像に使うものはメディアライブラリに画像が登録されていないといけないっぽい。つまり、ただのURLをアイキャッチ画像に設定することはWordPressの標準機能ではできないようだ。1プラグインが勝手にメディアライブラリに画像を突っ込むのはやり過ぎなのでこの時点で自動化はほぼ厳しい。

自動以外でユーザにアイキャッチ画像として使うオプションを提供することはできると思うが契約の問題がある。僕は同意して使っているからには Product Advertising APIの契約 をAmazonJSユーザは守るべきと考えており、APIの契約の中には商品データを永続的にキャッシュしていけないと書いてあるので画像データをメディアライブラリに突っ込むのは微妙なところである。(AmazonJSではデータを24時間キャッシュ、価格について取得日時を表示するというガイドラインを守っている)

2つの側面からなかなか一筋縄にはいかないようだ。

どうもWordPressのAmazonプラグインはカオスで定番がないらしい

結局のところ後日プラグインを自作した jquery-templateでamazon商品を紹介するamazonjsをリリースしました

いままでamazonの商品を紹介するときは、アソシエイトタグの入ったリンクと画像のhtmlを普通に書くということをしていたんですが、いい加減面倒くさくなってきたのでここに来てWordPressのプラグインを探してみました。

しかし、意外なことに先人の調査にもあるように

定番となりそうなプラグインがないようなのです。こまった。

カオスorz

Amazonプラグインに関しては

  • 海外で開発され日本localeに対応していない
  • メンテナンスが終了している
    • AmazonAPIの署名に対応していない
    • 最新のAmazonの規約に対応していない
    • 最新のWordPressに対応していない
  • 出力されるHTMLが気にいらない

といったことがあって、いろいろな新規プラグイン、派生プラグインが作成されているという現状があります。結果として今回自分がはまったように、「なんか結局いっぱいあってどれを使っていいかわからん。カオスすぎる。」という最大の問題にぶちあたります。

日本作のAmazonプラグインたち

日本の方がつくって、まだ(2010/10時点で)メンテされてそうなプラグインには以下のようなものがあります。いずれも現在(2010/10時点で)のAmazon APIで動作します。こだわりがなければ以下のどれかで十分要求は満たせるんじゃないでしょうか。

tmkm-amazon

原作者による更新は終了しているようですが、人気がありいくつも派生版が継続されているようなので一応記載。

  • ショートコードからhtmlに置換するタイプで、ある程度デザインしたhtmlを出力してくれる。
    • [tmkm-amazon]ASIN[/tmkm-amazon]
  • 投稿画面から商品の検索ができる。
  • 検索やデザインしたhtmlの出力の場合はプラグイン内部でProduct Advertising APIを使う。
  • PEAR/Cache_Liteでデータのキャッシュをファイルで保存、キャッシュ期間は1時間。

Simple Amazon

調べたバージョンは5.1.1。

  • ショートコードに頼らないプラグイン。内部実装としてはtmkm-amazonがベースになっているがコンセプトは違う。
  • Amazonへの商品URL(aタグ)をある程度デザインしたhtmlに変換してくれる。
  • 表示する情報量は設定画面から可能。
  • プラグインの中でProduct Advertising APIを使うのでアクセスキーなどが事前に必要。
  • PEAR/Cache_Liteでデータのキャッシュをファイルで保存、キャッシュ期間は24時間。
  • ファイルロックによるProduct Advertising APIのリクエスト制限。

AmazonLink

調べたバージョンは2.0.0 beta3。

  • 高機能なプラグイン。
  • ショートコードからhtmlに置換するタイプで、ある程度デザインしたhtmlを出力してくれる。
    • [amazon]ASIN[/amazon]
  • 投稿画面から商品の検索ができる。
  • 検索やデザインしたhtmlの出力の場合はプラグイン内部でProduct Advertising APIを使う。
  • Product Advertising APIを使わないでショートコードを単にAmazonの公式リンクツールに置き換えるモードもある。
  • テンプレートを設定画面から編集することで独自のhtmlを変更することができる。
  • データのキャッシュをデータベースのテーブルに保存。キャッシュ期間は24時間。
  • ファイルリンク(rename)によるロックファイルチェックによるProduct Advertising APIのリクエスト制限。

Mitsurin

調べたバージョンは1.1。

  • 表示する情報量は少ないがいくつかのテンプレートがありレイアウトのカスタマイズに便利なプラグイン。
  • ショートコードからhtmlに置換するタイプで、ある程度デザインしたhtmlを出力してくれる。
[amazon asin='ASIN' type='TYPE']
[amazon asin='ASIN' type='TYPE']商品の名前[/amazon]
  • いくつかの表示レイアウトパターンを持っていてショートコードのtypeへ指定可能。
  • PEAR/Cache_Liteでデータのキャッシュをファイルで保存。キャッシュ期間は24時間。

Amazon ISBN Anchor Plugin

調べたバージョンは2.0.0。

  • Product Advertising APIを直接使わないのでアクセスキーなの設定が不要なプラグイン。
  • []で表現されるショートコードではないがaタグhrefに入ったuriの表現を元にある程度デザインしたhtmlに置き換える。
    • <a href="isbn:978-4086012447">マリア様がみてる ハローグッバイ</a>
  • プラグイン内部ではProduct Advertising APIを使っておらず外部のサービスを経由している。
  • データのキャッシュをデータベースのテーブルに保存。キャッシュ期間は48時間。

リンク作成ツール

プラグインを使わずに外部のサービスで対応することもできます。外部のリンクサービスを使うメリットとしては自分のブログサーバに負荷を与えない点です。

例えば現在だと、Amazonには公式のリンク作成ツールがあります。
https://affiliate.amazon.co.jp/gp/associates/join/links.htmlX120X
デザインとかどうでもいいから、アフィリエイトしたいというならこれで十分じゃないかと思いました。公式なものだから安心感もあります。

それ以外だと、

がメジャーなようです。

Amazon公式以外のリンクツールを使う場合の問題としてはそのサービスが落ちてしまったり、終わってしまうと使えなくなってしまう点です。

マクロ

今まで自分がやっていたように機械的なhtmlをつくるだけなら、以下のようなマクロを使うのもありということにも気が付きました。

ただタグをいれるだけなら AddQuicktag プラグインをつかって以下のようなタグを追加してasinだけ置き換えるとかでも今のhtml書くのが面倒という不満も少しは解消できます。

<a href="http://www.amazon.co.jp/exec/obidos/ASIN/{asin}/makotokw-22/ref=nosim" target="_blank"><img src="http://images-jp.amazon.com/images/P/{asin}.09.MZZZZZZZ.jpg" alt="" border="0" /></a>

Product Advertising APIの規約

ずいぶん前にAPIを調べたことがあってデータは24時間しかキャッシュしてはいけないことは知っていたのですが、最新のProduct Advertising APIの規約を読んでいたところちょっと気になることが・・・

  • 価格や発送時期の表示は一時間以内に更新するか、もしくは取得した時間を横に記載すること
  • Product Advertising APIから取得したURLは改変しないこと
  • Product Advertising APIに指定したアソシエイトタグとアクセスキーの所有者(メールアドレス)は同じであること

価格を表示可能なプラグインもあるんですが、tmkm-amazon以外は24時間キャッシュを意図した実装になっているし、そもそもWordpress側でページキャッシュされてしまうとプラグインの介入する余地はなくなるので(ajaxなどで動的に更新しない場合は)、ブロガーが自己責任を覚悟で表示することになります。

次にProduct Advertising APIを使う場合、自分のアソシエイトタグを追加したい場合は自分で取得したアクセスキーを使ってProduct Advertising APIを実行する必要があります。外部のサービスをつかっているものが実際どういう仕組で動いているのかわかりませんが、普通の契約でProduct Advertising APIを使っているだけだとしたら、そこで取得したデータの商品URLを自分のアソシエイトタグに置き換えることは厳密には規約違反ということになるように見えます。Amazonとしても販売促進になっていることは確かなので実際にはそこまで厳しくはしておらず容認の方向なのではないかと想像していますが、急に制限されたらどうしようとか不安な気持ちにはなります。

個人的な結論

  1. デザインとかどうでもいいならプラグインは使わないでAmazonの公式のリンク作成ツールを使う
  2. デザインやアソシエイトタグを気にする場合、API規約を考えると内部でProduct Advertising APIを使っていうプラグインを使う、ただし価格を表示する場合は注意
  3. デザインを自由に変更したいなら、AmazonLinkプラグインを使う、レイアウトだけ変えたいのならMitsurinプラグインをつかう
  4. Amazonのリンクツールのデザインは嫌だが、そこまでのデザインは必要なくブログのパフォーマンスを気にする場合はマクロを使う
  5. それ以外どうしても満たしたい要求がある場合には、プラグイン作者に依頼するか、既存のプラグインを改変するか自作する

あくまで個人的な結論ですが、まずは一番信頼性の高い本家Amazonの公式リンク作成ツールで問題ないか検討すべき。次に公式リンクで満足できない場合は、デザインが嫌だとかもっと簡単に追加したい、という要求になってくると思います、どちらの要求度が高いのかをよく見極める必要があります。これらを解決する場合はProduct Advertising API規約を考えると外部のリンクツールより、Product Advertising APIを直接つかうプラグインを選択したほうが良いと思います。

デザインに関しては独自テンプレートを持っているAmazonLinkプラグイン、レイアウトパターンを持っているMitsurinプラグインが自由度が高いです。ある程度のスキルがあって簡単に追加したいという要求を満たすならマクロをつかうという選択肢がありなかなと。

で自分の場合、デザインの統一には気をつかっているのでAmazon公式リンクは使いたくなく、アソシエイトタグは埋め込みたいのでプラグインを使いたいんだけど、自分の欲しい機能を満たすものがないので4か5を選択しそう。

というか今回はじめて日本語プラグインがまとまっている http://wppluginsj.sourceforge.jp を知りました・・・・

結局のところ後日プラグインを自作した jquery-templateでamazon商品を紹介するamazonjsをリリースしました

WidgetのAmazon署名対応完了!!

ようやく自分が使っていたAmazon APIの署名対応をすべて完了。

Amazon APIは国によって別々のドメインで提供しているんですが、調子にのってWidgetの国際化対応でロケールにあわせて適切なドメインに投げてたから・・・

  • (de) Erinnerung: Amazon.de Product Advertising API-Authentifizierung
  • (co.jp) 【重要・あと30日です】Product Advertising API の署名認証利用開始のお願い
  • (co.uk) Product Advertising API Reminder
  • (com) Product Advertising API Reminder

もう、わかってるちゅーねん。って思わずツッこんでしまったくらいメールきた。(エセ関西人の性)。でもこうやって見るとフランス人には使われていないようだ。

正直のところ、Amazonにはあまり怒っていなくて、またもや怒りの矛先はxmlのencoding属性がないと日本語が文字化けするどう考えてもフォローできないYahoo Widgetのバグに向いてしまった。だからレスポンスのHTTP HeaderのContent-Typeみろって。

例のごとくAmazonにクエリストリングなしでパラメータをPOSTするとレスポンスのxmlタグにencoding=”UTF-8″が入って結果としてYahoo Widgetで日本語が化けないという技を利用。

Javascript内に秘密鍵を入れたくないのでGoogle App Engineで署名つけてリダイレクトしていたのだがPOSTのリダイレクトはしんどそうなのでApp EngineでPOSTを受け付けた場合は署名付きパラメータを文字列で返して再度Widget側でAmazonへリクエストをPOSTするようにした。

こんな面倒なことはおそらくYahoo WidgetだけなのでGETで受けたときはそのまま署名付きURLでリダイレクトする仕様。

しばらく続いていたサステイニング作業がようやく終わり。最近はブログもつぶやきもせず、ただ疲弊しただけだったがそろそろ新サービスを考えたい。Google Developer Phoneをまだ開けていないので開けよう。

Amazon Product Advertising APIの開発者の気持ちになってみる

アカン、何回よんでもこの日本語が理解でけへん。

AMAZON アソシエイト WEB サービスの名称変更および署名認証についてのお知らせ

名称変更にともない、Product Advertising API にリクエストを送信いただく都度、認証のための電子署名を含めていただくことが必要になります。

なんで、名前が変わると署名が必要になんの?何ルール?いや、まぁ、わからんでもないけどさ・・・でも機能は同じなのに名前がかわると何で署名が必須になるの?ねぇ?なんで?そんな法律あんの?
なんでいきなり?っていう思いはあるし、やり方がずるいよ。しかもhtml(xml)とJavascriptから成るWidgetのアーキテクチャでは秘密鍵がテキストで埋め込んだまま公開しなくてはならない。いや、マジでWidgetの開発者をなめてんのか?と考えざるを得ないのだが、落ち着いて相手の気持ちになって考えてみよう。

世界で一番使われてるWebサービスはおそらくAmazonじゃないだろうか。しかし、Webサービスに限らずたくさんのユーザを抱えてしまうと互換性が足かせになり新しいことができないといった状態に陥る。

AmazonのWebサービスはずいぶん前からあるので、そういった開発者のフラストレーションは相当なものになっているのだろう。おそらく署名をつけてもらうのは本当の目的ではない気がする。Webサービスを使うユーザが多すぎてどうにもならない今の現状をリセットしたいだけなんじゃないだろうか。

たとえば自分の知っていたアクセス先はwebservices.amazon.co.jpだったのだが今回見るとecs.amazonaws.jpとかになっている。いつ変わったのか知らないが、署名対応でユーザはプログラムを最新の情報で書き直すだろうし、Amazonの開発者は新しいドメインで新しいプラグラムを動かせる。当然古いプログラム(署名なしリクエスト)でアクセスされる古いURLはもう無視していい。過去何年もの負債が3ヶ月で一掃されるんだから、さぞAmazonの開発者は喜んでいるだろう。(8/15以降もwebservices.amazon.co.jpは使えるのかよくわかっていないけど、いずれにせよアクセスするユーザは相当減るのでリダイレクトしたところで大した負荷じゃないだろう)
さてWidgetの件はどうか。俺がもしAmazonの開発者でたくさんのユーザからのアクセスにウンザリきているのならこう思うのだろう。

「Google App Engine使えよ。タダで使えるんだからさ。つーか、うちのAPIだってタダで使わせてるんだからもまえらもそれぐらいの努力しろよ。こんにゃろ。」
俺なら絶対にこう思う。口には出さないだろうけど。

実際、Yahoo Widgetの文字化け問題がなかったらもうそれで解決してるんや。

「思てたんと違ーう!!」
このYahoo Widgetの文字化けの件も相当に頭に来ているけど、自分がもしマルチバイト圏外の開発者ならばやはり問題や深刻さは理解できないだろう。

こんなに憤慨しているのにだれにぶつけて良いかわからん。

「青春ってこんなに険しいんですか?」
そうだM-1を見よう。忍法、嫌なことがあったらお笑いを見るの術。

SongWidget 0.3.2をリリースしました(Yahoo! WidgetにおけるAmazonの文字化け)

ごめんなさい、ごめんなさい。半年ほったらかしにしていたSongWidgetのバグ修正版をリリースしました。(もっと放置してるwidgetもあるのは内緒)
http://makotokw.com/ja/portfolio/yahoowidget/songwidget
COMを同梱してwinamp対応とか考えてたんですが、影響がでかそうなので0.3.x系とtrunkに分岐して、とりあえず今起きてる不具合を修正して0.3.2としてリリースです。

でかい不具合としてAmazonのレスポンスが文字化けするという問題を修正しました。どうも、Yahoo Widget Engine側の修正の影響で発生するようになったようです。

結局、根本原因を調べるのはあきらめたんですが、調べてわかったことを書きます。

Yahoo! WidgetにおけるAWS(Amazon Web Service)文字化け問題
要因1:AWSにおいてResponseGroupをつけるとxml属性のencodingが省略される
http://webservices.amazon.co.jp/onca/xml?Service=AWSECommerceService&AWSAccessKeyId=0F49XFHPQYWX91XK4K82&Operation=ItemLookup&ItemId=B0000AKI8I&ResponseGroup=Large
ただし、HTTPのレスポンスヘッダには
Content-Type:text/xml;charset=UTF-8
が入ってる。

ResponseGroupがないと何故かencoding属性は返ってくる。

http://webservices.amazon.co.jp/onca/xml?Service=AWSECommerceService&AWSAccessKeyId=0F49XFHPQYWX91XK4K82&Operation=ItemLookup&ItemId=B0000AKI8I
&Versionで古いのを指定してもだめ。というかAmazonが突然仕様を返るとは考えにくい。

要因2:encodingが省略されるとXMLHttpRequestのresponseText/responseXMLが文字化けする
encodingが省略されるときにどの文字コードで処理しようとしてるのかはわからない。。。文字化けしたbyteコードを調べればわかったかもしれないが、どの文字コードで処理してるのではなくどうしたら文字化けしないのかばかり調べてたから。。。

要因3:SongWidetはレビューとかを取るためにReponseGroupを指定する
ResponseGroupを指定しなければencoding属性がついて結果として文字化けしないんだけど、SongWidgetではAmazonのレビューとかを取得するためにResponseGroupを省略するという選択肢がない。。。

最終的な対応
とりあえずforumになんかないかと思って調べてみたものの有用な情報は見つからなかった。こういう問題のときの英語圏のforumほど切ないものはないよ。。。

仕方がないので今度は日本のYahoo! WidgetでAmazon関連のwidgetを探してみたところ、文字化けを修正していた人がいたのでそれを参考にさせてもらった。

参考にしたWidget:
今日の新刊情報
# いぬさんありがとうございました!
結論から言うと、GETではなくPOSTを使い、リクエストをpostBodyに突っ込めばとencodingが返ってきて文字化けしない。

SongWidgetの場合、prototype.jsを経由しているの参考にならないが・・・対応コード

    var ajax = new Ajax.Request(url, {
method:'post',
postBody: postBody,
onComplete:this.onAjaxFetchContentComplete.bind(this),
onFailure:this.onAjaxFetchContentFailure.bind(this),
}
);

タイミング的にはYWE(Yahoo Widget Engine) 4.5で挙動が変わったと考えるのが自然なんだけど・・・確かYahoo.comで4.5がリリースされたときに動作確認した気がするんだけど・・・(YWEはなんか知らないがいつも日本はUSからかなり遅れてリリースされる)、それは気のせいなのか、日本のYWEだけ起きるのか今となってはわからないし、もうどっちでもいい。それが分かったところでYWEを直せないからさー。

Amazon ECS Simple Store in PHPを触ってみる

いまさらですが、Amazon ECS Simple Store in PHPを触ってみました。

http://developer.amazonwebservices.com/connect/entry.jspa?entryID=498
にあるecs-php-demo.zipをダウンロードして解答して配置。とりあえずローカル(xampp)で動かしてみます。

Call to undefined function: curl_init()

のエラー。む。デジャヴ?。パーティション切り直したときにリカバリしたからでした。curlを有効にします。

C:\xampp\php\php.iniの
extension=php_curl.dll
のコメントアウトをはずします。

さらに、httpd.confの適当なところに以下を入れます。

# For PHP 5 do something like this:
LoadModule php5_module "C:/Program Files/xampp/php/php5apache2.dll"
AddType application/x-httpd-php .php
PHPIniDir "C:\xampp/php/"

Apacheを再起動します。

動きました。

Janne Da ArcをMusicで検索するとちゃんとヒットしました。しかし、phpを見ているといくつか修正が必要なところがありました。

まず

define('KEYID','YourAccessKeyIdHere');
define('AssocTag','YourAssociateTagHere');

に自分のAccessKeyIdとAssociateTagに置き換えます。

次にこのままだとUSのAmazonの検索になっているので

define('BaseURL', 'ecs.amazonaws.jp');


define(‘KEYID’,’YourAccessKeyIdHere’);の上あたりに入れて

ecs.amazonaws.com

".BaseURL."

に置換する(5カ所)と日本のAmazonと連携できます。

最後に

<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">

を<title>の上に入れます。

# ブラウザは日本語があると勝手にShift-JISって解釈しちゃうことがあります。

それでもまだ商品価格が$だったり、PurchaseURLがとれなくてCheckoutに進めなかったり動かないところがあるようですが、それはまた気が向いたら調べます。

phpファイルは下記にアップしました。

http://labs.makotokw.com/sandbox/aws/ecs-php-demo/SimpleStore.php