ポジティブ丸メガネ

2年目エンジニアです。

Swift4でAmazon Product Advertising APIを叩く

前提

AWS

  • AccessKeyId
  • SecretKey
  • AssociateTag

はご自身で取得してください。

ドキュメント

ポータルページには下記リンクが張ってあるんですが、これは古いです。注意して下さい。 Product Advertising API

僕は下記を見ながら作りました。英語ですが頑張りましょう。 docs.aws.amazon.com

やること

ISBNから本のアフィリエイトリンクを取得したい。ItemLookupを使って取ってくるようにしているので、各自使いたい方法に置き換えてください。大変なのは、Signatureを作る部分だと思うので。

コード

Signatureを作るためにHMAC SHA256で署名しないといけないので、CryptoSwiftを使わせてもらいました。 github.com

import Foundation
import CryptoSwift

extension Date {
    func jpDate(_ format: String = "yyyy/MM/dd") -> String {
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "ja_JP")
        formatter.dateFormat = format
        return formatter.string(from: self)
    }
}

extension String {
    func urlAWSQueryEncoding() -> String {
        var allowedCharacters = CharacterSet.alphanumerics
        allowedCharacters.insert(charactersIn: "-")
        if let ret = self.addingPercentEncoding(withAllowedCharacters: allowedCharacters ) {
            return ret
        }
        return ""
    }
    
    func hmac(key: String) -> String {
        guard let keyBytes = key.data(using: .utf8)?.bytes, let mesBytes = self.data(using: .utf8)?.bytes else {
            return ""
        }
        let hmac = try! HMAC(key: keyBytes, variant: .sha256).authenticate(mesBytes)
        return Data(bytes: hmac).base64EncodedString()
    }
}

let isbn = "isbn number"

// parametersはkey名で昇順にソートされていなければならない
// 僕はめんどくさかったので主導で雑にやってます
var parameters = "AWSAccessKeyId=" + "YOUR ACCESS KEY"
parameters += "&AssociateTag=" + "YOUR TAGS"
parameters += "&IdType=" + "ISBN"
parameters += "&ItemId=" + isbn
parameters += "&Operation=" + "ItemLookup"
parameters += "&SearchIndex=" + "Books"
parameters += "&Service=" + "AWSECommerceService"
parameters += "&Timestamp=" + Date().jpDate("yyyy-MM-dd'T'HH:mm:ssZZZZZ").urlAWSQueryEncoding()

let target = "GET\nwebservices.amazon.co.jp\n/onca/xml\n\(parameters)"
let signature = target.hmac(key: "YOUR SECRET KEY").urlAWSQueryEncoding()
let url = "https://webservices.amazon.co.jp/onca/xml?\(parameters)&Signature=\(signature)"

// urlにGETリクエスト送ればXMLが返ってくる

レスポンスがXMLっていうめんどくささがあり、非常にだるい。今回はYahoo Japan様の下記を使ってParseしたけど。 github.com

おすすめ

楽に実装するなら、Proxy的なAPIを作って、そのAPIに署名やXMLのパースをやらせるのが早いかと。以前それでやったんですが、なんとなくSwiftでやってみたくなったんですよね。やらなきゃよかったと思ってます。結構手間取りました。

Node.jsならnpm packageにProduct Advertising APIを叩くものも、XMLをParseしてくれるものも揃っているので、もっと楽だと思います。

おわり。

参考

非常に助かりました。

Amazon API 経由で書籍を検索する