Vincent Chu Tinkerer | Leader | Innovator

Product & Engineering leader in SaaS.
Passionate with technology. Worked at Electronic Arts and Apple before venturing into the startup world.

One hot afternoon, I was assigned the job to e-mail a bunch of people and asked them to do a survey. Since those are all busy people, we thought it would be nice to personalize each one instead of a generic dear sir/madam...

Personalize E-mail with Perl Script

For those who have been in cs (Computer Science not Counter Strike!) for a while, this is probably pretty easy. But to promote the use of perl (it's a nice scripting language!), I thought it would be nice to show how this task can be done in this concise scripting language. You can think of this as a brief perl tutorial or a simple perl example.

Pre-requisite

This is done on a unix/linux system, where perl is pre-installed. The script is also dependent on the standard mailing program "sendmail". Theoretically, this can also be done on Windows, with a perl interpretor and a mailing tool.

Intended Audience

This is intended for people who have programming background. I remember the days when I got frustrated when reading some books on scripting languages that cover stuff like how to write a for loop. I think I know how to write a loop if I have programming background thank you very much.

Now I will start discuss the script bit by bit. If you prefer, you can download the complete script first.

#!/usr/local/bin/perl -w

 

$sendmail = '/usr/lib/sendmail -i -t';

Change this line to wherever sendmail is located. This can be found on a unix system by typing whereis sendmail.

$sender = 'yourname@address.com';

Substitute this line to your address. In Perl, single quote and double quote are both used to quote strings. The special characters in a single quoted string does not have to be escaped, while they have to be escaped in double quoted string. (i.e. "yourname\@address.com" is equivalent to 'yourname@address.com').

open(CONTACTLIST,'contactlist.txt');

This line opens the file called 'contactlist.txt'. The first line is the name of person A, the second line of the e-mail address of person A. The third line is the name of person B, and the fourth line is the address of person B, etc. In terms of perl syntax, CONTACTLIST is now the file handle of the contact list file.

$count=0;

Perl variables do not need to be declared before using them. You don't even have to define the type, and it would know based on the values you assigned to it. Non-array types (integer, string, character) variables are prefixed by a dollar sign.

while(<CONTACTLIST>){

<CONTACTLIST> means read a line from CONTACTLIST and returns true if the read is successful and false otherwise. This line effectively iterates through the entire file, line by line. The line that is read is automatically assigned to $_ (a default variable that Perl assigns to when no variable is specified)

chomp;

chomp is a handy command that removes the end of line character in the string value assigned to $_

$nameList[$count++]=$_;

Assign the default variable to an element in the an array called nameList. When nameList is addressed/called as the entire array, it's prefixed by @ (i.e. @nameList). However, because we are assigned it to a particular index (which stores a non-array type), we prefix the whole thing with a dollar sign. (so basically $(nameList[index])). Note that we do not have to declare the size of the array beforehand either.

$_=<CONTACTLIST>;

Read another line from the CONTACTLIST file.

chomp;

$nameList[$count++]=$_;

}

%nameList=@nameList;

We need to reference nameList as an array in this line, so we use the @ prefix on the right. The % prefix means the variable is an associative array. An associative array is an array that can take strings as indices. For example, colorArray{'red'}= 'White minus green and blue". What this line does is turn @nameList (a traditional array in C/C++) into an associate array (using the same name!). How the conversion takes place is take the first element in the original array and call it the key, and the element following it and call it the value. The third element is the key, the fourth is the value, and so on.

close(CONTACTLIST);

Close the CONTACTLIST file. This is straightforward.

open(MESSAGE,'message.txt');

After we finished reading the list of names and e-mails, we open the 'message.txt' to read the main content of the e-mail we are sending.

@entireMessage=<MESSAGE>;

This line shows that <FILEHANDLE> is an overloaded operator. When it is assigned to a scalar variable (prefixed by $, or to $_), it reads one line. If it's assigned to a array variable, it reads the entire file and place each line into a different element (in order).

 

 

while(($recipient, $address)=each(%nameList)){

This means for each key and value pair in the associate array, assign the key to $recipient and the value to $address.

#print "Key: $Key, Value: $Value\n";

This line is commented out. (Prefixing by # is the only way to comment out things in Perl.) This line shows that in a double-quoted string, the scalar variables will be substituted with their values. Isn't this smart way to concatenate strings? (It's like printf in C without arguments!)

$mailbody="Dear $recipient,\n\n";

foreach(@entireMessage){$mailbody.=$_;}

First of all, .= is a concatenate operator. (i.e. $a.=$b is the same as "$a$b"). What this line does is turn the @entireMessage into one big concatenated string

print $mailbody;

Prints out the $mailbody to console so that you can have a look at it.

open(MAIL, "|$sendmail -oi -t") ;

This line sets the environment so that whenever you do print MAIL something in the future, the something is piped to $sendmail (which contains the location of the sendmail program).

print MAIL "To: $address\n";

print MAIL "From: $sender\n";

print MAIL "Subject: AddSubjectLine\n\n";

print MAIL "$mailbody";

The above is the syntax to send a e-mail using sendmail. Basically by piping the above lines to sendmail, the mail will get sent.

close(MAIL);

}

Close the handle since we're done with it.

Last words:

For those who have done some programming, you may realize what the script is doing is terribly inefficient - for example, it reads the entire file to an array, and then convert the array into a string, and then convert it back, etc. Clearly, this is a contrived example meant to show you some basics of perl. Feel free to contact me if you have any questions.