single.php

Amazon Product Advertising API で商品(ASIN)検索を使ってみる

先回、APIのサンプルコードを使ってキーワードを使ったAmazon内の商品検索を試してみましたが、実際にアフィリエイトリンクを作るためには商品名やASINコードを使った検索が必要なので、試してみました。

Amazon APIの続き

先回、APIの参考資料内の[開発者ガイド]で公開されているサンプルコードでキーワードを使った商品検索ができました。

しかし、今回はキーワードではなくASINなどの識別コードでAmazon内の商品を検索したいのでキーワード以外で検索する必要があります。

利用条件が厳しいAPI

Amazon Product Advartising APIは無料で利用ができますが、利用するための条件があります。

中でも重要なのが、これ

売上実績の発生がない場合は、PA-APIの利用開始はできません。
また、発送済み商品売上が過去30日以内に発生していない場合、PA-APIをご利用いただけなくなる恐れがございます。

Amazon アソシエイト ヘルプより

1日で利用できるAPIの回数などの制限もありますが、Amazonアフィリエイトで継続的に売上実績を上げる必要があります。

なので、過去30日以内に1円でもアソシエイトリンクを使った売上が無いとAPIのテストもできないという状況になります。

これからAmazonのアフィリエイトを始める場合はAPIの利用は厳しい。

詳しくは[Amazon アソシエイト ヘルプ|その他のお知らせ]をご覧ください。

サンプルコードの修正

開発者ガイドで公開されているサンプルを使ってASINコードを指定してAmazonの商品検索するPHPを利用する手順です。

1. 公開されている表示された2つのサンプルコードを、[getItem.php]と[awsv4.php]として保存します。

[getItem.php]
<?php

/**
 * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

$searchItemRequest = new SearchItemsRequest ();
$searchItemRequest->PartnerType = "Associates";
// Put your Partner tag (Store/Tracking id) in place of Partner tag
$searchItemRequest->PartnerTag = <PARTNER_TAG>;
$searchItemRequest->Keywords = "Harry";
$searchItemRequest->SearchIndex = "All";
$searchItemRequest->Resources = ["Images.Primary.Small","ItemInfo.Title","Offers.Listings.Price"];
$host = "webservices.amazon.com";
$path = "/paapi5/searchitems";
$payload = json_encode ($searchItemRequest);
//Put your Access Key in place of <ACCESS_KEY> and Secret Key in place of <SECRET_KEY> in double quotes
$awsv4 = new AwsV4 (<ACCESS_KEY>, <SECRET_KEY>);
$awsv4->setRegionName("us-east-1");
$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 = array (
        'http' => array (
            'header' => $headerString,
            'method' => 'POST',
            'content' => $payload
        )
    );
$stream = stream_context_create ( $params );

$fp = @fopen ( 'https://'.$host.$path, 'rb', false, $stream );

if (! $fp) {
    throw new Exception ( "Exception Occured" );
}
$response = @stream_get_contents ( $fp );
if ($response === false) {
    throw new Exception ( "Exception Occured" );
}
echo $response;

class SearchItemsRequest {
    public $PartnerType;
    public $PartnerTag;
    public $Keywords;
    public $SearchIndex;
    public $Resources;
}
?>
[awsv4.php]
<?php

/**
 * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

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 . "," . "Signature=" . $strSignature;
    }

    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" );
    }
}
?>

2.[getItem.php]の先頭部分を次の様に編集します。

<?php
  require 'awsv4.php';
/**
 * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *

8. 続けて[getItem.php]の中段部分を次の様に編集します。

 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

$getItemRequest = new GetItemsRequest ();
$getItemRequest->PartnerType = "Associates";
// Put your Partner tag (Store/Tracking id) in place of Partner tag
$getItemRequest->PartnerTag = <PARTNER_TAG>;[Amazonアソシエイトで利用しているID(assosicate-22など)]
$getItemRequest->ItemIds = ["商品のASINコード(B09KMGQG5Yなど)]"];
$getItemRequest->ItemIdType = "ASIN";
$getItemRequest->Resources = ["Images.Primary.Small","ItemInfo.Title","ItemInfo.Features","Offers.Summaries.HighestPrice","ParentASIN"];
$host = "webservices.amazon.com";
$path = "/paapi5/getitems";
$payload = json_encode ($getItemRequest);
//Put your Access Key in place of <ACCESS_KEY> and Secret Key in place of <SECRET_KEY> in double quotes
$awsv4 = new AwsV4 (<ACCESS_KEY>, <SECRET_KEY>); 先に取得した[アクセスキー]と[シークレットキー]
$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.GetItems');
$headers = $awsv4->getHeaders ();

3. アイテム検索するためのクラスをファイルの末尾に追加します。

class GetItemsRequest {
    public $PartnerType;
    public $PartnerTag;
    public $ItemIds;
    public $ItemIdType;
    public $Resources;
}

4. PHPが動作する環境に、2つのファイルを保存してブラウザーで[getItem.php]を表示します。

5. 画面に検索された結果が表示されます。

{"ItemsResult":{"Items":[{"ASIN":"B09KMGQG5Y","DetailPageURL":"https://www.amazon.co.jp/dp/B09KMGQG5Y?tag=maggothand-22&linkCode=ogi&th=1&psc=1","Images":{"Primary":{"Small":{"Height":75,"URL":"https://m.media-amazon.com/images/I/41mvqe1FS3L._SL75_.jpg","Width":62}}},"ItemInfo":{"Features":{"DisplayValues":["B09KMGQG5Y"],"Label":"Features","Locale":"ja_JP"},"Title":{"DisplayValue":"Western Digital 8TB WD ブルー PC ハードドライブ HDD - 5640 RPM SATA 6 Gb/s 128 MB キャッシュ 3.5インチ - WD80EAZZ","Label":"Title","Locale":"ja_JP"}},"Offers":{"Summaries":[{"Condition":{"Value":"New"},"HighestPrice":{"Amount":36629.0,"Currency":"JPY","DisplayAmount":"¥36,629"}}]}}]}}

とりあえず、公式ページのサンプルを少し編集することでアフィリエイトで必要なリンク情報を取得するAPIの利用ができました。

まとめ

今回は、Amazon アソシエイトプログラムの[Amazon Product Advertising API]を利用して、ASINコードから商品を検索するための手順について書きました。

Amazonアソシエイツのツールバーで画像付きの商品ページへのリンクが作成できなくなるので、自前でアフィリエイトリンクを作るためにAPIを習得しています。

AWS上に用意されたGetItemsメソッドを使って、ASINコードから商品情報を習得することができました。

ツールバーでの生成が終了するまでに、少し猶予期間ができたのでAPIを使ってリンクを作成する方法を探していきます。

[Amazon Product Advertising API]でASINコードから商品検索したい人の参考になれば幸いです。

スポンサーリンク

最後までご覧いただき、ありがとうございます。

コメントを残す

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