Amazon Product Advertising API 5.0 (PA-API v5)をNode-REDから使う

PA-APIv5のコード
今年に入るまでぜんぜん気づいていなかったのですが、アマゾンアソシエイトで商品情報の検索に使うAmazon Product Advertising API(PA-API)のバージョンが5.0になったそうです。そして古いバージョン4は3月9日までで使えなくなります。
大急ぎでバージョン5.0への移行を行いました。

アマゾンアソシエイトのProduct Advertising API(PA-API)のバージョンが5.0になり古い4.0がそのうち使えなくなります。
バージョン4.0の頃はNode-REDでリクエストのクエリーを自力で署名していました。
関連記事:Amazon Product Advertising APIのテスト実行ツールを使ってみる
このとき続きを書くような事を言ってましたが書いてませんね・・・

このブログはGoogleのBloggerというブログサービス上にあります。自前のサーバーではないのでPA-APIなどの処理は別のサーバを用意する必要があります。そこでRaspberry Piをサーバにしてブログ用のサービスをNode-REDで作っています。

Node-REDとはデータドリブンで記述するプログラム環境です。中身はNode.jsです。つまりjavascriptです。httpの通信など非同期な処理をグラフィカルなインターフェースで見通しよく記述できます。

PA-APIバージョン4ではリクエストを自前で作って処理していましたが、バージョン5のリクエスパラメータがどうなっているのか把握できないのでAmazon謹製のSDKを使うことにします。

PA-API v5を試す

PA-APIを使うにはアクセスキーを取得する必要があります。この記事ではこのあたりの事は書きません。他のサイト様におまかせ。

簡単にPA-API v5を試すにはスクラッチパッドが良いでしょう。
Product Advertising API 5.0 Scratchpad
https://webservices.amazon.co.jp/paapi5/scratchpad/index.html
バージョン4の時と同じですね。リクエストパラメータを色々試してResponse typesのJSON responseがどうなるかを見て感じを掴みます。
しかしRequest detailsのSigned Requestは何を表しているのかわかりません。Signed Requestとはアクセスキーでハッシュ化したリクエストなのですが、バージョン4の頃は表示されたURLをコピーしてブラウザで開くとレスポンスが得られました。ですが、バージョン5ではリクエストのメソッドがPOSTになったのでURLを入れても動くはずがないのです。

Signed Requestの作り方自体はバージョン4の時と同じようです。リクエストパラメータが変わったのとヘッダーも署名しなくてはいけないようです。しかし、リクエストパラメータやヘッダーをどこまで入れればいいのかが良くわかりません。
リクエストの時刻の表記が少し変わったみたいです。お尻に"Z"をつけるようになったようです。

PA-APIにリクエストを送る回数には制限があります。売上がないとリクエスト可能な回数がどんどん減っていきます。スクラッチパッドを使うのも数十回くらいと思っておきましょう。

SDKを使う

スクラッチパッドで感じを掴んだらSDKを使ってみます。
Using SDK
https://webservices.amazon.com/paapi5/documentation/quick-start/using-sdk.html
SDKには4つの言語が用意されています。
PHP, Java, Node.jsとPythonです。
自前でブログサービスを動かしていればPHPやJavaを使う方が多いでしょう。最近はPythonでサービスを動かす人もいるでしょう。私はWebのクライアントとサーバで言語が異なるのは嫌なのでNode-REDでNode.jsのSDKを使います。
それぞれSDKのダウンロードリンクがありますのでダウンロードします。

SDKを所定の場所に配置し動かせるようにしたらサンプルコードを試します。
Integrating with SDK
https://webservices.amazon.com/paapi5/documentation/with-sdk.html
リクエストクエリーを作ってリクエストを送る関数を呼ぶだけです。

Node-REDで使う

Node-REDで使う例を書いておきます。こういう記事はアクセス数がものすごく少ないので詳細は書きません。大雑把な手順だけ備忘録として書いておきます。

Raspberry PiでNode-REDを動かしてPA-API v5のSDKを動かします。RaspbianではあらかじめNode-REDが入っていますが、バックアップやバージョンアップに備えてDocker上で動くようにした方がメンテナンスが楽です。
関連記事:Docker ComposeでNode-REDとnginxを動かしてみる
上の関連記事のようにNode-REDを動かすとnodered1ディレクトリをコピーしておけば他のコンピュータへも新しいOSへも簡単に移行ができます。
このNode-RED上でPA-API v5のSDKを動かようにします。

先のnodered1ディレクトリにSDKをダウンロードして展開します。nodered1ディレクトリの下にpaapi5-nodejs-sdkというディレクトリを作りSDKを展開します。
mkdir paapi5-nodejs-sdk
cd paapi5-nodejs-sdk
wget https://webservices.amazon.com/paapi5/documentation/assets/archives/paapi5-nodejs-sdk-example.zip
unzip paapi5-nodejs-sdk-example.zip
nodered1ディレクトリでunzipしないように注意します。package.jsonなど同じ名前のファイルがあり、上書きしてしまうとNode-REDの環境が壊れてしまいます。

SDKをインストールします。Node-REDコンテナで行います。コンテナのbashを起動します。
docker exec -u root -it xxx_nodered1_1 bash
paapi5-nodejs-sdkディレクトリでインストールします。
cd /data/paapi5-nodejs-sdk
npm install
exit
と実行します。署名に使うハッシュ関数ライブラリなどが追加で入ります。
ここまではNode.jsとしてのインストールです。次にNode-REDのfunctionノードで使えるようにします。
nodered1ディレクトリへ戻ります。
cd ..
settings.jsファイルをエディタで開きます。
nano settings.js
下の方にfunctionGlobalContextとある部分があるのでそこでSDKの場所を書いておきます。
functionGlobalContext: {
        // os:require('os'),
        // jfive:require("johnny-five"),
        // j5board:require("johnny-five").Board({repl:false})
        paapi5:require('./paapi5-nodejs-sdk/src/index.js')
    },
保存してNode-REDコンテナを再起動します。

サンプルコードを動かす

サンプルのsampleSearchItemsApi.jsを動かしてみます。Node-REDなのでそのままは動きませんがfunctionノードにほぼそのまま書けば動きます。
Node-REDでfunctionノードを配置し編集します。先頭に
var ProductAdvertisingAPIv1 =new global.get('paapi5');
と追加します。functionノードではrequireが使えません。requireはsettings.jsに書いておかなくてはなりません。そしてfunctionノードではglobal.getで呼び出します。
これでPA-API v5のSDKを使えるようになりました。
sampleSearchItemsApi.jsの残りの行をfunctionノードに追加します。

最低限の動作はするようになりました。ですが結果が表示できません。アマゾンへリクエストは飛ぶので不用意に実行しないでください。リクエストの回数制限があるのをお忘れなく。

フローへ応答を流す

サンプルコードに少し追加してフローとしてリクエストのレスポンスが渡るようにします。
functionノードの最後に
return ;
と追加します。これは何も値を返さない事を意味しますのでfunctionノードは値をフローへ流しません。フローは止まったままになります。
アマゾンへのリクエストの結果が返ってきたらそれをフローへ流します。その設定を書きます。SDKのアマゾンへのリクエストはcallback関数を使っています。responseが返った時の処理部分の最後に
node.send(msg);
node.done();
と書きます。これでレスポンスが返ったあとにフローへmsgが流れます。もちろんmsgにリクエストの結果を設定してからです。エラーで返った部分も同様に書きます。

レスポンスをmsgに追加する時に注意点があります。結果とエラーはsearchItemsResponseとerror変数に入ってますがそのままmsgへ追加できません。エラーでNode-REDが落ちます。半日くらい結果が取得できないと悩んでしまいました。
結果を代入するには次のように書きます。
msg.payload = JSON.parse(JSON.stringify(searchItemsResponse));
node.send(msg);
node.done();
errorも同様です。昔に同じようにハマった気がしますがすぐ忘れます。

まとめ

大慌てでPA-API v5を動くようにしてみました。3月9日に延びましたが先週までは2月11日までに切り替えろと言っていましたからね。
ヘッダーとリクエストの署名手順を把握できないのでSDKを使うことにしました。
Node.jsのSDKをNode-REDのfunction関数から呼べるようにしました。

amazon flow
今回のSDKを組み込んだアマゾン用フローは上のような感じになります。同じリクエストを何回も送らないように一定期間キャッシュしておく構成になってます。

リクエストクエリーが変わっただけでバージョン4との違いが実感できません。
レスポンスにアダルト向けアイテムがある場合は削除しているのですがIsAdultProductキーが有ったり無かったりで条件判断の面倒さも変わっていません。

ごりごりAPIを使うわけでもないので手間がかかった割には恩恵が何もないバージョンアップです。まだ突貫コードなのでエラー処理など地味な改良をしなくてはなりませんし、レスポンスのキーに何が含まれるのか少しずつ調べていかなくてはなりません。

コメント

最近のコメント

Threaded Recent Comments will be here.