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: 1)
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";
76 my $defaultIMAPServer = 'defaria.com';
77 my $defaultSleeptime = 1;
83 usage => sub { pod2usage },
84 help => sub { pod2usage(-verbose => 2)},
85 verbose => sub { set_verbose },
86 debug => sub { set_debug },
88 username => $ENV{USER},
89 password => $ENV{PASSWORD},
90 imap => $defaultIMAPServer,
91 sleep => $defaultSleeptime,
96 $log->msg("Turning off debugging");
99 $log->msg("Turning on debugging");
104 $SIG{USR1} = \&interrupted;
109 $log->msg($msg) if get_debug;
115 for (my $i = 1; $i <= $IMAP->status; $i++) {
116 $unseenMsgs{$i} = 0 unless $IMAP->seen($i);
123 $log->msg("Connecting to $opts{imap} as $opts{username}...", 1);
125 $IMAP = Net::IMAP::Simple->new($opts{imap}) ||
126 $log->err("Unable to connect to IMAP server $opts{imap}: " . $Net::IMAP::Simple::errstr, 1);
128 $log->msg(' connected');
130 $log->msg("Logging onto $opts{imap} as $opts{username}...", 1);
132 unless ($IMAP->login($opts{username}, $opts{password})) {
133 $log->err("Login to $opts{imap} as $opts{username} failed: " . $IMAP->errstr, 1);
136 $log->msg(' logged on');
138 # Focus on INBOX only
139 $IMAP->select('INBOX');
141 # Setup %unseen to have each unseen message index set to 0 meaning not read
143 %unseen = unseenMsgs;
147 my $msg = "Now monitoring email for $opts{username}\@$opts{imap}";
151 my $cmd = "/usr/local/bin/gt \"$msg\"";
153 my ($status, @output) = Execute $cmd;
156 # First close and reselect the INBOX to get its current status
158 $IMAP->select('INBOX')
159 or $log->err("Unable to select INBOX - ". $IMAP->errstr(), 1);
161 # Go through all of the unseen messages and add them to %unseen if they were
162 # not there already from a prior run and read
163 my %newUnseen = unseenMsgs;
165 # Now clean out any messages in %unseen that were not in the %newUnseen and
166 # marked as previously read
168 if (defined $newUnseen{$_}) {
170 delete $newUnseen{$_};
177 for (keys %newUnseen) {
180 my @msglines = $IMAP->top($_);
182 # What happens at INBOX 0? Does top return empty array?
183 $log->err("Unable to get top for $_ - " . $IMAP->errstr(), 1) unless @msglines;
185 my $email = Email::Simple->new(join '', @msglines);
187 my $from = $email->header('From');
189 # Extract the name only when the email is of the format "name <email>"
190 if ($from =~ /^(.*)\<(\S*)>/) {
191 $from = $1 if $1 ne '';
194 my $subject = $email->header('Subject');
196 if ($subject =~ /=?\S+?(Q|B)\?(.+)\?=/) {
197 $subject = decode_base64($2);
201 my $logmsg = "From $from $subject";
202 my $msg = "Message from $from... " . quotemeta $subject;
207 my $cmd = "/usr/local/bin/gt \"$msg\"";
209 my $hour = (localtime)[2];
211 # Only announce if after 6 Am. Not this will announce up until
212 # midnight but that's ok. I want midnight to 6 Am as silent time.
214 my ($status, @output) = Execute $cmd;
217 $log->err("Unable to execute $cmd" . join("\n", @output));
224 debugit "Sleeping for $opts{sleep} minutes";
225 sleep 60 * $opts{sleep};
226 debugit "Ah that was refreshing!";
231 $IMAP->quit if $IMAP;
233 $log->msg("$FindBin::Script ending!");
250 unless ($opts{password}) {
251 verbose "I need $opts{username}'s password";
252 $opts{password} = GetPassword;
255 $opts{debug} = get_debug;
257 EnterDaemonMode if $opts{daemon};
261 timestamped => 'yes',