Email Line Wrapping and Date for Perl
Sending Email with Perl – Part 2
Perl Course
Foreword: In this part of the series, I explain how to wrap lines of text to within 78 characters and how to produce email date automatically.
By: Chrysanthus Date Published: 23 Nov 2015
Introduction
Data from the HTML form at the client’s computer in the Internet, arrives at the server. At the server, you can use the CGI module to extract the data. After extracting, you can now send the data to an email box. A website consists of HTML pages.
I spend the first half of this tutorial explaining how to use the CGI; and then the second half explaining how to send the email.
The CGI Class and Objects
To use the CGI module, you need to have,
use CGI;
at the top of the block of your script that needs the CGI features. Your script is in a sub directory of the web server (any web server comes with a number of directories). CGI is a class, from which objects can be created. Below the above statement, you can go ahead to instantiate an object, as in:
my $obj = CGI->new();
where $obj is a name of your choice for the object, and the rest of the words in the statement are reserved words.
The HTML Form at the client sends data, typically using one of two methods. You have the GET or the POST methods. Whichever method has been used, the CGI collects the data for you. You just need to know how to get the data from the CGI.
At the web page Form, the data is coded in name/value pairs, as follows:
email/chrys@broad-network.com
firstname/Chrysanthus
title/M.
job/system analyst
There are 4 name/value pairs here: email is a name, firstname is a name, title is a name, and job is a name. And there are 4 values: chrys@broad-network.com is a value; Chrysanthus is a value; “Mr.” is a value; and “system analyst” is a value. So there are 4 name/value pairs with each name corresponding to a value. There can be more or less than 4 name/value pairs.
In normal programming, you should know the names for the name/value pairs. You will then use the names to obtain the values through CGI. However, if you do not know the names, CGI offers you a way of knowing all the names – see below.
Obtaining the Names
For the name/value pair, email/chrys@broad-network.com, if you know the name, email, then you can obtain the value by coding the following after the instantiation of the object:
my $email = $obj->param('email');
Here, $email is the script variable of your choice. $obj is the object you created. -> is an operator that relates the object to its method, param(). So param is a kind of reserved word, here. 'email' in quotes is the name from the name/value pair. You obtain the other values in the same way. To obtain the value for the name, job, you will type something like,
my $profession = $obj->param('job');
where $profession is a variable of your choice and the rest of the words from this point, are not really of your choice.
A few parameters that arrive are multivalued, e.g. from multiple selections in a scrolling list of the web page form. In this case, the value of the name/value pair, is a list. No problem; CGI provided the solution. You receive the list as in the following statement:
my @values = $obj->param('foo');
where @values is a variable of your choice. Note that this variable, unlike the previous ones, is an array, because of the preceding, @ , to hold the list. Here, the name/value pair has the name “foo” and the value is a list. You should know the name, foo in advance. You can get this from the web page that sent the data.
List of Names
If for some reason or the other, you do not know the names for the name/value pairs, there is no problem. The CGI module has already provided a solution. It is to code:
@names = $obj->param;
where @names is a variable of your choice. It is an array that holds the list of all the names of the name/value pairs sent from the client. $obj is the object you created above. param is a reserved word (method) in this situation.
So, after obtaining the data sent by the client, you can then send the data to an email box (address).
An email box is a set of directories or similar structure that holds the emails sent to a person. These directories belong to a software called the email server. The email server can be in the same computer as the web server or in some other computer; that does not matter here. What you need in the same computer as your script, is a program called the sendmail program. This program may have some other name, but its purpose is to send the data to the destination email box. You do not have to write this sendmail program; it is already written for you and available in the server; you just use it.
Assume that the following name/value pairs have been sent from the web page form to a web server:
email/jsmith@myserver.com
title/M.
firstname/John
job/Accountant
recipient/maryt@herserver.net
Cc/president@boss.com
Bcc/pol@theaudit.com
subject/Payment of Dues
message/Dear Madam,
I am by this email reminding you to pay your dues. We also want to let you know that an email message is made up of lines, and after each line you must press the enter key of your keyboard if you are typing the email in a text editor and if the email will be sent as typed, through the Internet cable without modification.
Sincerely,
John Smith
The email script to send this email to the email box (address) is as follows:
use strict;
use CGI;
my $obj = CGI->new();
my $email = $obj->param('email');
my $title = $obj->param('title');
my $firstname = $obj->param('firstname');
my $job = $obj->param('job');
my $recipient = $obj->param('recipient');
my $Cc = $obj->param('Cc');
my $Bcc = $obj->param('Bcc');
my $subject = $obj->param('subject');
my $message = $obj->param('message');
$message =~ s/^\s+|\s+$//g; #remove leading and trailing space characters
$message = 'From : ' . $firstname . "\n" . "Job" . $job . "\n\n" . $message; #prefix msg with fname and job
my @arr = split (/\n/, $message); #split received message at new lines
use Text::Wrap;
$Text::Wrap::columns = 70;
$Text::Wrap::separator = "\n";
my $lineMsg = wrap('', '', @arr);
my @time = localtime();
my @week = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
my @mYear = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
my $serverDateStr;
my $year = 1900 + $time[5];
my $hr = $time[2];
my $mn = $time[1];
my $sc = $time[0];
if (length($hr) == 1)
{
$hr = "0" . $hr;
}
if (length($mn) == 1)
{
$mn = "0" . $mn;
}
if (length($sc) == 1)
{
$sc = "0" . $sc;
}
$serverDateStr = $week[$time[6]] . ", " . $time[3] . " " . $mYear[$time[4]] . " " . $year . " " . $hr . ":" . $mn . ":" . $sc;
open(SENDMAIL, "|/usr/lib/sendmail -oi -t")
or die "Can't fork for sendmail: $!\n";
print SENDMAIL <<"EOF";
From: <$email>
To: <$recipient>
Subject: $subject
Date: $serverDateStr
Cc: $Cc
Bcc: $Bcc
$lineMsg
EOF
close(SENDMAIL) or warn "sendmail didn't close properly";
When the client clicks the Submit button at his browser, he needs to know if from the server, the email was sent to the email box or not. A simple way to achieve this is to have at least two files, one called, sent.htm and another called error.htm. sent.htm can have text like, “Thank you. Email has been sent.”. error.htm can have text like, “Error! The server could not send the email. Contact Webmaster.”. The two files can be kept in the same directory like the Perl script.
The last statement in the code above is the close() function. This function closes the filehandle, SENDMAIL. It returns true if the email was sent by sendmail or false if the email was not sent.
If it returns true, you should send a feedback to the client indicating to him that the message was sent. In this case you will have extra code that will read the file, sent.htm and then send the file content to the client. You can do this by reading the file into a Perl string and then sending the string to the client using the print() function. Whenever a Perl script is called through a channel from a network, the print() function sends its argument back to the network channel.
If it returns false, you should send a feedback to the client indicating to him that the message was not sent. In this case you will have extra code that will read the file, error.htm and then send the file content to the client. You can do this by reading the file into a Perl string and then sending the string to the client using the print() function. Whenever a Perl script is called through a channel from a network, the print() function sends its argument back to the network channel.
So the close() function above, should be modified and have code added as follows:
if (close(SENDMAIL))
{
my $str;
open(fHandle, "<", "sent.htm") or die "cannot open sent.htm : $!";
{
local $/ = undef;
$str = <fHandle>;
}
print $str;
close fHandle;
}
else
{
my $str;
open(fHandle, "<", "error.htm") or die "cannot open error.htm : $!";
{
local $/ = undef;
$str = <fHandle>;
}
print $str;
close fHandle;
}
If you do not understand HTML, you can skip this section and come back to it after learning HTML.
A web page is an HTML document. Perl uses the sendmail program to send the email. You will have to precede the headers with the following:
MIME-Version: 1.0
Content-type: text/html; charset=iso-8859-1
Do not worry much about the meaning of these fields for now.
Example
Let us assume that me@me.com is sending an HTML document to him@him.com by email and the subject is, Web Page Email Illustration. Let us also assume that the HTML document is,
<html>
<head>
<title>Title here</title>
</head>
<body>
Your personal message goes here.
</body>
</html>
The personal information and any HTML tags go into the HTML BODY element. The following Perl code will send the web page as email:
use strict;
open(SENDMAIL, "|/usr/lib/sendmail -oi -t")
or die "Can't fork for sendmail: $!\n";
print SENDMAIL <<"EOF";
MIME-Version: 1.0
Content-type: text/html; charset=iso-8859-1
From: <me\@me.com>
To: <him\@him.com>
Subject: Web Page Email Illustration
Date: Fri, 21 Nov 20115 09:55:00 -0000
<html>
<head>
<title>Title here</title>
</head>
<body>
Your personal message goes here
</body>
</html>
EOF
close(SENDMAIL) or warn "sendmail didn't close properly";
User Agent of Recipient
The user agent (software) of the recipient will have to display the $message content at a browser, when he requests to read his email. The user agent has ways to fit the To, From and other email header fields in the displayed (message) web page.
Images
What you have sent to the recipient is an HTML document. So if you want the recipient to see images in the email, you simply have to type the image tags in the HTML BODY element of the HTML document.
Time to take a break. We stop here and continue in the next part of the series.
Chrys
Related Links
Perl BasicsPerl Data Types
Perl Syntax
Perl References Optimized
Handling Files and Directories in Perl
Perl Function
Perl Package
Perl Object Oriented Programming
Perl Regular Expressions
Perl Operators
Perl Core Number Basics and Testing
Commonly Used Perl Predefined Functions
Line Oriented Operator and Here-doc
Handling Strings in Perl
Using Perl Arrays
Using Perl Hashes
Perl Multi-Dimensional Array
Date and Time in Perl
Perl Scoping
Namespace in Perl
Perl Eval Function
Writing a Perl Command Line Tool
Perl Insecurities and Prevention
Sending Email with Perl
Advanced Course
Miscellaneous Features in Perl
Perl Two-Dimensional Structures
Advanced Perl Regular Expressions
Designing and Using a Perl Module
More Related Links
Perl Mailsend
PurePerl MySQL API
Perl Course - Professional and Advanced
Major in Website Design
Web Development Course
Producing a Pure Perl Library
MySQL Course
BACK NEXT