cybozu developer network

カテゴリー内の他の記事

kintoneのレコード詳細ページからAmazon商品データを参照するテクニック

(著者:アクアビット 長井 祥和)

kintone アプリで資産管理を行いたい、という要望はよく聞きます。その際、既存サイトのデータが参照できたら便利ですよね。
例えば商品データを参照したい場合、Amazon APIを通して取得したいといった要件は十分考えられます。
本稿では、kintoneの詳細レコード上に、Amazon APIから取得したデータを表示する方法について紹介します。

Index

はじめに

本件を実現するために必要なものがあります。それは例えば・・・

  • パソコン
    ノートでもデスクトップでもよいですが、スマートフォンや俗にいうガラパゴス携帯、またタブレットからの利用は考慮していません。
  • パソコンのブラウザ
    本件ではGoogle Chrome、Firefox、Internet Explorer9、11で検証しています。その他のブラウザでは予測不可能な動作に遭遇するかもしれません。
    もちろん、他のブラウザでも動けばそれに越したことはありません。ノウハウはぜひ教えて頂ければ^^;)・・・。とりあえずこの4種でお願いします。
  • phpの動作するサーバー
    今回の検証で使用したレンタルサーバーは、iniも変更できず、pearなどのライブラリも利用できません。SSLも専用でははく共用SSLを使用しています。
    phpネイティブだけを頼りに構築しているので、サーバー間の動作差異はあまりないと思えます。
    なお、レンタルサーバのOSはUnix系で、Apache 2.2で動いているものを使いました。phpのバージョンは5.3.2です。
  • kintoneの画面ですが、最低限3つのフィールドが必要です。
    今回は下記のように準備しました。
    フィールドタイプ フィールド名 フィールドコード 説明
    文字列(1行) ISBNコード F_Isbn ISBNコード用
    スペース - Space_Image Amazon情報表示用スペース
    スペース - Large_Image 画像表示用スペース
    (※以下の結果画面は違うフィールドも多数入っていますが)

それらを満たしkintoneにカスタマイズを加えると、以下のように詳細画面にAmazonからの呼び出し結果が表示できるようになります♪

Amazonで必要な情報の取得

今回作成するサンプルに必要な、Access Key ID と Secret Access KeyトラッキングIDの3種類の情報を取得しましょう。
取得方法については、今回割愛させていただきます。

phpを利用したAmazonへのパラメーターの生成方法について

最初に一言申し添えておかねばなりません。
なぜkintoneからAmazonの情報を取得するのにphpを介さなければならないか、について。

このTipsをご覧の皆様は、すでに有識者の皆様が執筆された、秀逸なTipsの数々にも目を通されたことでしょう。
Tipsの中には

外部APIの同期処理をつかってみよう!

他サービスのAPIからデータを取得してkintoneに表示してみよう

という2つのkintoneから外部APIに接続するTipsも挙げられています。
私も本稿を書くにあたって参考にしました。ありがとうございますm(_ _)m。

これらのTipsはkintoneのJavaScript APIを使用しています。
JavaScript内に外部APIのURLを直接書き込み、その結果を表示させる方法です。
一方、Amazon APIを呼び出す際のURLですが、その中には全章で取得したAmazonの「Access Key ID」「Secret Access Key」「トラッキングID」の3種類から生成した署名文字列を含める必要があります。
つまり、署名文字列を生成するにあたっては、JavaScript内に「Access Key ID」「Secret Access Key」「トラッキングID」という機密情報を埋め込まねばなりません。
それを避けるために、外部のphpに署名文字列の生成や機密情報の扱いを任せようというのが狙いです。

能書きが長くなりました。それでは実装に移らせて頂きます。

まず、kintoneに埋め込むJavaScript内で呼び出すAPIのURLを記します。

url:'https://***. akvabit.jp/akvabit.jp/********/AmazonBookInfo.php' + '?code=ISBN&no='+Isbn,

パラメーターは ?code=ISBN&no='+Isbn としています。
Isbnとあるのは、kintoneのフィールドに入力された本のIsbnを変数化したものです。
Amazon認証情報に関する情報の一切はJavaScriptからは省かれています。
次にパラメーターを受け取ったAmazonBookInfo.phpの中身を示します。

JavaScriptに値を返すための各種ヘッダの記述と、Amazonから情報を取得する本体のphpであるSetBookByAmazon.phpの呼び出しが書かれています。
ヘッダについてはGoogle ChromeとFirefox、そしてInternet Explorer 9で正常にデータが渡せることが確認できています。
これは環境によって違いますので、工夫してみてください。
特に4番目のヘッダで application/xml となっています。これはJavaScriptに対して渡すデータの種類を xmlとして規定する部分ですから、重要です。

最後にパラメーターを受け取ったSetBookByAmazon.phpの中身を示します。

これで動くはずです。
あ、Access Key IDとSecret Access Key IDとアソシエイトTagはこんなふざけたものではなく、きちんとAmazonで取得した文字列を使って下さいね^^。
また、その他書き換える文字としては以下があります。

  • define('AssociateTag','anatanoiddesu-99'); の赤字の部分を前章で取得した「トラッキングID」で置き換えてください。
  • define('AccessKeyId','ICHIBANSAISHINNOAKUSESUKII’);  の赤字の部分を前章で取得した「Access Key ID」で置き換えてください。
  • define('SecretAccessKey','DAIJINADAIJINASIIKURETTOAKUSESUKIIDESUNENN');   の赤字の部分を前章で取得した「Secret Access Key」で置き換えてください。  

それ以外は、この内容でデータが取得できるはずです。
このphpをサーバーにアップし、URLをアドレス欄に打ち込んでみてください。例えば以下のように。

https://***.akvabit.jp/akvabit.jp/*******/AmazonBookInfo.php ?code=ISBN&no=4800207770

どうでしょう。XML形式でデータが表示されたのではないでしょうか。そう、あの本の情報が\(^o^)/

なお、渡すパラメータや取得できる情報の種類はかなり多岐に亘っています。
本稿ではISBNのみに焦点を当て、ISBNから取得可能な書籍情報のみについて紹介したいと思います。
上に挙げたphpの内容もISBNによる取得に対応しています。
Amazon Products Advertising APIの単一商品取得の ItemLookUpはこちらのリンクが公式情報となっています。

上のphpの内容に ・・・・・・あ といった記述があります。
くれぐれもこの部分はphpファイルからは除いてくださいね。動かなくなってしまいますので^^。

以下は、その あ~か についての説明を記します。

 ・・・・あ その上の行と共にJavaScriptから渡ってきた変数が格納される場所です。

 ・・・・い Amazonから取得する情報の種類を指定します。ItemAttributesは商品詳細、Imagesは画像情報。

       このように複数の種類を指定する場合 , カンマでつなげます。

 ・・・・う 指定した各種パラメーターをそのパラメーター名称で並び替えます。署名作成時に必要な処理です。

 ・・・・え 指定した各種パラメーターをエンコードします。RFC3986で定められた方法に準じています。

 ・・・・お 署名文字列の生成部分です。ここで初めてSecret Access Keyの活躍の場が与えられます。ハッシュ

       関数によって、容易には結果から元々の文字列が推測できないような文字列に変換されます。

 ・・・・か 組み立てられたUrlから取得した文字列を取得します。結果文字列はXML形式で帰ってきています。

 ・・・・き 帰ってきた文字列を表示します。この表示処理によって、呼び出し元へ文字列が戻されます。

これで、Access Key ID と Secret Access Key、トラッキングIDの3種類の情報とISBNからAmazonの書籍情報がデータ取得できました。
あとはこれをJavaScriptで加工するだけです。あと一息です!もうしばらくご辛抱ください!!

最後に、こちらで作成した SetBookByAmazon.php と AmazonBookInfo.php ですが、サーバーにアップする際、http://の領域ではなく、https:// の方にアップされたほうが良いかと存じます。

なぜかというと、呼び出し元となるkintoneのURLは https://******.cybozu.com/k/12/ とhttps://から始まります。
これに対し、上記2つのphpファイルが http:// から始まる領域から始まると、ブラウザによっては好ましからざる動きをするからです。

kintoneからのJavaScript呼び出しとJavaScript内でのAjaxの記載について

ここでは、kintoneへのJavaScriptの適用方法その他の説明は割愛します。
はじめよう kintone JavaScript API の記述が大変参考になります。私も最初はここから勉強しました^^

ただし、本稿でもまた、前書きを書かねばなりません。恐縮ですm(_ _)m

それは、kintoneからAmazon API呼び出しのタイミングについてです。
冒頭でも挙げたように、本稿ではレコードの詳細画面でAmazon情報を呼び出すのが目的です。しかし、レコード詳細画面の編集時画面での実装については、本稿では触れていません。ご了承下さい。

また、Amazonからの呼び出し自体にも、全く問題がない訳ではありません。
Amazon側にリクエストを続けて投げると、Http/1.1 Service Unavailable のエラーが返ってくる場合があります。
なので、リクエストはほどほどに・・・ということなのでしょうか。
このエラー対策については、jQueryのAjaxで、Errorハンドラから再帰呼び出しを試したのですが、calleeとuse strictが両立できていません。
なので、時間をおいて再実行ということでご了承ください。

最後にクロスドメイン制約についてです。
本稿の目指す実装は、*****.cybozu.com から ****.jp/ または *****.co.jpといった違ったドメインのサーバーにAjaxリクエストを発行します。
が、そのような別ドメインへのリクエストは、セキュリティ上脆弱になりかねないため、環境によっては簡単に通信ができないようになっています。
本稿ではphpからkintoneへ渡すデータ形式をXMLにしました。
JSONPを使えばクロスドメイン制約についても解決できるようです。

あと、jQueryの呼び出しも必要となります。
kintoneのアプリ設定画面から、サイボウズが提供するCDNの参照を忘れずに。

さて、気を取り直して実装開始^^

以下に、AmazonCallBookInfoDetail.jsの内容です。
200行あるすべてのコードを開示しながら、適宜解説を加えていきたいと思います。

6行目…
実行しているブラウザの種別をここで取得しています。呼び出し先のURLがhttpsから始まっても、画像はhttpが返されることがあり、それを防ぐために一部ブラウザによって画像のアドレスを変更しています。

 15-17行目…
本稿で実装する内容では、ユーザ入力データからのサニタイズ処理はあまりありません。
唯一この場所で実施しています。
数値がどうかをチェックしていますが、ISBNの末尾一桁のチェックディジット結果が X となる場合があり、その場合のみ許可しています。

 24行目…
先に紹介しましたが、codeとIsbnという2つのパラメーター以外に、nowというパラメーターも追加しています。
実はnowパラメーターは以下の処理では使われていません。
投げるリクエストURLを常に変化させないとInternet Explorer上でうまく値が戻ってこないという情報から、このような記載を設けています。

26行目…
キャッシュをOFFにしないとInternet Explorerで正常に戻ってこないという情報を基に追加しました。

また、AmazonからのXMLデータで気を付けるべき点があります。
それは書籍とkindle書籍の場合です。
kindle書籍はISBN項目を持っていないのですが、Amazonの仕様でISBNに対してデータ検索結果にkindleデータも含まれます。
XML上では、2つの<Item>タグが紐付いています。
その場合は、JavaScript側で<Item>タグ内をループさせるのですが、<ISBN>タグの有無で判別しています。

大体のXMLデータの構造がおわかり頂けましたでしょうか。
先に紹介したAmazonのガイドですが、項目の位置はこちらでガイドされています。
ただし、各項目がどのように商品データに関連付いているかはわかりません。
なので、上に挙げた項目以外にも存在することもあるかと思います。ご容赦ください。

82行目からは、XMLのデータが格納された変数dataに対し、<item>タグの要素を検索し、
更にその中で<ImageSet>タグを検索しています。
そして必要な情報を、ごにょごにょと取得後innerHTMLを使用して書き込むべき文字列を生成しています。

最後に、JavaScriptを完成させ、あとはこれをkintoneのアプリ管理画面からアップすれば完成!

のはずですが・・・・・実は先ほどのJavaScriptの仕組みでは動かないブラウザがあります。
それは。。。。Internet Explorerです。
jQueryのAjax関数では、Internet Explorer 9より前のバージョンに対応しておらず、別の仕組みを経由してAjaxを実装する必要があります。
なんてこった!またまたクロスドメインではまることになりました。

Googleで検索を行うと、いくつかInternet Explorer 9以前のバージョンでのクロスドメイン実装についてのJavaScriptが存在します。
私もいくつか試しましたが、私の環境ではそのうち動いたのが以下の1つだけでした。

  MoonScript/jQuery-ajaxTransport-XDomainRequest                      

なので、今回はこちらのJavaScriptも使わせて頂きました。ありがとうございます。
結果として、kintone上にアップするJavaScriptファイルは3種類となりました。
最初にjQuery本体。
次にIE9以前対応のクロスドメイン制約対応のJavaScript。
最後に今回作成したJavaScriptです。

これで完成です。

と。このように表示が出来ましたでしょうか。
レコードを移動すると新たなレコード先でAmazonから呼び出されたデータが表示されます。
ただし、あまり短い時間で呼び出すとAmazonからの応答が途絶えてしまうことがあります。
その場合は F5でリロードを行って頂ければと思います。

外部認証が必要な複雑なAPIを呼び出す場合、このような方法があるよ、ということを理解頂ければ、さまざまなケースで実装が可能になり、kintoneをより一層ご活用頂くことができることでしょう。
ぜひ、お試しください。ただしくれぐれも過度なAmazonへのリクエストはお控えください。1時間当たりのリクエスト回数も上限が定められているようですし・・・・

本件について、文責は全て私にあります。もし内容についての御質問などございましたら、お寄せいただければ、時間の許す限り、回答させて頂くようにいたします。

 

 

記事に関するフィードバック

記事のコメント欄は記事に対するフィードバックをする場となっております。
右の記事フィードバックのためのガイドを参照してコメントしてください。
記事のリンク切れなど、気になる点がある場合も、こちらのフォームからフィードバックいただけますと幸いです。

サインインしてコメントを残してください。