Added some changes for WellsFargo
[clearscm.git] / bin / announceEmail.pl
1 #!/usr/bin/perl
2
3 =pod
4
5 =head1 NAME $RCSfile: announceEmail.pl,v $
6
7 Monitors an IMAP Server and announce incoming emails by extracting the subject
8 line and from line and then pushing that into "GoogleTalk".
9
10 =head1 VERSION
11
12 =over
13
14 =item Author
15
16 Andrew DeFaria <Andrew@DeFaria.com>
17
18 =item Revision
19
20 $Revision: 1.0 $
21
22 =item Created:
23
24 Thu Apr  4 13:40:10 MST 2019
25
26 =item Modified:
27
28 $Date: 2019/04/04 13:40:10 $
29
30 =back
31
32 =hade1 SYNOPSIS
33
34  Usage: announceEmail.pl [-usa|ge] [-h|elp] [-v|erbose] [-de|bug] [-da|emon]
35                          [-use|rname <username>] [-p|assword <password>]
36                          [-i|map <server]
37
38  Where:
39    -usa|ge:    Print this usage
40    -h|elp:     Detailed help
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)
48
49 =head1 DESCRIPTION
50
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:
55
56   "<From> emailed <Subject>"
57
58 =cut
59
60 use strict;
61 use warnings;
62
63 use FindBin;
64 use Getopt::Long;
65 use Pod::Usage;
66 use Net::IMAP::Simple;
67 use Email::Simple;
68 use MIME::Base64;
69
70 use lib "$FindBin::Bin/../lib";
71
72 use Display;
73 use Logger;
74 use Utils;
75
76 my $defaultIMAPServer = 'defaria.com';
77 my $defaultSleeptime  = 1;
78 my $IMAP;
79 my %unseen;
80 my $log;
81
82 my %opts = (
83   usage    => sub { pod2usage },
84   help     => sub { pod2usage(-verbose => 2)},
85   verbose  => sub { set_verbose },
86   debug    => sub { set_debug },
87   daemon   => 1,
88   username => $ENV{USER},
89   password => $ENV{PASSWORD},
90   imap     => $defaultIMAPServer,
91   sleep    => $defaultSleeptime,
92 );
93
94 sub interrupted {
95   if (get_debug) {
96     $log->msg("Turning off debugging");
97     set_debug 0;
98   } else {
99     $log->msg("Turning on debugging");
100     set_debug 1;
101   } # if
102 } # interrupted
103
104 $SIG{USR1} = \&interrupted;
105
106 sub debugit($) {
107   my ($msg) = @_;
108
109   $log->msg($msg) if get_debug;
110 } # logit
111
112 sub unseenMsgs() {
113   my %unseenMsgs;
114
115   for (my $i = 1; $i <= $IMAP->status; $i++) {
116     $unseenMsgs{$i} = 0 unless $IMAP->seen($i);
117   } # for
118
119   return %unseenMsgs;
120 } # unseenMsgs 
121
122 sub Connect2IMAP() {
123   $log->msg("Connecting to $opts{imap} as $opts{username}...", 1);
124
125   $IMAP = Net::IMAP::Simple->new($opts{imap}) ||
126     $log->err("Unable to connect to IMAP server $opts{imap}: " . $Net::IMAP::Simple::errstr, 1);
127
128   $log->msg(' connected');
129
130   $log->msg("Logging onto $opts{imap} as $opts{username}...", 1);
131
132   unless ($IMAP->login($opts{username}, $opts{password})) {
133     $log->err("Login to $opts{imap} as $opts{username} failed: " . $IMAP->errstr, 1);
134   } # unless
135
136   $log->msg(' logged on');
137
138   # Focus on INBOX only
139   $IMAP->select('INBOX');
140
141   # Setup %unseen to have each unseen message index set to 0 meaning not read
142   # aloud yet
143   %unseen = unseenMsgs;
144 } # Connect2IMAP
145
146 sub MonitorMail() {
147   my $msg = "Now monitoring email for $opts{username}\@$opts{imap}";
148
149   $log->msg($msg);
150
151   my $cmd = "/usr/local/bin/gt \"$msg\"";
152
153   my ($status, @output) = Execute $cmd;
154
155   while () {
156     # First close and reselect the INBOX to get its current status
157     $IMAP->close;
158     $IMAP->select('INBOX')
159       or $log->err("Unable to select INBOX - ". $IMAP->errstr(), 1);
160
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;
164
165     # Now clean out any messages in %unseen that were not in the %newUnseen and
166     # marked as previously read
167     for (keys %unseen) {
168       if (defined $newUnseen{$_}) {
169         if ($unseen{$_}) {
170           delete $newUnseen{$_};
171         } # if
172       } else {
173         delete $unseen{$_}
174       } # if
175     } # for
176
177     for (keys %newUnseen) {
178       next if $unseen{$_};
179
180       my @msglines = $IMAP->top($_);
181
182       # What happens at INBOX 0? Does top return empty array?
183       $log->err("Unable to get top for $_ - " . $IMAP->errstr(), 1) unless @msglines;
184
185       my $email = Email::Simple->new(join '', @msglines);
186
187       my $from = $email->header('From');
188
189       # Extract the name only when the email is of the format "name <email>"
190       if ($from =~ /^(.*)\<(\S*)>/) {
191         $from = $1 if $1 ne '';
192       } # if
193
194       my $subject = $email->header('Subject');
195
196       if ($subject =~ /=?\S+?(Q|B)\?(.+)\?=/) {
197         $subject = decode_base64($2);
198       } # if
199
200       # Now speak it!
201       my $logmsg = "From $from $subject";
202       my $msg = "Message from $from... " . quotemeta $subject;
203       $msg =~ s/\"/\\"/g;
204
205       debugit $logmsg;
206
207       my $cmd = "/usr/local/bin/gt \"$msg\"";
208
209       my $hour = (localtime)[2];
210
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.
213       if ($hour > 6) {
214         my ($status, @output) = Execute $cmd;
215
216         if ($status) {
217           $log->err("Unable to execute $cmd" . join("\n", @output));
218         } # if
219       } # if
220
221       $unseen{$_} = 1;
222     } # for
223
224     debugit "Sleeping for $opts{sleep} minutes";
225     sleep 60 * $opts{sleep};
226     debugit "Ah that was refreshing!";
227   } # while
228 } # MonitorMail
229
230 END {
231   $IMAP->quit if $IMAP;
232
233   $log->msg("$FindBin::Script ending!");
234 } # END
235
236 ## Main
237 GetOptions(
238   \%opts,
239   'usage',
240   'help',
241   'verbose',
242   'debug',
243   'daemon!',
244   'username=s',
245   'password=s',
246   'imap=s',
247   'sleep',
248 );
249
250 unless ($opts{password}) {
251   verbose "I need $opts{username}'s password";
252   $opts{password} = GetPassword;
253 } # unless
254
255 $opts{debug} = get_debug;
256
257 EnterDaemonMode if $opts{daemon};
258
259 $log = Logger->new(
260   path        => '/var/log',
261   timestamped => 'yes',
262   append      => 'yes',
263 );
264
265 Connect2IMAP;
266
267 MonitorMail;