Part36:Amazon Product Advertising APIを使ってみる

凛「今日集まってもらったのは他でもないにゃ」
海未「他も何も・・・」
希「思い当たる節が何もないんやけど?」
凛「こ、細かいことはどうでもいいにゃ!とにかく、ちょっとやりたいことがあってAmazonの商品情報を扱うAPIを叩くプログラムを作ってたんだよ」
希「なんでまた・・・」
凛「最近新商品の買い逃しが多いにゃ。だから、発売日に知らせてくれる仕組みがほしいなって思って」
海未「まあ、その需要は分かりますが・・・」
凛「それで、Amazon Product Advertising APIっていうのがあるから、Elixirから試しに使ってみたコードを紹介するにゃ」

凛「Mixでプロジェクト作るよ。mix new paatestとかして、まずはmix.exsに依存関係の追加にゃ」

凛「HTTPoisonっていうのがHTTP通信のパッケージで、他にもHTTPotionなんていうのもあったけど、なんとなく強そうだからHTTPoisonにしたよ」
海未「その判断根拠には色々と突っ込みたいところはありますが」
凛「もう1つは時間を扱うTimexっていうパッケージを使うにゃ」
希「ああ、時計メーカーの・・・」
凛「それ凛も思ったよ・・・」

凛「次はメインロジックの実装にゃ。AWSのアカウントとかは各自用意でお願いね」

凛「APIの仕様は公式ドキュメント見てもらうとして・・・」

Amazon Product Advertising API

凛「厄介なのがリクエストへの署名にゃ」
海未「ええと・・・TimestampとSignatureが必要で、SignatureはAWS秘密キーを元にしたbase64エンコードのHMAC_SHA256署名・・・確かに、難しそうです」
凛「それぞれtimestamp関数とsign関数に実装してあるけど、タイムスタンプの方はそんなに難しくないにゃ。Timexを使うとDateとかDateFormatとかのモジュールが使えるから」
海未「それで現在時刻を付けてやればいいのですね」
凛「ここで付ける時刻、日本時間じゃなくてGMTだから注意にゃ。最初Date.localでやってて、ずっとはまってて・・・」

希「となると、難題は署名の方やね」
凛「まずは、署名するときはパラメータがソートされてないといけないから、一旦マップにしてEnum.sortでソートしてからクエリストリングに戻してるんだよ」

凛「最終的にはこういう形のものが署名対象になるにゃ」

凛「ここから署名を生成するのが:crypto.hmacで、秘密鍵を使ってSHA256で署名を生成してるにゃ。あとはBASE64でエンコードしてやれば署名のできあがり」
希「んん、そこまで難しわけでもないんかな。分かってしまえば」
凛「ちなみに全般的にURIモジュール使ってるけど、これはURL文字列とそれを分解したマップの相互変換みたいなのをやってくれるモジュールにゃ。Elixirの標準機能だからドキュメントにも載ってるよ」

凛「結果がXMLで返ってくるんだけど、これを読む方が大変だったような気がするにゃ」
希「うん、全然読めへんわ」
凛「Erlangのxmerlっていうのを使ってるんだ。基本はDOMで、:xmerl_scan.stringで文字列からDOMツリーを構築できるよ。けど、ここでいう文字列は文字リスト、シングルクォートで囲う方の文字列にゃ」
海未「そういえば、文字列は2種類あるのでした」
凛「このxmerlで使う文字列は全部文字リストだと思えばよさそうにゃ」

凛「あとは、目的の要素をXPathで・・・:xmerl_xpath.stringを使うと、XPathを文字列で指定してノードのリストを取得できるよ」
海未「それで、ここのXPathもシングルクォートなのですね」
凛「うん。で、xmlElementとかxmlTextとかxmerlに用意されてる関数を使って、中身を読み出してあげるにゃ」
海未「最初の方でdefrecordしているものですね」

凛「xmlElement <node>, :contentみたいにすると、その要素の内容が取れるから、例えば<Title>ノードに入ってる値がほしければこれを使うとテキストノードが取れるよ」
希「まだテキスト自体ではないんやったね」
凛「テキストノードからテキストを読み出すのはxmlText <node>, :valueみたいにするにゃ」

凛「一応これで、ASINを指定すると商品名と発売日を取得できるようになったにゃ」
海未「なるほど、これを膨らませていけば、最初に言っていた通知の仕組みも作れそうですね」
凛「そのへんはまた、うまくできたらお話しするね」


LINEで送る
Pocket


返信を残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です