#!/fellow/monks.pl

On a PC in a different part of the house, I wanted to know when new email arrived in my mailbox. I did not want to reconfigure Outlook for that. This simple perl script comes to the rescue.

It will sleep for the specified number of seconds, and then play the specified wav file when a new message arrives.

#!c:/perl/bin/perl.exe -w use strict; use Mail::POP3Client; use Win32::Sound; my $precnt = 0; if(!$ARGV[0] || !$ARGV[1] || !$ARGV[2] || !$ARGV[3] || !$ARGV[4]) { print "Usage : $0 [server] [username] [password] [sleep time] [wav + file]\n"; exit(1); } while(1) { &daemon($ARGV[0],$ARGV[1],$ARGV[2]); print "Sleep for $ARGV[3]\n"; sleep($ARGV[3]); } sub daemon { my ($server,$user,$pwd) = @_; my $pop = new Mail::POP3Client( USER => "$user", PASSWORD => "$pwd", HOST => "$server" ); my $cnt = $pop->Count; $pop->Close; if($cnt == -1) { print "Error in connecting to the POP3 server...\n"; return; } print "You have $cnt new messages\n"; if($cnt > $precnt) { Win32::Sound::Play("$ARGV[4]"); Win32::Sound::Stop; } $precnt = $cnt; }

Thanks!

|\/| _. _ _  ._
|  |(_|_>_>\/| |
           /

Replies are listed 'Best First'.
Re: You've got mail!
by bgreenlee (Friar) on Jul 25, 2004 at 17:00 UTC
    To avoid the race condition CountZero mentions, maybe try storing the unique ids of all the messages in your mailbox and check for new messages by calling Uidl and comparing the results with what you have stored (I'm not sure if this gets unreasonably slow with a large message queue). Something like:
    my %msg_uid_hash = (); ... sub daemon { ... $new_msg_cnt = 0; # check current uid list against our last one my @msg_uid_list = $pop->Uidl(); foreach my $uid (@msg_uid_list) { $new_msg_cnt++ if !$msg_uid_hash{$uid}; } # replace the old uid list with the current one %msg_uid_hash = map {$_ => 1} @msg_uid_list; ... }

    Update: actually, using the message count isn't so much a race condition as a flawed model; messages can easily be deleted, making the message count a poor indicator of new messages.

    Brad

Re: You've got mail!
by graff (Chancellor) on Jul 25, 2004 at 14:24 UTC
    I like that. Just one nit-pick: why not supply "reasonable defaults" for the @ARGV values? (So you don't have to remember/retype all that stuff every time you run it.)

    And of course, since you have it working now, you might as well comment out the print "Sleep for $ARGV[3]\n" -- that output gets tiresome, doesn't it?

    update: Also, since you are printing reports to STDOUT about errors and incoming mail, it might be useful to include a time-stamp with each print-out:

    print "New incoming mail detected at ", scalar(localtime), "\n";

      Getopt::Long provides a handy method of doing default options.

      use Getop::Long; my %opt = ( defaults => are, set => here ); GetOptions( \%opt, defaults, overriden, here );

      --
      "A long habit of not thinking a thing wrong, gives it a superficial appearance of being right." -- Thomas Paine
      naChoZ

Re: You've got mail!
by CountZero (Bishop) on Jul 25, 2004 at 16:05 UTC
    Suppose the following scenario:
    • First call of daemon: it finds 5 new messages on the server and plays the "you have mail"-sound.
    • You go to your "Outlook"-box and download these mails and switch off Outlook.
    • 2 new mails arrive before daemon gets called again.
    • daemon gets called again and finds 2 messages on the server which is less than the 5 messages it has in $precnt, so the sound does not get played and you miss these messages which required you to answer within 2 minutes to claim your 1,000,000 $ prize in the Internet Sweepstake!
    I think it is called a race condition.

    One other remark: would it be easier on the computer resources to have daemon run by a cron-type job rather than keep it running and sleeping? Probably depend on how quickly it has to run again.

    One final comment: some ISP's don't like it that their mail-servers get polled at a too high rate (several times every few minutes). I once got cut-off for 10 minutes by just doing that.

    CountZero

    "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

Re: You've got mail!
by chanio (Priest) on Jul 26, 2004 at 04:35 UTC
    Hi,

    Very nice!

    I have read somewhere, that it is not good to read a mail server with two programs at the same time, you should call your email agent from the program and get it sleeping while Outlook (4 example) is working.

    It would be nice to take all your parameters away into a simple config.ini file. Then, it would be easy to add parameters, such as time to sleep, perhaps, some waited emails to check, some time to wait for the minimum number of emails until you raise the message if you have less new emails.

    Question, wouldn't it be better to check a constantly opened Outlook account for new arrived messages instead of checking your mail server? It is sure a better way of constantly downloading emails, and it should deal with connections, polling and others in a more professional way (I guess :). And even filtering spams that don't matter at your 'Got Email' message.

    Besides, try using Freeware Incredimail mail agent that announces 'Got Email' with any number of Flash screens and sounds.

    .{\('v')/}
    _`(___)' __________________________