O'Reilly Hacks
oreilly.comO'Reilly NetworkSafari BookshelfConferences Sign In/My Account | View Cart   
Book List Learning Lab PDFs O'Reilly Gear Newsletters Press Room Jobs  


 
Buy the book!
Amazon Hacks
By Paul Bausch
August 2003
More Info

HACK
#95
Create an Amazon AIM Bot
Chat with some Perl code to get book prices via AOL Instant Messenger
The Code
[Discuss (14) | Link to this hack]

The Code

Create a file called asin_bot.pl and include the following code. The code that communicates with Amazon is based on a previous hack (), though the AWS request is made inside the on_im subroutine, when a message comes in. Instead of printing out to the console, it saves the results in a variable, $detail, and sends it as an instant message back to the person sending the message.

#!/usr/bin/perl
# asin_bot.pl
#
# An AIM bot that given an ASIN will
# return the product title and price.
# Usage: perl asin_bot.pl

use warnings;
use strict;
use Net::AIM;
use LWP::Simple;
use XML::Simple;

# fill in your relevants.
my $aim_un = 'insert AIM username';
my $aim_pw = 'insert AIM password';
my $dev_key = 'insert developer token';
my $af_code = 'insert affiliate tag';

# create an AIM connection
# and return it for usage.
my $aim = new Net::AIM;
$aim->newconn(Screenname=>$aim_un,Password=>$aim_pw)
                or die "Cannot connect to AIM.";
my $conn = $aim->getconn();

# Set up a handler for messages.
$conn->set_handler('im_in', on_im);
$conn->set_handler('error', on_error);
print "Logged on to AIM!\n\n";
$aim->start;

# incoming.
sub on_im {

    my ($aim, $evt, $from, $to) = @_;
    my $args = $evt->args();
    ($from, my $friend, my $msg) = @$args;

    # cheaply remote html.
    $msg =~ s/<(.|\n)+?>//g;

    # if this isn't an ASIN sized string, 
    # send back an error message stating such.
    $aim->send_im($from, "I only accept ASINs.") unless length($msg) eq 10;

    # create our final URL.
    my $url = "http://xml.amazon.com/onca/xml3?t=$af_code". 
              "&dev-t=$dev_key&type=lite&f=xml&".
              "AsinSearch=$msg";

    my $content = get($url);
    my $response = XMLin($content);
    my $detail = $response->{Details}->{ProductName}||"no title";
    $detail   .= " $response->{Details}->{OurPrice}";
    $aim->send_im($from, $detail);
}

# oops!
sub on_error {
    my ($self, $evt) = @_;
    my ($error, @stuff) = @{$evt->args()};

    # Translate error number into English.
    # then filter and print to STDERR.
    my $errstr = $evt->trans($error);
    $errstr =~ s/\$(\d+)/$stuff[$1]/ge;
    print "ERROR: $errstr\n";
}

Notice that inside the on_im subroutine, the script checks to make sure the incoming message is exactly 10 characters, the length of an ASIN. Otherwise it sends back the message, "I only accept ASINs." It's a good idea to set up rules like this for any kind of queries you allow. Bots should always send a message about success or failure.


O'Reilly Home | Privacy Policy

© 2007 O'Reilly Media, Inc.
Website: | Customer Service: | Book issues:

All trademarks and registered trademarks appearing on oreilly.com are the property of their respective owners.