Hack95CreateanAmazonAIMBot
ChatwithsomePerlcodetogetbookpricesviaAOL
InstantMessenger.
AOLInstantMessengerisn'tthemostlikelyplaceyou'llneed
Amazonbookdata,butthatdoesn'tmeantheapplications
aren'tfuntoconnect.WithPerlandtheNet::AIMmodule,you
canhaveyourownchatteringbook-botrequestingAmazon
informationforyou.
95.1WhatYouNeed
Firstyou'llneedtheNet::AIMlibrary,whichprovidesallthe
functionsforloggingintoAIMandsendingorreceiving
messages.Youcanfinditatactivestate.com
(Togetajumpstartoncoding,checkoutthe
tutorialsatWiredBots
(Theyhavesome
fullyfunctionalsamplebotsandlotsofexamplecodefor
workingwithNet::AIM.
You'llalsoneedanAIMscreennameandpasswordforyournew
virtualassistant,alongwithascreennameforyourselfifyou
don'thaveone;signupat.
95.2TheCode
Createafilecalledasin_bot.plandincludethefollowingcode.
ThecodethatcommunicateswithAmazonisbasedona
previoushack([Hack#80]),thoughtheAWSrequestismade
insidetheon_imsubroutine,whenamessagecomesin.Instead
ofprintingouttotheconsole,itsavestheresultsinavariable,
$detail,andsendsitasaninstantmessagebacktotheperson
sendingthemessage.
#!/usr/bin/perl
#asin_bot.pl
#
#AnAIMbotthatgivenanASINwill
#returntheproducttitleandprice.
#Usage:perlasin_bot.pl
usewarnings;
usestrict;
useNet::AIM;
useLWP::Simple;
useXML::Simple;
#fillinyourrelevants.
my$aim_un='insertAIMusername';
my$aim_pw='insertAIMpassword';
my$dev_key='insertdevelopertoken';
my$af_code='insertaffiliatetag';
#createanAIMconnection
#andreturnitforusage.
my$aim=newNet::AIM;
$aim->newconn(Screenname=>$aim_un,Password=>$aim_pw)
ordie"CannotconnecttoAIM.";
my$conn=$aim->getconn();
#Setupahandlerformessages.
$conn->set_handler('im_in',on_im);
$conn->set_handler('error',on_error);
print"LoggedontoAIM!\n\n";
$aim->start;
#incoming.
subon_im{
my($aim,$evt,$from,$to)=@_;
my$args=$evt->args();
($from,my$friend,my$msg)=@$args;
#cheaplyremotehtml.
$msg=~s/<(.|\n)+?>//g;
#ifthisisn'tanASINsizedstring,
#sendbackanerrormessagestatingsuch.
$aim->send_im($from,"IonlyacceptASINs.")unlesslength(
#createourfinalURL.
my$url="
"&dev-t=$dev_key&type=lite&f=xml&".
"AsinSearch=$msg";
my$content=get($url);
my$response=XMLin($content);
my$detail=$response->{Details}->{ProductName}||"notitle
$detail.="$response->{Details}->{OurPrice}";
$aim->send_im($from,$detail);
}
#oops!
subon_error{
my($self,$evt)=@_;
my($error,@stuff)=@{$evt->args()};
#TranslateerrornumberintoEnglish.
#thenfilterandprinttoSTDERR.
my$errstr=$evt->trans($error);
$errstr=~s/\$(\d+)/$stuff[$1]/ge;
print"ERROR:$errstr\n";
}
Noticethatinsidetheon_imsubroutine,thescriptchecksto
makesuretheincomingmessageisexactly10characters,the
lengthofanASIN.Otherwiseitsendsbackthemessage,"Ionly
acceptASINs."It'sagoodideatosetupruleslikethisforany
kindofqueriesyouallow.Botsshouldalwayssendamessage
aboutsuccessorfailure.
95.3RunningtheHack
StartupAOLInstantMessengerandaddthevirtualscreen
nameyougaveyourbottoyourbuddylist.Whenyourun
asin_bot.pl,youshouldseethebotappearamongyouronline
buddies.SendamessageconsistingofonlyanASIN,andyou
shouldgetthebooktitleandAmazonpriceback.This
conversationisshowninFigure6-9.
Figure6-9.TalkingASINswithanAIMbot
Notexactlystimulatingconversation,butexpandingits
vocabularyissimplyamatterofaddingAmazonrequestsand
responsestothescript.
Hack80ProgramAWSwithPerl
AlightweightXMLparserisallyouneedtoworkwith
Amazon'sdatainPerlscripts.
Evenwithoutwrapperfunctions,retrievingdatadirectlyfrom
AmazonwithXML/HTTPisstraightforward.Youjustneedthe
abilitytograbafilefromtheWebandparsetheresults.
80.1WhatYouNeed
ThishackrequirestwocommonPerlmodules:onetohandlethe
HTTPrequestandanothertoparsetheXML.OncetheAmazon
requestURLisbuilt,LWP::Simplehandlessendingtherequest
andreceivingtheXMLwithaget()function.Youcanfindout
moreaboutLWP::SimpleatCPAN
( />XML::Simple(isalightweightXMLparser.It
providesaquick,simpleinterfaceforworkingwithXML.
ManyISPshavebothofthesemodulesinstalledalready.Ifnot,
youcaninstallthemwithCPAN:
perl-MCPAN-eshell
cpan>installXML::Simple
IfyouhaveaWin32system,youcaninstallthemfromthe
commandlinewiththepackagemanagerlikethis:
ppminstallXML::Simple
80.2TheCode
Thiscodeacceptsacommand-lineargumentandbuildsan
AmazonURLwiththeargumentasthekeyword.Createthefile
amazon_http.plwiththefollowingcode:
#!/usr/bin/perl
#amazon_http.pl
#AtypicalAmazonWebAPIPerlscriptusingtheXML/HTTPinter
#Usage:amazon_http.pl<keyword>
#YourAmazondeveloper'stoken
my$dev_key='insertdevelopertoken';
#YourAmazonaffiliatecode
my$af_tag='insertassociatetag';
#Takethekeywordfromthecommand-line
my$keyword=shift@ARGVordie"Usage:perlamazon_http.pl
#AssembletheURL
my$url=".$af_tag.
"&dev-t=".$dev_key.
"&type=lite&f=xml&mode=books&".
"KeywordSearch=".$keyword;
usestrict;
#UsetheXML::ParserandLWP::SimplePerlmodules
useXML::Simple;
useLWP::Simple;
my$content=get($url);
die"Couldnotretrieve$url"unless$content;
my$xmlsimple=XML::Simple->new();
my$response=$xmlsimple->XMLin($content);
foreachmy$result(@{$response->{Details}}){
#Printoutthemainbitsofeachresult
print
join"\n",
$result->{ProductName}||"notitle",
"ASIN:".$result->{Asin}.",".
$result->{OurPrice}."\n\n";
}
Theforeachattheendofthecodeloopsthroughtheresults
fromAmazonandprintsthemout.Bychangingthevariable
names,youcanchangetheinformationthatisdisplayed.For
example,changingOurPriceonthelastlinetoListPrice
woulddisplaythatpriceinsteadofAmazon'sprice.
80.3RunningtheHack
Fromthecommandline,callthescriptlikeso:
perlamazon_http.plhacks
Besuretoenclosephrasesormultiplekeywordsinquotes,like
so:
perlamazon.http.pl"googlehacks"