GoogleAppsScriptでAmazonの「Product Advertising API」を使う

JavaScriptでの利用方法はいくつか記載があったものの、Google Apps Scriptでの利用方法が見つからなかったため、作成した時のメモ。

API利用のための準備

以下を参考に作成。
AjaxTower - サービス利用の準備

1.Amazon.comにアカウントを作成
2.メール到着

メールには2つの記載があるが、今回は前者を利用しないため、キーの取得作業のみ実施

  • アソシエイトプログラムへの参加
  • キーの取得


■2012/03/12追記
2011/10/26の仕様変更によりAssociateTagパラメータの必須化したため、アソシエイトプログラムへの参加も必須となった。
そのため、別途アソシエイトプログラムへ参加すること。
2012/03/12追記ここまで

 

3.キーの取得

メールで示されたリンクより、以下を取得。

  • アクセスキー
  • シークレットアクセスキー

 

署名やパラメーターの検討

JavaScriptの場合、いくつかライブラリを使用しなければならないのに加え、Amazonのシークレットアクセスキーをどのように隠すのかが悩みどころ。

ただ、GoogleAppsのAppsScriptでは以下の点が楽。

  • 署名時のHMAC-SHA256は、メソッド「computeHmacSha256Signature()」を利用すればよい
  • BASE64エンコードは、メソッド「base64Encode()」を利用すればよい
  • Spreadsheetを公開しなければ、Amazonのシークレットアクセスキーの要件を満たす(はず)

 

サンプルコードの作成

以下の作業を行い、動作を確認。

1.新しいスプレッドシートを作成し、以下のように入力

 

2.範囲を作成
範囲名 SearchRange
セルの範囲 A2:D9

 

3.スクリプトの作成

ASINから、タイトル・定価・中古価格を取得するサンプルコードは以下。

自分はWin7x64 + Firefox6で作成したが、Apps Scriptのエディタが日本語では激重になったため、コメントも含めてすべて半角とした。


■2012/03/12追記
AssociateTagが必須パラメータとなったため、その部分を追加。
2012/03/12追記ここまで

function main(){
  
  sheet = SpreadsheetApp.getActiveSpreadsheet();
  range = sheet.getRangeByName("SearchRange");
  
  for (i = 1; i < 3; i++){
    
    var cellAsin = range.getCell(i,1).getValue();
    var xmlData = getXML_(cellAsin);
    var title = getTitle_(xmlData);
    var amountPrice = getAmountPrice_(xmlData);
    var usedPrice = getUsedPrice_(xmlData);
    
    range.getCell(i,2).setValue(title);
    range.getCell(i,3).setValue(amountPrice);
    range.getCell(i,4).setValue(usedPrice);
  }
}


// Private getXML_
function getXML_(asin)
{
  var timestamp = getTimeStamp_();
  var accessKey = "00000000000000000000";  //Your Access Key
  var secretKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";  //Your Secret Key
  var associateID = "NNNNN";  //Your Associate ID   2012/03/12Add
  
  var url = "webservices.amazon.co.jp";  // Search In Japan
  //var url = "webservices.amazon.com";  // Search In USA
  
  var parameters = {
      "Service":"AWSECommerceService",
      "AWSAccessKeyId":accessKey,
      "Operation":"ItemLookup",
      "ItemId":asin,
      "AssociateTag":associateID,   // 2012/03/12Add
      "ResponseGroup":"ItemAttributes,OfferSummary",
      "Timestamp":timestamp
  };
  
  var array = [];
  for(var parameter in parameters){
    array.push(parameter + "=" + encodeURIComponent(parameters[parameter]));  //Encode
  }

  array.sort();
  
  var urlParameter = array.join('&');
  var request = "GET" + "\n" + url + "\n" + "/onca/xml" + "\n" + urlParameter;
  
  var signature = Utilities.base64Encode(Utilities.computeHmacSha256Signature(request, secretKey));  //HMAC-SHA256 -> base64
  var urlSignature = "&Signature=" + encodeURIComponent(signature);

  
  var response = UrlFetchApp.fetch("http://" + url + "/onca/xml?" + urlParameter + urlSignature);
  //Browser.msgBox(response.getContentText());  //--> responseData
  
  return Xml.parse(response.getContentText(), false);  // Get XMLData
}


// Private getTitle_
function getTitle_(xmlData){
  var title = xmlData.getElement().getElement("Items").getElement("Item").getElement("ItemAttributes").getElement("Title").getText();  
  return title;
}

// Private getAmountPrice_
function getAmountPrice_(xmlData){
  var price = xmlData.getElement().getElement("Items").getElement("Item").getElement("ItemAttributes").getElement("ListPrice").getElement("Amount").getText();
  return price;
}

// Private getUserPrice_
function getUsedPrice_(xmlData){
  var price = xmlData.getElement().getElement("Items").getElement("Item").getElement("OfferSummary").getElement("LowestUsedPrice").getElement("Amount").getText();
  return price;
}


// Private getTimeStamp
function getTimeStamp_(){
  
  var dates = new Date();
  
  var year = dates.getUTCFullYear();
  var month = paddingZero_(dates.getUTCMonth() + 1);   //Month:0to11
  var day = paddingZero_(dates.getUTCDate());
  var hour = paddingZero_(dates.getUTCHours());
  var minute = paddingZero_(dates.getUTCMinutes());
  var second = paddingZero_(dates.getUTCSeconds());
  
  return year + "-" + month + "-" + day + "T" + hour + ":" + minute + ":" + second + "Z";
}


// Private paddingZero_
function paddingZero_(value){
  
  //Get Last 2 Characters
  return ("0" + value).slice(-2);
}

 

結果