merrymonk has asked for the wisdom of the Perl Monks concerning the following question:

I want to set up a system where using a ‘standard’ application a user enters data which is
then e-mailed to me. I then want to automatically read this e-mail using a Perl
application. I know how to set up an application that attempts such a read every
defined number of minutes. However I do not know how to start with an application
that can read the e-mail from my service provider. (I do not want to rely of things
like Outlook since, as far as I know I cannot get the automation that I need). Can
any Monk help with any of questions I should ask my service provider, some
‘starter’ code and links to explanations about how this can be achieved?
  • Comment on Automatically getting and reading e-mails

Replies are listed 'Best First'.
Re: Automatically getting and reading e-mails
by moritz (Cardinal) on Aug 27, 2008 at 15:26 UTC
    You can receive mails from mail servers either with pop3 or imap. knows lots of modules to do this.

    You can also use something like fetchmail to feed them into a local mail box, and read these local files. There's more than one way to do it ;-)

      fetchmail looks more than interesting but as ever with
      such things I am not sure where to start.
      Therefore it would be fantastic if a simple
      Perl exmaple was available that included fetchmail
      .

        The best place to start is to read the documentation provided with fetchmail. Under the heading 'CONFIGURATION EXAMPLES' you will find some examples.

        Note that fetchmail just forwards the emails to your local mail server. On linux there is always one running, don't think there is one on a windows machine (and probably we are talking about windows since you said something about Outlook)

        Because of that leocharres script might be a better starting place for you

        As we all can easily understand, your problem, namely to send and read email with perl, is just so specific and rarely occurring that it is very unlikely that anybody has ever had it, let alone asked about it here. But just in case you wanted to check if by some incredible coincidence an event with some ridiculously low probability in the universe did happen and someone did ask a similar question, I recommend you try some specific Super Search.

        --
        If you can't understand the incipit, then please check the IPB Campaign.
Re: Automatically getting and reading e-mails
by leocharre (Priest) on Aug 27, 2008 at 15:42 UTC
    This one is old, it may be of interest. It reads my mail and checks what I want to discard. I don't suggest it for use, but again, may be of interest.
    #!/usr/bin/perl -w use strict; use warnings; use Mail::SpamAssassin; use Net::IMAP::Simple; use Email::Simple; use constant DEBUG => 1; #BEGIN { open(STDERR,">>/home/myself/stderr.log"); } my $verbose=1; # quiet my @whitelist = qw( monty beth leocharre bankofamerica dyer pappajohns gmail yahoo craigslist bikini schizowave Amanda Ali geiman.com chroma hickey elizabeth dtyh owen dietofcookies pierre cilli westhost fenton jesse thornton charre puritans cherrys cecilia perl bronwyn cpan ); my @blacklisted = qw( lotto yahoo.co.jp lottery yahoo.co.cn ); my $host = 'mail.host.com'; my $user = 'myself@host.com'; my $pass = 'mypasswerd'; my $imap; my $sa = new Mail::SpamAssassin; my $box = 'INBOX'; my $cycle = 30; # how many before commit and restart my $x=1; my $cycle_limit = 10; # how many cycles before end instance of script my $cycle_count = 0; while (cycle()){ print STDERR "imapcleaner, cycle $cycle_count done\n" if DEBUG; $cycle_count++; last if $cycle_count == $cycle_limit; } sub cycle { $imap = Net::IMAP::Simple->new($host) || die("imapcleaner, unable to connect to IMAP: $Net::IMAP::Simple +::errstr"); # Log on if(!$imap->login($user,$pass)){ die("imapcleaner, login failed: " . $imap->errstr); } print STDERR "imapcleaner: connected\n" if DEBUG; my $count = $imap->select($box); unless( $count){ closeup(); return 0; } print STDERR "per cycle limit is $cycle\n" if DEBUG; my $m = 0; while ( $m < $count ){ ### cleaning ... $m++; last if $m == $cycle; my $header = join '', @{$imap->top($m)}; my $e = Email::Simple->new( $header ); my $from = $e->header('From'); print STDERR "sender: $from" if DEBUG; if ($from and is_blacklist($from)){ print STDERR ", blacklisted\n" if DEBUG; $imap->copy($m, 'INBOX.spam'); $imap->delete($m); next; } my $all = $imap->get($m); my $mail = $sa->parse($all); my $status = $sa->check($mail); if ( $status->is_spam ){ print STDERR ", spam" if DEBUG; #$imap->copy($m, 'INBOX.spam'); $imap->delete($m); print STDERR ", deleted.\n" if DEBUG; next; } print STDERR ", not spam" if DEBUG; my $dont_erase =0; if ($from and is_whitelist($from)){ print STDERR ", whitelisted\n" if DEBUG; $imap->copy($m, 'INBOX.whitelisted') or die('cant copy to +whitelisted'); $imap->delete($m); ## on whitelist: ## $from $dont_erase =1; next; } print STDERR "\n" if DEBUG; # everything else $imap->copy($m, 'INBOX.spam'); $imap->delete($m); } closeup(); return 1; } sub closeup { $imap->quit; # this commits changes $imap = undef; print STDERR "imapcleaner: done\n" if DEBUG; } sub is_whitelist { my $text = shift; $text or die; for (@whitelist){ my $term= $_; if ( $text=~/$term/i ){ return $term; } } return; } sub is_blacklist { my $text = shift; $text or die; for (@blacklist){ my $term= $_; if ( $text=~/$term/i ){ return $term; } } return; }
      Thanks for that.
      It may be old but then many good things are.
      ...and as it works it may well help me to start!
Re: Automatically getting and reading e-mails
by zentara (Cardinal) on Aug 27, 2008 at 19:30 UTC
    The 2 easiest modules to use are Net::POP3 and Mail::POP3Client About the only glitch you may run into is the type of auth the mail server uses, the port, and if ssl is used. But the module should take care of this automatically. Another glitch is if you have the email address as your logon name, you must either \ the @ or single quote the name.

    Here is a simple filter I use.

    #!/usr/bin/perl -w use strict; use Net::POP3; my $maxsize = 50000; my (@fromgoodre,@frombadre,@badwordre,@maillistre,@badcontentre,@recei +vedgoodre,@togoodre); my %rehash = ( 'fromgood' => \@fromgoodre, 'frombad' => \@frombadre, 'badwords' => \@badwordre, 'maillist' => \@maillistre, 'contentbad' => \@badcontentre, 'receivedgood' => \@receivedgoodre, 'togood' => \@togoodre ); foreach my $file (keys %rehash){ open(FH,"< $file") or warn "Can't open $file $!\n"; chomp (my @lines = <FH>); foreach my $line(@lines){push(@{$rehash{$file}},qr/$line/i) if $l +ine =~ /\w/} #removes tabs, empty lines from b +ecoming regexes close FH; } my $ServerName = "mail.foobar.com"; my $pop3 = Net::POP3->new($ServerName)||die("Couldn't log on to server +\n"); my $UserName = 'fuzzball@foobar.com'; my $Password = "goofy"; my $num_messages = $pop3->login($UserName, $Password)||die("Bad userna +me or password\n"); my $messages = $pop3->list(); print "******$messages Number of messages->$num_messages*******\n"; my %messages; my ($flag,$msg_id,$messcheck,@del_mess,@header,@top,$line); @del_mess = (); $messcheck = ''; print "####################################################\n"; foreach $msg_id(keys %{$messages}) { $flag = ''; my @header =(); #array for headerlines my @top = (); #array for top of messagebody my $messref = $pop3->top($msg_id,10); my $size = $pop3->list($msg_id); print "message$msg_id->size=$size\n"; # print "@$messref"; print "----------------------------------\n"; while(1){ my $line = shift @$messref; last if $line =~ /^\s*$/; push(@header,$line); } @top = @$messref; print '~~~~~~~~~~~~~~~~~~@header ->',"\n@header\n"; print '~~~~~~~~~~~~~~~~~~@top ->',"\n@top\n"; #check X-Mailinglist: if(($line) = grep(/^X-Mailinglist:/o,@header)){ print "#################X-Mailinglistline-> $line\n"; for my $maillistre (@maillistre) { if ($line =~ /$maillistre/) { print "Mail list g +ood\n"; $flag = 'ok'; goto DOBODY} } } #check From ($line) = grep(/^From:/io,@header); print "#################Fromgrepline-> $line\n"; my $from = $line; for my $goodfromre (@fromgoodre) { if ($line =~ /$goodfromre/) { print "GoodFrom->$ +goodfromre\n"; $flag = 'ok'; goto DOBODY} } for my $badfromre (@frombadre) { if ($line =~ /$badfromre/) { print "BadFrom->$ba +dfromre\n"; push(@del_mess,$msg_id); $messcheck .= "$msg_id -> $badfr +omre ->$from\n"; $flag = 'bad'; goto DOBODY} } #check To and CC and Return-Path ($line) = grep(/^(To|Cc|Return-Path):/io,@header); print "#################To-CC-ReturnPathgrepline-> $line\n"; for my $togoodre (@togoodre) { if ($line =~ /$togoodre/) { print "ToCCReturn-Pa +th address good ->$togoodre\n"; $flag = 'ok'; goto DOBODY} } for my $badfromre (@frombadre) { if ($line =~ /$badfromre/) { print "BadReceived- +>$badfromre\n"; push(@del_mess,$msg_id); $messcheck .= "$msg_id -> $b +adfromre ->$from\n"; $flag = 'bad'; goto DOBODY} } #check Received if(($line) = grep(/^Received:/io,@header)){ print "#################Receivedgrepline-> $line\n"; for my $receivedgoodre (@receivedgoodre) { if ($line =~ /$receivedgoodre/) { print "Receive +d address good\n"; $flag = 'ok'; goto DOBODY} } for my $badfromre (@frombadre) { if ($line =~ /$badfromre/) { print "BadReceived- +>$badfromre\n"; push(@del_mess,$msg_id); $messcheck .= "$msg_id -> $b +adfromre ->$from\n"; $flag = 'bad'; goto DOBODY} } } #check Content-type if(($line) = grep(/^Content-Type:/o,@header)){ print "#################Content-typegrepline-> $line\n"; for my $badcontentre (@badcontentre) { if ($line =~ /$badcontentre/) { print "Bad Conte +nt->$badcontentre\n"; push(@del_mess,$msg_id); $messcheck .= "$msg_id + -> $badcontentre ->$from\n"; $flag = 'bad'; goto DOBODY} } } #check Subject ($line) = grep(/^Subject:/io,@header); print "#################Subjectgrepline-> $line\n"; for my $badwordre (@badwordre) { if ($line =~ /$badwordre/) { print "badword in s +ubject->$badwordre\n"; push(@del_mess,$msg_id); $messcheck .= "$msg_i +d -> $badwordre ->$from\n"; $flag = 'bad'; goto DOBODY} } #check for base64 if(($line) = grep(/^Content-Transfer-Encoding: base64/o,@header)){ print "#################base64grepline-> $line\n"; if ($line =~ /^Content-Transfer-Encoding: base64/o){print +"base64 content\n"; push(@del_mess,$msg_id); $messcheck .= "$msg_id - +> base64 ->$from\n"; $flag = 'bad';goto DOBODY} } #check Message-Id ($line) = grep(/^Message-ID:/io,@header); print "#################Message-Idgrepline-> $line\n"; if (($line !~ /.*<?.+@.+(\..+)?>?$/o) || ($line =~ /\@127\ +.0\.0\.1/o)) { print "Bad Message-Id\n"; push(@del_mess,$msg_id); $mes +scheck .= "$msg_id -> bad Message-Id ->$from\n"; $flag = 'bad'; goto +DOBODY} DOBODY: if ($flag eq 'ok'){print "Message $msg_id is OK\n"; line(); next} if ($flag eq 'bad'){print "Message $msg_id is bad\n"; delmessage($msg_ +id); line(); next} if ($size > $maxsize){print "Size limit exceeded\n"; push(@del_mess,$m +sg_id); $messcheck .= "$msg_id -> size limit exceeded ->$from\n"; $fl +ag = 'bad'; goto DOBODY} #do body check print "Doing body check\n"; for my $line (@top){ for my $badwordre (@badwordre) { if ($line =~ /$badwordre/) { print "badword in body->$badword +re\n"; push(@del_mess,$msg_id); $messcheck .= "$msg_id -> bad word in + body ->$badwordre ->$from\n"; delmessage($msg_id); line(); goto FINI +SH} } } FINISH: line(); print "\n"; } #confirm the deletions line();line();line();line(); unless(defined $del_mess[0]){print "No messages to be deleted\nHit Ent +er to quit\n"; my $input = <>; $pop3->quit(); exit} print "Bad Messages:\n$messcheck\n\n"; print "Delete above messages?\n [yY] then Enter to delete, or Enter t +o abort\n"; chomp(my $input = <>); if($input =~ /^[yY]$/i){foreach(@del_mess){print "Deleting message $_\ +n"; $pop3->delete($_)}} $pop3->quit(); sub delmessage{print "Message @_ to be deleted\n"} sub line {print "####################################################\ +n"} exit 0;

    I'm not really a human, but I play one on earth Remember How Lucky You Are
      Many thanks for that. An excellent starter if not solution!
Re: Automatically getting and reading e-mails
by dwm042 (Priest) on Aug 27, 2008 at 17:47 UTC
    I've gotten very good use out of the modules Net::POP3 and Mail::Sendmail. I set up programs that test mail servers, and they can send mail to and fetch emails from the target server.

    The example at the top of the Net::POP3 documentation shows both fetching and reading email (see the code in the Synopsis).