5 =head1 NAME $RCSfile: announceEmail.pl,v $
7 Monitors an IMAP Server and announce incoming emails by extracting the subject
8 line and from line and then pushing that into "GoogleTalk".
16 Andrew DeFaria <Andrew@DeFaria.com>
24 Thu Apr 4 13:40:10 MST 2019
28 $Date: 2019/04/04 13:40:10 $
34 Usage: announceEmail.pl [-usa|ge] [-h|elp] [-v|erbose] [-de|bug] [-da|emon]
35 [-use|rname <username>] [-p|assword <password>]
39 -usa|ge: Print this usage
41 -v|erbose: Verbose mode (Default: -verbose)
42 -de|bug: Turn on debugging (Default: Off)
43 -da|emon: Run in daemon mode (Default: -daemon)
44 -use|rname: User name to log in with (Default: $USER)
45 -p|assword: Password to use (Default: prompted)
46 -i|map: IMAP server to talk to (Default: defaria.com)
47 -s|leep: Number of minutes to sleep inbetween checking mail (Default: 5)
51 This script will connect to an IMAP server, login and then monitor the user's
52 INBOX. When new messages arrive it will extract the From address and Subject
53 from the message and compose a message to be used by "Google Talk" to announce
54 the email. The message will be similar to:
56 "<From> emailed <Subject>"
66 use Net::IMAP::Simple;
70 use lib "$FindBin::Bin/../lib";
75 my $defaultIMAPServer = 'defaria.com';
76 my $defaultSleeptime = 5;
81 usage => sub { pod2usage },
82 help => sub { pod2usage(-verbose => 2)},
83 verbose => sub { set_verbose },
84 debug => sub { set_debug },
86 username => $ENV{USER},
87 imap => $defaultIMAPServer,
88 sleep => $defaultSleeptime,
94 for (my $i = 1; $i <= $IMAP->status; $i++) {
95 $unseenMsgs{$i} = 0 unless $IMAP->seen($i);
102 verbose "Connecting to $opts{imap} as $opts{username}";
104 $IMAP = Net::IMAP::Simple->new($opts{imap}) ||
105 error("Unable to connect to IMAP server $opts{imap}: " . $Net::IMAP::Simple::errstr, 1);
109 verbose "Logging onto $opts{imap} as $opts{username}";
111 unless ($IMAP->login($opts{username}, $opts{password})) {
112 error("Login to $opts{imap} as $opts{username} failed: " . $IMAP->errstr, 1);
117 # Focus on INBOX only
118 $IMAP->select('INBOX');
120 # Setup %unseen to have each unseen message index set to 0 meaning not read
122 %unseen = unseenMsgs;
126 verbose "Monitoring email";
129 verbose "Looking for unread messages";
130 # First close and reselect the INBOX to get its current status
132 $IMAP->select('INBOX');
134 # Go through all of the unseen messages and add them to %unseen if they were
135 # not there already from a prior run and read
136 my %newUnseen = unseenMsgs;
138 # Now clean out any messages in %unseen that were not in the %newUnseen and
139 # marked as previously read
141 if (defined $newUnseen{$_}) {
143 delete $newUnseen{$_};
150 for (keys %newUnseen) {
153 my $email = Email::Simple->new(join '', @{$IMAP->top($_)});
155 my $from = $email->header('From');
157 # Extract the name only when the email is of the format "name <email>"
158 if ($from =~ /^(.*)\<(\S*)>/) {
159 $from = $1 if $1 ne '';
162 my $subject = $email->header('Subject');
164 if ($subject =~ /=?\S+?(Q|B)\?(.+)\?=/) {
165 $subject = decode_base64($2);
169 my $msg = "Message from $from... " . quotemeta $subject;
172 verbose "Announcing $msg";
174 Execute "/usr/local/bin/gt \"$msg\"";
179 verbose "Sleeping for $opts{sleep} minutes";
180 sleep 60 * $opts{sleep};
181 verbose "Ah that was refreshing!";
203 unless ($opts{password}) {
204 verbose "I need $opts{username}'s password";
205 $opts{password} = GetPassword;
208 EnterDaemonMode if $opts{daemon};