Cookie Notice

As far as I know, and as far as I remember, nothing in this page does anything with Cookies.

2009/10/27

Reading IMAP directories with Perl

I use and like Thunderbird. Not the greatest thing since sliced bread, surely, but better for managing most of my mailboxes than pine and the school's web interface, which might soon be replaced with Gmail. Plus, IMAP!

The thing that sucks is alerting. If a mailing list gets updated, don't tell me. I shunt that stuff off into a subdirectory for a reason. In fact, there are three classes of people whose emails I want alerts about:
  • Family — mostly my wife and parents, but also my children, cousins, etc.
  • Bosses and Co-Workers — If you're involved in me getting paid, of course I need to know when you contact me
  • Friends — this is a low third, which is understandable, I hope.
Everyone else, all the spammers and mailing lists, I'll read your mail when I get around to it.

So, I looked into Perl's Mail::IMAPClient.


#!/usr/bin/perl
use Modern::Perl ;
use IO::Socket::SSL ;
use Mail::IMAPClient ;
use Getopt::Long ;
use Carp ;
use Data::Dumper ;

$Data::Dumper::Indent = 1 ;

my $server = 'imap.gmail.com' ;
my $username = 'me' ;
my $password = 'nope' ;
my @sender ;

GetOptions(
'sender=s' => \@sender ,
) ;

my $sender = join '|' , @sender ;

my $socket = IO::Socket::SSL->new(
PeerAddr => $server ,
PeerPort => 993,
)
or die "socket(): $@";

my $client = Mail::IMAPClient->new(
Socket => $socket,
User => $username ,
Password => $password ,
Ignoresizeerrors => 1 ,
)
or die "new(): $@";

if ( $client->IsAuthenticated() ) {
$client->select( 'INBOX' )
or die "Select 'INBOX' error: ", $client->LastError, "\n";
#for my $msg ( reverse $client->messages ) {
for my $msg ( reverse $client->unseen ) {
#my $string = $client->message_string($msg)
#or die "Could not message_string: $@\n";
my $from = $client->get_header( $msg , 'From' ) ;
my $to = $client->get_header( $msg , 'To' ) ;
my $subject = $client->subject($msg)
or die "Could not subject $@\n";
if ( $from =~ m{$sender}i ) {
my $notify = '/usr/bin/notify-send' ;
my $title = 'New mail from ' . $from ;
my $body = $subject ;
my $icon = '-i ~/Pictures/Icons/icon_black_muffin.jpg' ;
my $time = '-t ' . (1000 * 10 ) ;
$body =~ s/(['"])/\\$1/g;
$title =~ s/(['"])/\\$1/g;
$title = join q{"} , '' , $title , '' ;
$body = join q{"} , '' , $body , '' ;
qx{ $notify $title $body $icon $time } ;
}
}
$client->logout();
}


It takes one or more sender substrings. mail_notify.pl -sender '@purdue.edu' , for example, would pop notifications from all mail from Purdue University addresses. And the good thing is, you don't need to change much more than the server name, username and password to make it work on my work server.