cakephp amazon api 商品検索
題名にcakephpを入れたけど特にcakephpだからやり方変わるとかないです。
amazon apiを使うには申請が通る必要があります。
登録しましたー>使います!ではないです。
登録した?ー>売上上げた?ー>コンテンツ沢山ある?->API_KEYどうぞって流れです。
ということでAPI使うより申請通すほうが大変です。はい。
SDKダウンロードしてやる方法もありましたが、今回はファイル作ってコピーしました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
class AmazonApiController extends Controller { public function getAmazonData($item=null) { $amazonKeys = Configure::read( 'AmazonKey' ); $searchItemRequest = new SearchItemsRequest (); $searchItemRequest->PartnerType = "Associates"; $searchItemRequest->PartnerTag = 'hogehogePartnerTag'; $searchItemRequest->Keywords = $item->name; $searchItemRequest->SearchIndex = "All"; $searchItemReques ->Resource ["Images.Primary.Small","ItemInfo.Title","Offers.Listings.Price"]; $host = "webservices.amazon.co.jp"; $path = "/paapi5/searchitems"; $payload = json_encode ($searchItemRequest); $awsv4 = new AwsV4 ( 'hogehogeAccessKey', 'hogehogeSecretKey'); $awsv4->setRegionName("us-west-2"); $awsv4->setServiceName("ProductAdvertisingAPI"); $awsv4->setPath ($path); $awsv4->setPayload ($payload); $awsv4->setRequestMethod ("POST"); $awsv4->addHeader ('content-encoding', 'amz-1.0'); $awsv4->addHeader ('content-type', 'application/json; charset=utf-8'); $awsv4->addHeader ('host', $host); $awsv4->addHeader ('x-amz- target','com.amazon.paapi5.v1.ProductAdvertisingAPIv1.SearchItems'); $headers = $awsv4->getHeaders (); $headerString = ""; foreach ( $headers as $key => $value ) { $headerString .= $key . ': ' . $value . "\r\n"; } $params = [ 'http' => [ 'header' => $headerString, 'method' => 'POST', 'content' => $payload ] ]; $stream = stream_context_create ( $params ); $fp = @fopen ( 'https://'.$host.$path, 'rb', false, $stream ); $response = @stream_get_contents ( $fp ); return $response; } } class SearchItemsRequest { public $PartnerType; public $PartnerTag; public $Keywords; public $SearchIndex; public $Resources; } class AwsV4 { private $accessKeyID = null; private $secretAccessKey = null; private $path = null; private $regionName = null; private $serviceName = null; private $httpMethodName = null; private $queryParametes = array (); private $awsHeaders = array (); private $payload = ""; private $HMACAlgorithm = "AWS4-HMAC-SHA256"; private $aws4Request = "aws4_request"; private $strSignedHeader = null; private $xAmzDate = null; private $currentDate = null; public function __construct($accessKeyID, $secretAccessKey) { $this->accessKeyID = $accessKeyID; $this->secretAccessKey = $secretAccessKey; $this->xAmzDate = $this->getTimeStamp (); $this->currentDate = $this->getDate (); } function setPath($path) { $this->path = $path; } function setServiceName($serviceName) { $this->serviceName = $serviceName; } function setRegionName($regionName) { $this->regionName = $regionName; } function setPayload($payload) { $this->payload = $payload; } function setRequestMethod($method) { $this->httpMethodName = $method; } function addHeader($headerName, $headerValue) { $this->awsHeaders [$headerName] = $headerValue; } private function prepareCanonicalRequest() { $canonicalURL = ""; $canonicalURL .= $this->httpMethodName . "\n"; $canonicalURL .= $this->path . "\n" . "\n"; $signedHeaders = ''; foreach ( $this->awsHeaders as $key => $value ) { $signedHeaders .= $key . ";"; $canonicalURL .= $key . ":" . $value . "\n"; } $canonicalURL .= "\n"; $this->strSignedHeader = substr ( $signedHeaders, 0, - 1 ); $canonicalURL .= $this->strSignedHeader . "\n"; $canonicalURL .= $this->generateHex ( $this->payload ); return $canonicalURL; } private function prepareStringToSign($canonicalURL) { $stringToSign = ''; $stringToSign .= $this->HMACAlgorithm . "\n"; $stringToSign .= $this->xAmzDate . "\n"; $stringToSign .= $this->currentDate . "/" . $this->regionName . "/" . $this->serviceName . "/" . $this->aws4Request . "\n"; $stringToSign .= $this->generateHex ( $canonicalURL ); return $stringToSign; } private function calculateSignature($stringToSign) { $signatureKey = $this->getSignatureKey ( $this->secretAccessKey, $this->currentDate, $this->regionName, $this->serviceName ); $signature = hash_hmac ( "sha256", $stringToSign, $signatureKey, true ); $strHexSignature = strtolower ( bin2hex ( $signature ) ); return $strHexSignature; } public function getHeaders() { $this->awsHeaders ['x-amz-date'] = $this->xAmzDate; ksort ( $this->awsHeaders ); $canonicalURL = $this->prepareCanonicalRequest (); $stringToSign = $this->prepareStringToSign ( $canonicalURL ); $signature = $this->calculateSignature ( $stringToSign ); if ($signature) { $this->awsHeaders ['Authorization'] = $this->buildAuthorizationString ( $signature ); return $this->awsHeaders; } } private function buildAuthorizationString($strSignature) { return $this->HMACAlgorithm . " " . "Credential=" . $this->accessKeyID . "/" . $this->getDate () . "/" . $this->regionName . "/" . $this->serviceName . "/" . $this->aws4Request . "," . "SignedHeaders=" . $this->strSignedHeader . } private function generateHex($data) { return strtolower ( bin2hex ( hash ( "sha256", $data, true ) ) ); } private function getSignatureKey($key, $date, $regionName, $serviceName) { $kSecret = "AWS4" . $key; $kDate = hash_hmac ( "sha256", $date, $kSecret, true ); $kRegion = hash_hmac ( "sha256", $regionName, $kDate, true ); $kService = hash_hmac ( "sha256", $serviceName, $kRegion, true ); $kSigning = hash_hmac ( "sha256", $this->aws4Request, $kService, true ); return $kSigning; } private function getTimeStamp() { return gmdate ( "Ymd\THis\Z" ); } private function getDate() { return gmdate ( "Ymd" ); } } |
公式の丸々コピーでは勿論うまくいかないです。
まずリージョンを変更するために、多分公式では$awsv4->setRegionName(“us-east-1”);になっている所を
$awsv4->setRegionName(“us-west-2”);に変更します。
最後に仕様としてアマゾンは検索結果を全部返します。
仮に検索に一致した商品がない場合でも少しでも引っかかる「まったく違う商品」を返すので、そこを気をつける必要アリです。
この投稿へのトラックバック
トラックバックはありません。
- トラックバック URL
この投稿へのコメント