Skip to main content

Getting started using Amazon Product Advertizing API in C#

Amazon Product API is a set of web services that are available for developers, to interact with Amazon e-commerce website (more details are available on Amazon website):
  1. You can extract information about product: Get information about products, reviews, information about the company selling these items.
  2. Create a fully functional shopping cart
The main goal for developers here is to advertise items sold on amazon website and get a commission from sales they generate through the associate program.(more details available on Amazon website)
Bellow I'm going to show a simple example on how to use this API:

Pre-requisites:

  1. Become an Associate
  2. Become a Product Advertising API Developer
Before coding you can try the web client provided by amazon: Product Advertising API Scratchpad

Using the API:

Now we can start coding. For this example I'm just going to create console app that calls the web service to retrieve some information:
1. List products for a given category
2. Get Prices for each product

1. Prepare the project:

Create a new console app:















Add service reference (http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl):




















Show all files:











3. Add Authentication logic:

Amazon rely on a hashing function to authenticate users of the web service:
Each client is assigned an identifier (access key) and a secret key (Known by the user and amazon only, communicated only once). Communication steps:
1. The user sends a hash of a specific section of the header (this the signature) alongside the access key, the hash function uses the secret key.
2. When the request is received by amazon web service it will extract the secret key corresponding to the requests access key, and hash the header and compare it to the request signature.
This a brief description, more details available on Amazon's website: (This code is inspired from the implementation available at this link)

1. Add IEndPointBehavior Implementation:

public class AmazonSigningEndpointBehavior : IEndpointBehavior
{
 private string accessKeyId = "";
 private string secretKey = "";

 public AmazonSigningEndpointBehavior(string accessKeyId, string secretKey)
 {
  this.accessKeyId = accessKeyId;
  this.secretKey = secretKey;
 }

 public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime clientRuntime)
 {
  clientRuntime.MessageInspectors.Add(new AmazonSigningMessageInspector(accessKeyId, secretKey));
 }

    public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher) { return; }
    public void Validate(ServiceEndpoint serviceEndpoint) { return; }
    public void AddBindingParameters(ServiceEndpoint serviceEndpoint, BindingParameterCollection bindingParameters) { return; }
}


2. Add Header Class:

public class AmazonHeader : MessageHeader
    {
  
        private string name;
        private string value;

        public AmazonHeader(string name, string value)
        {
            this.name = name;

            this.value = value;
        }

        public override string Name { get { return name; } }

        public override string Namespace { get { return "http://security.amazonaws.com/doc/2007-01-01/"; } }

        protected override void OnWriteHeaderContents(XmlDictionaryWriter xmlDictionaryWriter, MessageVersion messageVersion)
        {
            xmlDictionaryWriter.WriteString(value);
        }

    }

3. Add Message Inspector:


public class AmazonSigningMessageInspector : IClientMessageInspector
    {
        private string accessKeyId = "";
        private string secretKey = "";

        public AmazonSigningMessageInspector(string accessKeyId, string secretKey)
        {
            this.accessKeyId = accessKeyId;
            this.secretKey = secretKey;
        }

        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            // prepare the data to sign
            string operation = Regex.Match(request.Headers.Action, "[^/]+$").ToString();
            DateTime now = DateTime.UtcNow;
            string timestamp = now.ToString("yyyy-MM-ddTHH:mm:ssZ");
            string signMe = operation + timestamp;
            byte[] bytesToSign = Encoding.UTF8.GetBytes(signMe);

            // sign the data
            byte[] secretKeyBytes = Encoding.UTF8.GetBytes(secretKey);
            HMAC hmacSha256 = new HMACSHA256(secretKeyBytes);
            byte[] hashBytes = hmacSha256.ComputeHash(bytesToSign);
            string signature = Convert.ToBase64String(hashBytes);

            // add the signature information to the request headers
            request.Headers.Add(new AmazonHeader("AWSAccessKeyId", accessKeyId));
            request.Headers.Add(new AmazonHeader("Timestamp", timestamp));
            request.Headers.Add(new AmazonHeader("Signature", signature));

            return null;
        }

        public void AfterReceiveReply(ref Message reply, object correlationState) { }
    }

4. Client Code:


In this code we're using the ItemSearch method.
Each ItemSearch require a combination of parameters, in this case I'm using search index and browse node:
PCHardware 340832031 (Computers), the reference is available in amazon website.
Response group specifies the type information you want the webservice to return, for more details check the reference.






static void Main(string[] args)
        {
            AWSECommerceServicePortTypeClient srv = new AWSECommerceServicePortTypeClient("AWSECommerceServicePortUK");

        string accessKeyId = "Your access key";
        string secretKey = "Your Secret Key";
        string[] _responseGroup = new string[] { "ItemIds", "OfferSummary", "ItemAttributes" };
        srv.ChannelFactory.Endpoint.EndpointBehaviors.Add(new AmazonSigningEndpointBehavior(accessKeyId, secretKey));
            var response = srv.ItemSearch(new ItemSearch
            {
                AWSAccessKeyId = "Your Access Key",
                AssociateTag = "associate tag",
                Request = new ItemSearchRequest[] { new ItemSearchRequest
                {
                    SearchIndex = "PCHardware",
                     BrowseNode = "340832031",
                    ResponseGroup = _responseGroup,

                }},
            });
        }
If you run the client code it will fail, one more step is left, where we need to fix the auto generated code of the webservice proxy.
One way to do it is to search for all occurrences of ImageSet[][] and replace it by ImageSet[].

No you're ready, you  can retrieve the result and extract the information you need, more details on the response structure available here.






Comments

Popular posts from this blog

Understanding Monte Carlo Simulation C#

This method has been introduced to resolve numerically complex physics problems, such as neutron diffusion, that were to complex for an analytical solution. This method is based on generating random values for parameters or inputs to explore the behaviour of complex systems, now this method is used in various domains like: Engineering, science and finance. These approaches tend to follow a particular pattern: 1- Define a domain of possible inputs. 2- Generate inputs randomly from the domain using a certain specified probability distribution. 3- Perform a deterministic computation using the inputs. 4- Aggregate the results of the individual computations into the final result. Here is an example of using Monte Carlo simulation to approximate the value of Pi: In this case we have 2 parameters x,y which defines a location in the plane (e.g The picture on the left). We will calculate the probability to have a point in the 1/4 Circle area, with a radius of 1. To calculate Pi we...

Full Text Search using Entity Framework

I've been working on a project where I needed to implement full time search on one table. My current solution was based on SQL Server db and Entity Framework 6. I had two choices implement the full text search in C# or use the functionality available in SQL server, since the data was stored in SQL Server the obvious solution was to use the built in full text search. How this works: 1. You need to activate and configure the full text search: Activate on the sql server table by using SSMS, and specify which columns are going to be included. 2. To perform a full text search in a T-SQL query you have the choice between 2 Boolean functions: Contains and Freetext or two functions that returns 2 columns tables. In my case I need a function that could be used in a where clause (Boolean), and decided to use 'Contains'. For more details about the difference between Freetext and contains have a look at this article . 3. I need to instruct EF6 to generate a particular T-SQL stateme...

Twitter API and Microsoft Text Analytics API in Python

Since we are getting closer to the French presidential election, and that I'm working on a project that involves using social media API and sentiment analysis, I've decide to post an example that will use these technologies to try and give an idea about each major candidate popularity. Solution description: 1. Collect social media information related to each candidate: For this example the main source is Twitter. 2. Extract sentiment for each Candidate from the Twitter posts collected previously. Implementation: For a quick implementation I decided to use python, but I'll definitely post a C# version as well. Code: 1. Twitter Client code: The code is pretty basic, I'm streaming the posts to a text file in son, by applying a list of filters; the names of the candidates I've decided to include: #Import the necessary methods from tweepy library from tweepy.streaming import StreamListener from tweepy import OAuthHandler from tweepy import Stream #Vari...