#!/usr/local/bin/perl -w # # This is an example of writing a VXML application for TellMe.com in Perl. # I wrote this because when I walk into a book, CD or DVD store, I # immediately forget what I own. Using my cell phone, I can call into # 1-800-555-TELL, select the book database, enter the ISBN number, and know # if I own it or not. I've built in some infra-structure for the CD and # DVD portion, but at the moment it only returns a 'Not implemented # message'. I'll prolly add this as I go on. # # To use it, you'll first need an account at www.TellMe.com. It's free, so # you should go get one now. As far as setting up the TellMe side, it's # pretty straight forward, and I don't want to explain it here, since they # may change it. Next, put the script in your favorite directory. I put # mine in /vxml off my docroot, and name it according to the extension it # will be assigned to from TellMe.com. Since I have multiple extensions, it # makes it easy to keep track of what scripts are associated with what # extensions. # # You'll need to create a database (I use mySQL) with the structure that's # at the __END__ section. It's a direct mysqldump of my Media database. # Set the variables below to the host, database name, etc. Security says # you should make sure that the user you allow to access the database only # has SELECT privledges. If someone manages to dump your script source, you # don't want a DB writable password being exposed. Don't forget to put a # index.html file in the directory also, so it's not browsable. # # Odds & ends: Some ISBN numbers have an 'X' in the 10th position. Since a # DTMF pad doesn't have 'X', we use '9'. If the script sees a '9' in the # 10th position it will check for both an entry ending in '9' and in 'X'. # If it finds both (and you'd be way out beyond the statistical norm if you # did), it will read back both titles. The help could no doubt be clearer, # but since only trained users are using it, you get what I needed as a # reminder. # # Requires the following modules: # CGI # DBI # # Copyright 2001(c) J.C.Wren jcwren@jcwren.com # A production of Twitching Monk Software # No rights reserved, use as you see fit. I'd like to know about it, though, just for kicks. # # 2001/03/23 - 1.00.00 - Initial release # # use strict; use CGI; use DBI; use Carp; # # Our script name. TellMe doesn't handle not having a script name correctly. # use constant cScriptName => '54529.pl'; # # Tune these for your database setup # use constant cDB_Host => 'localhost'; # Host for database use constant cDB_Database => 'Media'; # Database to use use constant cDB_Table_Books => 'Books'; # Table name use constant cDB_User => 'media'; # User name to access DB with use constant cDB_Pass => 'media'; # Our super-secret password (!) # # Action dispatch list # my %actionList = ('mainmenu' => \&function_mainmenu, 'books' => \&function_books, 'cds' => \&function_cds, 'dvds' => \&function_dvds, 'help' => \&function_help, ); my %actionListBooks = ('getisbn' => \&function_books_getisbn, 'lookup' => \&function_books_lookup, 'mainmenu' => \&function_books_mainmenu, ); # # Help for the clueless (or me, after two days of not using it) # my %helpList = ('mainmenu' => qq{Say books or press 1 for the book database. Say C dees or press 2 for the C D database. Say D V dees or press 3 for the D V D database. Hang up to exit system. End of help. }, 'getisbn' => qq{Say or type the 10 digit I S B N number. If the number has the letter X in it use 9, instead. Say menu or press star to return to the main menu, or hang up. End of help. }, 'unknown' => qq{Unknown help request. }, ); # # Main # { my $cgi = new CGI; $| = 1; $cgi->cache (1); my $goto = $cgi->param ('goto') || 'mainmenu'; $goto = 'mainmenu' if (!$actionList {$goto}); &{$actionList {$goto}} ($cgi); } # # Main menu (doncha love redundant comments?) # sub function_mainmenu { my $cgi = shift; write_headers ($cgi); print <<"ENDHERE";
} [dtmf-2 seedees] {
ENDHERE } # # Book handler # sub function_books { my $cgi = shift; my $option = $cgi->param ('option') || 'getisbn'; $option = 'getisbn' if (!$actionListBooks {$option}); &{$actionListBooks {$option}} ($cgi); } sub function_books_getisbn { my $cgi = shift; write_headers ($cgi); print <<"ENDHERE";
} ] ]]> 500 500
ENDHERE } sub function_books_lookup { my $cgi = shift; my $isbn = $cgi->param ('isbn') || 0; if (length ($isbn) != 10) { short_message ($cgi, "The I S B N entered was not 10 digits. Please try again.", 'books', 'getisbn'); } elsif ($isbn =~ m/[^0-9]/) { short_message ($cgi, "The I S B N must be all digits. Please try again.", 'books', 'getisbn'); } else { if (my $database = DBI->connect ("DBI:mysql:@{[cDB_Database]}:@{[cDB_Host]}", cDB_User, cDB_Pass)) { my $query = qq{SELECT Title,ISBN FROM @{[cDB_Table_Books]} WHERE ISBN='$isbn'}; $query .= qq{ OR ISBN='} . substr ($isbn, 0, 9) . qq{X'} if (substr ($isbn, -1, 1) eq '9'); my $cursor = $database->prepare ($query) or internal_error ($cgi, $database->errstr); $cursor->execute or internal_error ($cgi, $database->errstr); my $rows = $cursor->fetchall_arrayref; if (scalar @$rows) { if (scalar @$rows == 1) { short_message ($cgi, "I S B N present. Title is @$rows[0]->[0].", 'books', 'getisbn'); } else { my $titles = "Multiple I S B N matches. Titles are "; $titles .= $_->[0] . '1000