Thursday, June 11, 2009

Flex Amazon Image Search

Here's a sample application that queries the Amazon Web Services to retrieve images for CDs, DVDs, books, video games, software, etc. E.g. if you want to find the album cover for a music CD.

Here is my example - it lets you search for music, dvds, books, etc by title (and an artist for music cds, and an author for books) and then shows the resulting images ordered into 5 different image sizes. Double click an image to open the jpg in a new window.
** As Amazon keeps updating their web service this example will stop working. Please view the source code to see how it used to work!


Here are the steps to get it working in your Flex Builder:
  1. Download the source code from the example above (Right click "View Source", then click the download link in the bottom left corner of the page)
  2. Sign up for an Amazon Web Service Account
  3. Copy your Access Key ID and put it in the services/AmazonItemSearch.as file
  4. Full details and the API for the Amazon Web Services are located here

I found this website which helped me get started:
Finding cover art with Flex and Amazon WebServices.


** August 24th, 2009 Update **
As of August 15th Amazon now requires that all requests are signed. The example above has been updated to include this change, so you can View Source to see the code.

Here are some links that I found very useful in fixing the problem:** One final note
When signing the request, I tried using the com.adobe.crypto.HMAC and com.adobe.crypto.SHA256 classes that come with the as3corelib project to create the signature, but it didn't work because the signature needs to be Base64 encoded. So instead I modified those two classes very slightly to make it work.

I also included a TestSignature.mxml application which was useful to make sure that the signature matched what the Signed Request Helper output.

8 comments:

Mike said...

Really liked this example.

Modifying it to also search for images using EAN / Barcodes, slightly different API call, uses ItemType=EAN and ItemId=[bar code]

Once that's done, I'm going to try and get some more meaningful information displayed, like Title, Price etc.

Thanks again for your example

Nuk said...

Nice example..

but there're some errors on accessing AWS.. can u explain ?

Thanks.

Chris Callendar said...

Thanks for the comment, you are right, it was broken. As of August 15th 2009 the Amazon web services now require you to sign the requests, and I wasn't doing that.

I've update the example above and added some more information in the main blog entry.

Cheers,
Chris

Nuk said...

Thanks again,

I've tested your updated codes(without any changes except AWSAccessKeyId and SecretKeyID) but I couldn't see any results like your demonstrated example. Maybe my codes couldn't get any results from AWS. (I've got error messages like "Can't access to Null object reference or methods..." with popup window shows original and signed request messages)

another question is, what's the difference between as2corelib's HMAC and SHA256 class and your modified classes ?

Thanks,

Chris Callendar said...

Hi,

That's weird that your codes don't work. I'd suggest logging into the AWS website and verifying that your codes haven't changed (my codes had changed when I logged in yesterday, no clue why).
https://aws-portal.amazon.com/gp/aws/developer/account/index.html?ie=UTF8&action=access-key

I've made comments in the HMAC and SHA256 classes to indicate what I changed from the original.
But to summarize - I changed 2 lines in HMAC, one was to default to the SHA256 algorithm (instead of MD5) and the other was the last line of the hashBytes() function to call the SHA256.hashBytesToBase64() function (instead of the hashBytes() function).
The SHA256.hashBytesToBase64() is the new function that I added. It is identical to the SHA256.hashToBase64() function except that it takes in a ByteArray instead of a String. So really the only overall change is that HMAC.hash() now returns a Base64 encoded String which is needed for the Amazon signature.

Nuk said...

Chris,

finally, I've succeeded with modifying signing method using "Base64Encoder" and "HMAC.hash() with SHA256 method".

but, there's another problem. Sometimes my sample returns "FaultEvent" on continous trying to request. e.g it's succeed or fail with same keyword.

Help again, I couldn't solve this issue.

Thanks,

Chris Callendar said...

Can you tell me more about the FaultEvent that you're getting? Can you trace out the error?
e.g. trace(event.fault);

There is often some information in FaultEvent that tells you what is going wrong. Usually there is the complete URL of the request that was sent to the Amazon Web Service, and so a trick I've found is to copy that complete url (it contains all the parameters like the signature) and paste it into the addressbar of a new browser window and then you'll see the real error in XML. It's annoying how Flex's FaultEvent's hide the real problem.

I guess the other thing that could be going wrong is the request is timing out? But I doubt it, in my sample code I set the timeout to 20 seconds... (see the AmazonItemSearch.send() function).

Chris

Anonymous said...

faultCode:Channel.Security.Error faultString:'Security error accessing url' faultDetail:'Destination: DefaultHTTP'