3 =head1 NAME $RCSfile: Mail.pm,v $
5 A simplified approach to sending email
13 Andrew DeFaria <Andrew@ClearSCM.com>
21 Thu Jan 5 15:15:29 PST 2006
25 $Date: 2012/09/25 01:34:10 $
31 Conveniently send email.
33 my $msg = "<h1>The Daily News</h1><p>Today in the news...</p>";
36 to => "somebody\@somewhere.com",
37 cc => "sombody_else\@somewhere.com",
38 subject => "Today's News",
43 open STATUS_REPORT, "status.html";
46 to => "boss\@mycompany.com",
47 bcc => "mysecret\@mailbox.com",
48 subject => "Weekly Status Report",
49 data => STATUS_REPORT,
50 footing => "Another day - Another dollar!"
57 Sending email from Perl scripts is another one of those things that is
58 often reinvented over and over. Well... This is yet another
59 reinvention I guess. The goal here is to allow for a simplifed
60 approach to sending email while still allowing MIME or rich text email
63 Additionally a multipart (plain text and HTML'ized) email will be send
64 if mode is set to html. Finally, if attempting to send HTML mail, if
65 we cannot find the appropriate dependent modules we'll fall back to
70 The following routines are exported:
94 my $mail_conf = dirname (__FILE__) . '/../etc/mail.conf';
97 %config = GetConfig $mail_conf;
99 $config{SMTPHOST} = $ENV{SMTPHOST} || $config{SMTPHOST};
101 $err = "SMTPHOST not defined in $mail_conf nor in the environment variable SMTPHOST"
102 unless $config{SMTPHOST};
105 $config{SMTPFROM} = $ENV{SMTPFROM} || $config{SMTPFROM};
107 $err = "SMTPFROM not defined in $mail_conf nor in the environment variable SMTPFROM"
108 unless $config{SMTPFROM};
111 $err = "Unable to read mail config file $mail_conf";
119 =head2 mail (<parms>)
121 Send email. The following OO style arguments are supported:
133 The from email address. If not specified then defaults to $ENV{SMTPFROM}.
137 Comma separated list of email addresses to set the mail to. At least
138 one address must be specified.
142 Comma separated list of email addresses to cc the mail to.
146 Comma separated list of email addresses to bcc the mail to.
150 Subject line for email (Default: "(no subject)")
154 Mode to send the email as. Values can be "plain", "text/plain",
159 Either a scalar that contains the message or a filehandle to an open
160 file which contains the message. Can contain HTML if mode = HTML.
164 Text to be included at the beginning of the email message. Can
165 contain HTML if mode = HTML.
169 Text to be included at the end fo the email message. Can contain HTML
202 # If from isn't specified we'll use a default
203 my $from = defined $parms{from} ? $parms{from} : $config{SMTPFROM};
205 error $err, 1 if $err;
207 my $me = "Mail::mail";
209 # Make arrays for to, cc and bcc
211 @to = split /, */, $parms{to};
212 @cc = split /, */, $parms{cc} if defined $parms{cc};
213 @bcc = split /, */, $parms{bcc} if defined $parms{bcc};
215 error "$me: You must specify \"to\"" if scalar @to == 0;
216 warning "$me: You should specify \"subject\"" if !defined $parms{subject};
218 my $subject = defined $parms{subject} ? $parms{subject} : "(no subject)";
222 if (!defined $parms{mode}) {
223 $mode = "text/plain";
224 } elsif ($parms{mode} eq "plain" or $parms{mode} eq "text/plain") {
225 $mode = "text/plain";
226 } elsif ($parms{mode} eq "html") {
228 } elsif ($parms{mode} eq "html") {
230 # Make sure we can get our modules...
231 eval { require MIME::Entity }
232 or error "Unable to find MIME::Entity module", 1;
233 eval { require HTML::Parser }
234 or error "Unable to find HTML::Parser module", 1;
235 eval { require HTML::FormatText }
236 or error "Unable to find HTML::FormatText module", 1;
237 eval { require HTML::TreeBuilder }
238 or error "Unable to find HTML::TreeBuilder module", 1;
240 error "Mode, ${parms{mode}}, is invalid - should be plain or html", 1;
244 my $smtp = Net::SMTP->new ($config{SMTPHOST})
245 or error "Unable to connect to mail server: $config{SMTPHOST}", 1;
250 # Who are we sending to...
251 $smtp->to ($_, {SkipBad => 1}) foreach (@to);
252 $smtp->cc ($_, {SkipBad => 1}) foreach (@cc);
253 $smtp->bcc ($_, {SkipBad => 1}) foreach (@bcc);
255 # Now write the headers
257 $smtp->datasend ("From: $from\n");
258 $smtp->datasend ("To: $_\n") foreach (@to);
259 $smtp->datasend ("Cc: $_\n") foreach (@cc);
260 $smtp->datasend ("Subject: $subject\n");
261 $smtp->datasend ("Content-Type: $mode\n");
262 $smtp->datasend ("\n");
264 # If heading is specified then the user wants this stuff before the main
266 my $msgdata = $parms{heading};
267 chomp $msgdata if $msgdata;
269 # If $parms{data} is a GLOB we'll assume it's a FILE reference.
270 if (ref ($parms{data}) eq "GLOB") {
272 my $datafile = $parms{data};
274 # Just because it's a file reference doesn't mean that it's a valid file
276 unless (eval { @lines = <$datafile> }) {
277 error "$me: File passed in to mail is invalid - $!", 1
280 $msgdata .= join "", @lines;
282 $msgdata .= $parms{data};
285 # If footing is specified then the user wants this stuff after the main
287 $msgdata .= $parms{footing} if defined $parms{footing};
289 # if the user requested html mode then convert the message to HTML
290 if ($mode eq "multipart") {
291 # Create multipart container
292 my $container = MIME::Entity->build (
293 Type => "multipart/alternative",
298 # Create a textual version of the HTML
299 my $html = HTML::TreeBuilder->new;
300 $html->parse ($msgdata);
302 my $formatter = HTML::FormatText->new (
306 my $plain_text = $formatter->format ($html);
308 # Create ASCII attachment first
310 Type => "text/plain",
311 Encoding => "quoted-printable",
315 # Create HTML attachment
318 Encoding => "quoted-printable",
322 $container->smtpsend (Host => $smtp);
325 $smtp->datasend ($msgdata);
339 =head2 CONFIGURATION AND ENVIRONMENT
341 SMTPHOST: Set to the appropriate mail server
343 SMTPFROM: Set to a from address to be used as a default
355 (Optionally - i.e. if html email is requested:)
357 =for html <p><a href="http://search.cpan.org/search?query=MIME::Entity">MIME::Entity</a>
359 =for html <p><a href="http://search.cpan.org/search?query=HTML::Parser">HTML::Parser</a>
361 =for html <p><a href="http://search.cpan.org/search?query=HTML::FormatText">HTML::FormatText</a>
363 =for html <p><a href="http://search.cpan.org/search?query=HTML::TreeBuilder">HTML::TreeBuilder</a>
365 =head3 ClearSCM Perl Modules
367 =for html <p><a href="/php/scm_man.php?file=lib/Display.pm">Display</a></p>
369 =for html <p><a href="/php/scm_man.php?file=lib/GetConfig.pm">GetConfig</a></p>
371 =head2 INCOMPATABILITIES
375 =head2 BUGS AND LIMITATIONS
377 There are no known bugs in this module.
379 Please report problems to Andrew DeFaria >Andrew@ClearSCM.com>.
381 =head2 LICENSE AND COPYRIGHT
383 This Perl Module is freely available; you can redistribute it and/or
384 modify it under the terms of the GNU General Public License as
385 published by the Free Software Foundation; either version 2 of the
386 License, or (at your option) any later version.
388 This Perl Module is distributed in the hope that it will be useful,
389 but WITHOUT ANY WARRANTY; without even the implied warranty of
390 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
391 General Public License (L<http://www.gnu.org/copyleft/gpl.html>) for more
394 You should have received a copy of the GNU General Public License
395 along with this Perl Module; if not, write to the Free Software Foundation,
396 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.