Liz::BulkMail - Send many (almost) identical emails
use Liz::BulkMail; $mail = Liz::BulkMail->new( $subject ); $mail->From( $from ); $mail->To( @list ); $mail->Body( <<EOD ); message EOD $mail->send;
or:
use Liz::BulkMail; use Liz::Perl; $mail = Liz::BulkMail->new( $subject ); $mail->From( $from ); $mail->To( @list ); $mail->Template( $template ); $mail->send;
The Liz::BulkMail package allows you to send (almost) the same email to a number of recipients. In its simplest form it is identical in the usage to the Liz::Mail module, with the only difference being that you can specify a list for the To method.
In its most complex form it allows you to send completely different emails to each recipient depending on external values, e.g. data stored in a database. To activate this mode of operation, you also need to to have the Liz::Perl module available and specify a Template which is to be executed as a Liz::Perl object for each recipient.
To send identical emails to a number of people, the Liz::BulkMail module basically functions the same as the Liz::Mail module, with one major difference: the To method accepts a list or a reference to a list as its parameter. To facilitate using external files any newlines will be automatically removed from each email address. This allows you to create an example such as this:
- emailaddresses ----------------------------------------------------------- liz@xxLINK.nl wendy@xxLINK.nl maarten@xxLINK.nl hayo@xxLINK.nl ----------------------------------------------------------------------------
- script ------------------------------------------------------------------- #!/usr/local/bin/perl
use Liz::BulkMail;
$mail = Liz::BulkMail->new( 'Example of Identical' ); $mail->From( 'info@xxLINK.nl' ); $mail->Body( <<EOD ); This is a example message, really! EOD open( LIST,'emailaddresses' ); $mail->To( <LIST> ); close( LIST );
$mail->send; ----------------------------------------------------------------------------
Sending a unique email to each recipient involves the use of a Liz::Perl template. This template is usually created in a seperate file, but does not need to be.
The template can either be fed with pre-fetched values that are available
with the template as variables $FIELD1 through
$FIELD20 or be fed with a single value that allows the
template to obtain the other values needed.
The case of pre-fetched values can be demonstrated with this template:
- template ----------------------------------------------------------------- To: $FIELD1 Dear $FIELD2<IF $FIELD4> $FIELD4<ENDIF> $FIELD5,
We would like to congratulate you on your decision. Whatever that was, even if your firstname(s) are "$FIELD3".
<IF $FIELD2 eq 'Mrs.'>And of course we have something special for girls!<ENDIF>
Thank you. ----------------------------------------------------------------------------
and this datafile:
- datafile ----------------------------------------------------------------- liz@xxLINK.nl,Mrs.,Elizabeth,,Mattijsen inge@xxLINK.nl,Mrs.,Ingeborg Rosa,,Kasik wendy@xxLINK.nl,Mrs.,Wendy,van,Dijk luc@xxLINK.nl,Mr.,Luc,,Ambagts ----------------------------------------------------------------------------
Notice that the comma ',' is used as a delimiter in the datafile (which is the default) and that therefore we do not need to specify a delimiter. This then allows the following script to be used to send 4 unique emails:
- script ------------------------------------------------------------------- #!/usr/local/bin/perl
use Liz::BulkMail; use Liz::Perl;
$mail = Liz::BulkMail->new( 'Congratulations!' ); $mail->From( 'info@xxLINK.nl' ); $mail->Template( 'template' ); open( LIST,'datafile' ); $mail->To( <LIST> ); close( LIST );
$mail->send; ----------------------------------------------------------------------------
Of course, the field values do not need to be stored in a seperate
text-file at all. In this template example only one field is passed to the
template which is then in turn used to obtain all relevant data from a
database. Note also that the automatically defined variable
$MAIL is used to add an extra unique header to each email
also.
- template2 ---------------------------------------------------------------- <INHERIT $object> <PERL>$object->Query2Vars( "SELECT * FROM table WHERE ID=$FIELD1" )</PERL> Subject: Unique message (ID=$ID) To: $email Hello $firstname $lastname,
We would like to congratulate you on your decision.
Thank you. <PERL>$MAIL->X( 'UserID',$ID )</PERL> ---------------------------------------------------------------------------- Note that in this example the Subject: of the email message is also changed for each recipient. This can be useful when tracking bounced mails. Then, in the script a single query is used to obtain the ID's to which emails should be sent. The ID then appears as $FIELD1 inside the template so that it can be used to obtain the other values from the table.
- script2 ------------------------------------------------------------------ #!/usr/local/bin/perl
use Liz::BulkMail; use Liz::Perl;
$mail = new Liz::BulkMail; $mail->From( 'info@xxLINK.nl' ); $mail->Template( 'template2' ); $mail->To( $object->Query( "SELECT ID FROM table" )->fetchcol(0) );
$mail->send; ----------------------------------------------------------------------------
Of course many more mixed forms are possible. You could e.g. first create a seperate datafile with a SQL query such as ``SELECT INTO OUTFILE'' and then use the first method again. This would be less CPU intensive, but would make it more difficult to create complicated templates as all variables will have non-descript names ($FIELD1 .. $FIELD20).
Finally, it is also possible to send unique HTML-mail with the HTMLTemplate method. As with the Template, this is a Liz::Perl compatible text that will be executed to create the HTML version of each email.
The following methods are the basic methods of the Liz::BulkMail module.
Create a new Liz::BulkMail object. Optionally sets the subject of the email to be sent.
1 subject of email to be sent (default: none)
1 instantiated object
$mail = new Liz::BulkMail( 'Something fishy at the OK Corral' );
Sends the email message contained in the object to all recipients specified. Return when all messages have been sent. Use method sendbg to send messages in the background.
1 flag: create seperate emails for each addressee (default: no)
1 number of bytes of email sent 2 reference to list with email addresses of recipients 3 number of email sent
($bytes,$sent) = $mail->send;
Sends the email message contained in the object to all recipients specified. Return immediately, send a transmission report to the From: email address specified when the sending of all emails has been completed. Otherwise identical to method send.
1 Subject: to use for the delivery report (default: 'Liz::BulkMail Delivery Report') 2 flag: create seperate emails for each addressee (default: no) 3 time (as an -at- compatible string) at which to send the messages (default: none = as soon as possible)
1 PID of the process that will send the emails
$mail->sendbg; print "Sending of email has commenced, you will receive a report later\n";
The following methods allow changes to information that is associated with an entire mail.
Specify/Return the From: address of the email object.
1 new From: addressee (default: no change)
1 current/old From: addressee(s)
$mail->From( 'info@xxLINK.nl' );
Specify/Return the To: addressee(s) of all the recipients of
the email.
The To: addressees may either be completely qualified email addresses (if the simple mode of bulk email is being used) or be an information record that is passed to the template as variables.
If you are using a Liz::Perl template, the addressee(s)
specified are in fact records that can be processed inside the Liz::Perl
template. They therefor do not need to be email addresses per se, just a
token of the information about the addressee to send to.
If you are using a Liz::Perl template for each email to be sent, the recipient of a message must be indicated by placing a line with
To: (recipient)
at the beginning of the template.
1..N new To: addressees
(default: no change; may also be specified as a reference to a list)
1 current/old To: addressee(s) (as a reference to a list)
$mail->To( <DATA> ); : __END__ liz@xxLINK.nl wendy@xxLINK.nl
open( LIST,"emailaddresses" ); $mail->To( <LIST> ); close( LIST );
$mail->To( $object->Query( "SELECT ID FROM table" )->fetchcol(0) );
Specify/Return the Subject: of the email object. This can also be done when the object is created with the new method.
If you are using a Liz::Perl template for each email to be sent, the subject of a message can be overriden by placing a line with
Subject: (unique subject)
at the beginning of the template.
1 new Subject: (default: no change)
1 current/old Subject:
$mail->Subject( 'About this and that' );
Specify/Return the Cc: addressee(s) of the email object. You
may prefix any extra addressee with ``+='' to add to the already existing
addressee(s).
Please note that if you are using a Liz::Perl template for each email, the Cc'd email address will receive a copy of every email sent. If you would like to Cc: a person, it is probably wiser to add the email address of that person to the list of people to send to.
1 new/additional Cc: addressee (default: no change)
1 current/old Cc: addressee(s)
$mail->Cc( 'wendy@xxLINK.nl' );
Specify/Return the Bcc: addressee(s) of the email object. You
may prefix any extra addressee with ``+='' to add to the already existing
addressee(s).
Please note that if you are using a Liz::Perl template for each email, the Bcc'd email address will receive a copy of every email sent. If you would like to Bcc: a person, it is probably wiser to add the email address of that person to the list of people to send to.
1 new/additional Bcc: addressee (default: no change)
1 current/old Bcc: addressee(s)
$mail->Bcc( 'wendy@xxLINK.nl' );
Specify/Return the Importance: of the email object.
1 new Importance of email object (default: no change)
1 current/old Importance of email object
$mail->Importance( 'high' );
Most email programma's only recognize the following values for importance:
1 or highest 2 or high 3 or normal 4 of low 5 or lowest
A value of '3' or 'normal' will not add any header to the email. Another value from the above list will add both an 'X-Priority:' header as well as an 'Importance:' header. If the value specified is not recognized, then only an 'Importance:' header will be added.
Specify/Return the Errors-to: addressee of the email object. This indicates the email address where email should be returned to if there is a failure in the delivery. Please note that this feauture is not supported by all Mail Transfer Agents: those who do not support this will usually return undeliverable mail to the From: address.
1 new ErrorsTo: addressee (default: no change)
1 current/old ErrorsTo: addressee(s)
$mail->ErrorsTo( 'postmaster@xxLINK.nl' );
Specify/Return an external ID of the email object. This has no meaning within Liz::BulkMail, but only when being used in conjunction with the Liz::TrackSet module.
1 new external ID (default: no change)
1 current/old external ID
$mail->ExternalID( $ID ); $ID = $mail->ExternalID;
Specify/Return the Reply-to: addressee of the email object. This indicates the email address where email should be sent to if the user uses hisr/her ``Reply'' function in their email program. Please note that this feature is not supported by all email programs: those who do not support this will usually return undeliverable mail to the From: address.
1 new ReplyTo: addressee (default: no change)
1 current/old ReplyTo: addressee(s)
$mail->ReplyTo( 'liz@xxLINK.nl' );
Specify additional header lines in the email to be sent. It is usually not necessary to call this method, as all standard email header lines are generated automatically by this module. It is only necessary if you would like to add special, non-standard header lines.
You may prefix any extra header line with ``+='' to add to the already existing header lines. It is advised to always prefix additional header lines with ``X-'' to indicate that they are non-standard.
1 new/extra additional header line (default: no change)
1 current/old additional header lines
$mail->Header( "X-MyHeader: whoopee\n" );
Specify the body (actual message) of the email to be sent. This method is to be used only for the simple method of sending bulk email, in which the messages for all recipients are the same.
Use the Template method if you want to customize the message for each recipient.
1 new body (default: no change)
1 current/old body
$mail->Body( <<EOD ); Hi,
what do you think of this message? It was sent with the Liz::Mail module!
Kind regards,
Liz EOD
Specify the body (actual message) of the email to be sent in HTML-format. This only works if you also have a plain-text version of the message specified with the Body method.
Use the HTMLTemplate method if you want to customize the message for each recipient.
1 new HTML-version of the body (default: no change)
1 current/old HTML-version of the body
$mail->HTML( <<EOD ); <HTML><BODY BGCOLOR="yellow"> Hi, <P> what do you think of this message? It was sent with the Liz::Mail module! <HR> Kind regards,
<I>Liz</I> </BODY></HTML> EOD
Not all email-programs, especially the ones that use text-mode, support this type of email messaging.
Add a file to the message to be sent.
Optionally allows an already MIME-encoded data-stream to be associated with the email message. MIME-encoding can be performed by the Binary2MIME method. The advantage of MIME-encoding beforehand makes a lot of sense in the Liz::BulkMail module as it reduces the amount of CPU to be used for each email significantly.
1 file (contents or file-specification) 2 name of file (default: file-specification or 'noname') 3 MIME-type of contents (default: application/octet-stream) 4 flag: whether contents are already MIME-encoded (default: not)
$mime = $mail->Binary2MIME( Liz::Contents( '/etc/filename.bin' ) ); $mail->File( $mime,'filename.bin','tencore/bin',1 );
Specify/Return the delimiter to be used to create the seperate field variables that exist inside the template. It is not necessary to specify this method if identical emails are being sent to every recipient (the Body method) or if only one field is passed on to the Liz::Perl template (the Template method).
The default is ','.
1 new delimiter (default: no change)
1 current/old delimiter
$mail->Delimiter( '|' );
Specify/Return the To: address to which the Delivery Report (as send by sendbg) will be sent to. By default, the From: address specified will be used to send the Delivery Report to.
1 new Deliery Report addressee (default: no change)
1 current/old Deliery Report addressee(s)
$mail->DeliveryReportTo( 'beheer@xxLINK.nl' );
Specify/Return the number of seconds to wait between the sending of each email. It is not necessary to specify this method if identical emails are being sent to every recipient (the Body method).
The default is ``1''.
1 new number of seconds to wait (default: no change)
1 current/old number of seconds to wait
$mail->Sleep( 5 );
Specify/Return the Liz::Perl template to be executed for each email to be sent. This allows customization and personalization of the email to be sent to each recipient.
If a template is specified, it overrides anything that was specified with the Body method. Please note that you can also specify a template for the HTML version of each email to be sent with the HTMLTemplate method.
1 new Liz::Perl template (either filespec or template itself) (default: no change)
1 current/old template
$mail->Template( $body );
$mail->Template( '/usr/templates/registeredusers' );
Specify/Return the Liz::Perl template to be executed for the HTML version of each email to be sent. This allows additional customization and personalization of the email to be sent to each recipient.
If a template is specified, it overrides anything that was specified with the HTML method. Please note that you must have a normal Template specification also in order for the HTML template to be used.
1 new Liz::Perl template (either filespec or template itself) (default: no change)
1 current/old template
$mail->HTMLTemplate( $html );
$mail->HTMLTemplate( '/usr/templates/registeredusers.html' );
Specify/Return a reference to a subroutine that should be called as a method (first parameter is the Liz::Mail object) just before each mail is actually sent.
1 new reference to subroutine (either alpha or code reference) (default: no change) 2..N parameters to be passed to the FixupHandler
1 current/old reference to subroutine
$bulkmail->FixupHandler( \&AddTracking,$dbh );
Specify the program that will be used to send the actual email. In most situations it is not necessary to call this method if the Liz::Mail package is correctly installed.
The default is usually ``/usr/lib/sendmail''.
1 new sendmail program to be used (default: no change)
1 current/old sendmail program
$mail->MailProgram( '/usr/sbin/sendmail' );
The following methods are generally not used in normal situations but only once to set things up or to fix problems.
Create the batch-file for an already existing mail message file. Is basically an internal routine, but can also be used to (re)start the sending of emails of an existing mail message file.
1 filename of message file (without the .gz extension) 2 email address to send Delivery report to 3 subject to be used for the Delivery Report 4 seperate messages flag 5 number of emails to be sent
$token = 'Liz::BulkMail.19991020171827.21576'; $mail = new Liz::BulkMail; $mail->Sleep( .1 ); $mail->BatchFile( $token,'liz@xxLINK.nl','Adfo Nieuwsbrief',1,2811 ); system( "$token.bat" );
Convert a value to its MIME-encoded version. It performs the opposite action to MIME2Binary. Usually used in combination with ``Contents'' and ``WriteContents'' of the Liz.pm module to encode a file to be sent only once, instead of each time it is sent.
1 value to be MIME-encoded
1 MIME-encoded value
$mime = $mail->Binary2Mime( Liz::Contents( '/usr/bin/ls' ) );
Convert the MIME-encoded version of a value to its original state. It is the opposite action to Binary2MIME.
1 value to be MIME-encoded
1 MIME-encoded value
Liz::WriteContents( '/tmp/filename',$mail->MIME2Binary( $mime ) );
Elizabeth Mattijsen ( lizperl@INC.nl )
(C) 1996-1999 International Network Consultants
Put module name between quotes to fix obscure bug in Perl 5.005x under ModPerl in methods send, sendbg and BatchFile.
Method new now sets the default Liz::Mail->Boundary before sending any mail. This facilitates the use of BatchFile externally.
New method BatchFile created from part of sendbg. This allows to create a batchfile to be created of an existing zipped messages file, for fixing problems and debugging mainly.
Now no longer adds Exporter to ISA: it wasn't necessary.
Support for ExternalID added: needed for Liz::TrackSet functionality.
Method sendbg now checks for errors in the Liz::Perl execution and returns without actually sending anything if an error has occurred.
Added new method HTMLTemplate for specifying a HTML version of each email to be sent. Added support for this in send, and indirectly to sendbg.
Added new method HTML for specifying the HTML version of all emails to be sent.
Method send (and indirectly method sendbg) now set the X-ExternalID: header to the first value specified when using
Liz::Perl templates for the email, but only if that value appears to be an
ID (i.e. is completely numeric). This should allow for better tracking of
bulk email events. To facilitate tracking even further, the Liz::BulkMail
object is now available to the Liz::Perl template as global variable
$MAIL during execution. This van e.g. be used to add a unique
extra header to the email from within the template.
Fixed problem in sendbg which would cause no messages to be sent if there was no Body and no Template specified.
Added documentation for Importance (inherited from Liz::Mail).
Added documentation for FixupHandler (inherited from Liz::Mail).
Changed typography of source to new format.
Fixed problem in sendbg which would cause bulkmail's to fail if there was a single quote in the subject.
Made all s###'s constant where applicable to save on execution speed at the expense of memory footprint.
Fixed problem in send that would cause sendbg to crash if there were no emails to be sent.
Fixed dependency on Liz::SQL::Int2Timestamp in sendbg.
Fixed problem with execution of batch-file if there are no emails to be sent.
Added check to delivery script of method sendbg that will check if the number of emails sent is the number that was expected to be sent.
Status delivery report now adds a copy of the message last sent with a file extension ``.txt'', so that it is easier to open within a mailbox context.
Changed setup of sendbg so that the actual sending is now performed by a completely seperate process, invoked by a system -at- command. This should make it a lot less likely that a sending of messages is interrupted by a server restart in the ModPerl environment.
Methods send and sendbg now have a flag to indicate whether seperate emails should be made for each recipient even if the message is the same for every addressee.
Method sendbg now checks for errors when sending the mail (should really never happen) and alerts through the delivery report.
The delivery report of sendbg now properly reflects the number of messages and bytes sent even if Bcc: was used for distribution.
Extra X-IP header is now added automatically when called in a web environment.
Templates with DOS-text line delimiters are now also handled by method send.
Reduced memory footprint by using fully qualified global variables.
First version of this true Perl module.