http://www.perlmonks.org?node_id=189549
Category:
Author/Contact Info Val Polyakov vpolyakov@katrillion.com
Description: This is an amazingly fast script for sending out newsletters. And by fast I mean REALLY fast. From start to finish, of sending out a 20kb newsletter to 90,000 recipients, it takes around 15 minutes.
#!/usr/bin/perl
######################################################################
+##
# This little guy will send out your newsletters AMAZINGLY fast.
# I do 90,000 recipients (approximately 20kb newsletter) in approximat
+ely
# 15 minutes with it.
# 
# Be *sure*, and I mean absolutely POSITIVELY sure that your email
# list is sorted by domain. all aol.com's together, all yahoo.com's
# together, etc. THAT IS *VERY* IMPORTANT, if it will not be sorted
# then you sacrifice pretty much all the speed of this thing.
# You also need to install Mail::Bulkmail module.
#
# Val Polyakov    August 11, 2002
# vpolyakov@katrillion.com
######################################################################
+##
use Mail::Bulkmail;
$/ = undef;

# Path to a something.list that contains email addresses to send 
# the newsletters to. One address per line, in the file
$list = </home/ds2/test/*.list>;

# Path to something.msg which is the actual newsletter
$msg = </home/ds2/test/*.msg>;

# Path to the error log
$errfile = "/home/ds2/test/log/error.log";

# Path to the success log
$success = "/home/ds2/test/log/success.log";

open(NEWSLETTER, $msg) or die "Couldnt open message file\n";

$newsletter = <NEWSLETTER>;


$bulk = Mail::Bulkmail->new(
                "LIST" => $list,
                "From" => 'vpolyakov@katrillion.com',
                "Subject" => 'Default subject',      
                "Message" => $newsletter,
                "ERRFILE" => $errfile,
                "HTML" => '1',
                "use_envelope" => '1',
                "BAD" => $errfile,
                "GOOD" => $success
);
$bulk->HFM(1);
$bulk->envelope_limit(1000);
$bulk->header("Content-type", "text/html");
$bulk->bulkmail;
Replies are listed 'Best First'.
Re: Yet another tool for sending out newsletters
by Aristotle (Chancellor) on Aug 13, 2002 at 00:33 UTC
    #!/usr/bin/perl -w use strict; use Mail::Bulkmail; use File::Spec::Functions; use Getopt::Std; my %default = ( dir => ".", addrfile => "addresslist.txt", mailfile => "mail.txt", errorlog => "error.log", successlog => "success.log", subject => q(Default subject), fromaddr => q(vpolyakov@katrillion.com), ); getopts('a:d:e:hf:l:m:s:', \my %option); $option{h} && die << "HELPMSG"; usage: bulkmail [-a addrfile] [-d directory] [-e errorlog] [-h] [-f fromaddr] [-l successlog] [-m mailfile] [-s subject] All files must reside in the same directory. defaults: -a $default{addrfile} -d $default{dir} -e $default{errorlo +g} -f $default{fromaddr} -l $default{successlog} -m $default{ +mailfile} -s $default{subject} HELPMSG my $dir = $option{d} || $default{dir}; open(my $listfile, "<", catdir($dir, $option{a} || $default{addrfile}) +) or die "Couldn't open address list: $!\n"; chomp(my @address = <$listfile>); close $listfile; @address = map { $_->[0] } sort { $a->[1] cmp $b->[1] } map { $_, lc((split /\@/)[-1]) } @address; open(my $mailfile, "<", catdir($dir, $option{m} || $default{mailfile}) +) or die "Couldn't open message file: $!\n"; read $mailfile, my $mail, -s $mailfile; close $mailfile; $bulk = Mail::Bulkmail->new( LIST => \@address, Message => $mail, From => $option{f} || $default{fromaddr}, Subject => $option{s} || $default{subject}, BAD => catfile($dir, $option{e} || $default{errorlog}), GOOD => catfile($dir, $option{l} || $default{successlo +g}), ERRFILE => catfile($dir, $option{e} || $default{errorl +og}), HTML => 1, use_envelope => 1, ); $bulk->HFM(1); $bulk->envelope_limit(1000); $bulk->header(qw(Content-type text/html)); $bulk->bulkmail;
    Of course you can get past the same-directory limitation by passing something like -a ../addresses.txt

    Makeshifts last the longest.

      Aristotle, with your code i get the following errors:
      Useless use of a constant in void context at /usr/local/share/perl/5.6 +.1/Mail/Bulkmail.pm line 1173. Use of uninitialized value in string comparison (cmp) at ./bulkmail.pl + line 38.

      Edited: ~Wed Aug 14 22:25:41 2002 (GMT) by footpad: Replaced <tag> tags with <code> tags, per Consideration

        Hmm.. no idea. :-) I don't actually have the module installed myself, just wrote the above source from the Mail::Bulkmail POD and the bits you provided. I'm not sure why this happens, although I figure it's because rather than a filename it's passing an array reference as the address list. According to the documentation, that is allowed (as would have been passing a coderef). If I had the module, I'd look into it.. maybe tonight when I'm home again.

        Update: Duh, of course.

        Makeshifts last the longest.

Re: Yet another tool for sending out newsletters
by tadman (Prior) on Aug 12, 2002 at 23:27 UTC
    It would be really nice if there were some configuration variables, or even better, a configuration file. The utility of this script is greatly degraded unless your name is 'ds2'.

    Some POD documentation wouldn't hurt, either.

    Your remark about making sure things are sorted seems kind of odd since that thing can be done so easily in Perl. Why not just pre-sort before firing in to Mail::Bulkmail?
Re: Yet another tool for sending out newsletters
by Anonymous Monk on Aug 13, 2002 at 15:25 UTC
    #!/usr/bin/perl -w use strict; use Mail::Bulkmail; use Mail::AddressSort; use File::Spec::Functions; use Getopt::Std; my %default = ( dir => ".", addrfile => "addresslist.txt", mailfile => "mail.txt", errorlog => "error.log", successlog => "success.log", subject => q(Default subject), fromaddr => q(email@domain.com), ); getopts('a:d:e:hf:l:m:s:', \my %option); $option{h} && die << "HELPMSG"; usage: bulkmail [-a addrfile] [-d directory] [-e errorlog] [-h] [-f fromaddr] [-l successlog] [-m mailfile] [-s subject] All files must reside in the same directory. defaults: -a $default{addrfile} -d $default{dir} -e $default{errorlog} -f $default{fromaddr} -l $default{successlog} -m $default{mailfile} -s $default{subject} HELPMSG my $dir = $option{d} || $default{dir}; open(my $listfile,"<",catdir($dir, $option{a} || $default{addrfile})) or die "Couldn't open address list: $!\n"; chomp(my @address = <$listfile>); close $listfile; my $list=Mail::AddressSort->new(); $list->input(@address); (@address)=$list->sorted(); open(my $mailfile,"<",catdir($dir, $option{m} || $default{mailfile})) or die "Couldn't open message file: $!\n"; read $mailfile, my $mail, -s $mailfile; close $mailfile; my $bulk = Mail::Bulkmail->new( 'LIST' => \@address, 'Message' => $mail, 'From' => $option{f} || $default{fromaddr}, 'Reply-to' => $option{f} || $default{fromaddr}, 'Subject' => $option{s} || $default{subject}, 'BAD' => catfile($dir, $option{e} || $default{errorlog}), 'GOOD' => catfile($dir, $option{l} || $default{successlog}) +, 'ERRFILE' => catfile($dir, $option{e} || $default{errorlog}), 'HTML' => 1, 'use_envelope' => 1, 'envelope_limit'=> 1000 ) or die Mail::Bulkmail -> error(); $bulk->header(qw(Content-type: text/html)); $bulk->bulkmail;
      Anonymous Monk, your code gives these errors:
      Useless use of a constant in void context at /usr/lib/perl5/site_perl/ +5.005/Mail/Bulkmail.pm line 1173. Too many arguments for open at ./ds4.pl line 39, at end of line Too many arguments for open at ./ds4.pl line 48, near "))

      Edited: ~Wed Aug 14 22:27:32 2002 (GMT) by footpad: Added <code> tags, per Consideration

        The first warning has to do with 'strict' inside Bulkmail, and will appear even with their test case. Dunno there, without going deeper. It will run however to deliver the mail as is.

        Check your line wrap on the other two. Those 'or die' cases are identical to previous post. Try removing the line break.
        should work fine otherwise.