Broad Network


Sending Email with ECMAScript in Node.js

Web Development Basics with ECMAScript and MySQL in Node.js Ė Part 3

Web Development with ECMAScript and MySQL in Node.js

Foreword: In this part of the series, I explain how to send email using ECMAScript in Node.js

By: Chrysanthus Date Published: 16 Jul 2016

Introduction

This is part 2 of my series, Web Development Basics with ECMAScript and MySQL in Node.js. In this part of the series, I explain how to send email using ECMAScript in Node.js

The Mailsend Module
It is a single file module and needs an ECMAScript program with the following variables and function, as you should use them.

const ms = require('./Mailsend.js');
This includes the mailsend module (assuming it is in the same directory as your program).

ms.setMAILFROM ('<bob@example.org>');
This variable must be coded with its email address. This is the address to which an email will be sent to, by the email server if an error occurs in the transmission. It can be the same as one of the addresses in the From field.

ms.setRecipientsArr(['<alice@example.com>','<theboss@example.com>']);
This array must be coded with at least one of the recipients address.

ms.setFrom("'Bob Example' <bob@example.org>");
This variable must be coded with one or more email addresses, separated by commas, in a string. In this heading you have just one email address. It is for the person (or people) who wrote the email.

ms.setCc('<person@example.com>');
The use of this variable is optional. A copy of the email can be sent to the address (or addresses).

ms.setBcc('<police@theaudit.com>');
The use of this Blind Carbon Copy variable is optional.

ms.setSubject('A Test');
The use of this variable for the subject is obligatory.

ms.setBody("something sometning sometning");
The use of this variable, for the body of the letter is obligatory. The string value can be very long. The string should not have the dot between new lines.

ms.sendmail();
This function should be typed after the above has been typed. It sends the email to the email server (MSA, Mail Submission Agent), which sends the email to the destination. You can use the function as follows:

ms.sendmail(function(err, feedback)
    {
        if (err)
            console.log(err);
        else
            {
                console.log(feedback + ' Message has been sent.');
            }
    });

The argument to the sendmail() function is a callback function, with two parameters: err and feedback. If an error occurs, err has the error message, otherwise it is undefined. If the mail is sent to the MSA, then the value of feedback is Boolean true.

Installation
Installation is easy. Just download the free Mail Send program from the following link:

Node Mailsend

It comes as a zipped directory. Unzip the directory and you will find the file (module), Mailsend.js . Copy this file into the same directory as your ECMAScript program that has the above code.

Mailsend.js is a text file. Open the file with your text editor. Change the port and the domain name of your mail server from,

    const port = 587;
    const remoteHost = "localhost";

to something like,

    const port = 25;
    const remoteHost = "mail.o2online.de";

as necessary.

Save the file. Thatís all.

Sending Web Form Mail

A Simple Node Server
A node server is a web server. A web server can receive request to send a web page to the browser or request to send email to a mail server (Mail Submission Agent). The request for a web page is sent by the browser. The request to send email is also send by the browser (Form). The code of a simple node server is:

    const http = require('http');
    const fs = require('fs');
    const ms = require('./Mailsend');

    http.createServer(function(request, response)
        {

            //form mail code goes here
    
            request.on('error', function(err)
                {
                    console.error(err);
                });

            response.on('error', function(err)
                {
                    console.error(err);
                });

        }).listen(8080);

I will explain the code of this simple server later on. In the meantime, note that the server listens at port 8080 (not 80, the default). The formmail code is typed where you have the comment (//) above.

A Web Form
A web form whose information can be sent to a mail server is,

<!DOCTYPE HTML>
<html>
<head>
    <title>Illustration</title>
</head>
<body>

    <h3>The Form</h3>    
    <form method="post" action="http://localhost:8080/SimpleFormMail.js">
        <p><label>Name: <input type="text" name="name"></label></p>
        <p><label>Telephone: <input type="tel" name="tel"></label></p>
        <p><label>E-mail address: <input type="email" name="email"></label></p>
        <p><label>Subject: <input type="text" name="subject"></label></p>
        <p><label>Comment: <textarea name="comments" rows=4 cols=30></textarea></label></p>
        <p><button>Submit</button><p>
        <input type="hidden" name="recipient" value='john@site.com'>
    </form>

</body>
</html>

The fields for the form: are, name, telephone, email, subject, comment and recipient. The value of the recipient field is the email of the person whom the form information is meant for. When the submit button is clicked, the information is sent to the node server. There, the information is processed and sent to the mail server, which will send the email to the recipientís email box. The node server and the mail server are in two different computers in the Internet.

The method to send the form information is POST. The action or URL that will receive the form information in the node server, is http://localhost:8080. In your commercial project, replace this URL with something like, http://www.yahoo.com:80 .

Formmail Code

The On Data Event
When a request or data from the browser arrives at the node server, an event called the on-data event is triggered. The code to handle this event (receive the data) is:

            request.on('data', function(chunk)
                {
                    //chunk statements
                }).on('end', function()
                {
                     //process data and send to mail-send.
                });

Here, request is an object with the method, on. The method has two arguments: the first one should be 'data' to indicate the on-data event. The second argument is a callback function. The code for the callback function can be:

            var body = [];

            request.on('data', function(chunk)
                {
                    body.push(chunk);
                })

The data (request) from the browser comes in segments (chunks). Each time a segment comes, it is pushed (added) into the body array. A chunk of data is a chunk of bytes.

The On End Event
The data arrives at the server in segments. When all the data have arrived, the on-end event is triggered. The rest of the formmail code is the on-end event code.

The first code segment for the on-end event is:

                    body = Buffer.concat(body).toString();
                    body = decodeURIComponent(body);
                    body = body.replace(/\+/g, " ");

This segment converts all the data that has arrived into a string.

The data from the web page form that arrives, is similar to:

    name=Paul Smith&tel=5555555555&email=jane@example.com&subject=The Title&comments=message message message&recipient=john@site.com

The next code segment separates this form data into the name/value pairs and places them in a map. The segment is:

                    keyValueArr = body.split('&');

                    keyValueMap = new Map();
                    for (item of keyValueArr )
                        {
                            arr = item.split('=');
                            keyValueMap.set(arr[0], arr[1]);
                        }

The code segment after, assigns the values of the key/value pairs to variables of the script. The segment is:

                    //variables
                    name = keyValueMap.get('name');
                    tel = keyValueMap.get('tel');
                    email = keyValueMap.get('email');
                    subject = keyValueMap.get('subject');
                    comments = keyValueMap.get('comments');
                    recipient = keyValueMap.get('recipient');

Validation in this script is simple: Just the presence or absence of a value is tested. The validation code is:

                    //simple validation
                    state = true;
                    if (name == "")
                        state = false;
                    if (tel == "")
                        state = false;
                    if (email == "")
                        state = false;
                    if (comments == "")
                        state = false;
                    if (recipient == "")
                        state = false;
                    if (subject == "")
                        state = false;

If any value of a name/value pair is absent, the value of the variable, state is false, otherwise it is true.

If the variable, state is false, the last code segment sends an error message to the client and the email is not sent; else it processes the information from the form and sends to the mail-send module, also sending a feedback to the client that the email has been sent. The last code segment is long.

Complete Code
Actually, the server code and the formmail code are in separate files. The name of the server file is server.js. The server code is as follows (glance through it -  I will explain the operation of a usable node server later in this series):

    const http = require('http');
    const fs = require('fs');
    const sfm = require('./SimpleFormMail.js');

    http.createServer(function(request, response)
        {
            var url = request.url;

            const fs = require('fs');

            if (url == '/')
                url = '/server/index.htm';
            else
              url = '/server' + url;

            if (url.search(/.*\.htm\s*$|.*\.html\s*$/i) != -1)
                {
                     fs.readFile(url, (err, data) => {
                         if (err)
                             {
                                 output = err;
                                 response.setHeader('Content-Type', 'text/html');
                                 response.end(output);
                             }
                         else
                             {
                                 output = data.toString('utf8');
                                 response.setHeader('Content-Type', 'text/html');
                                 response.end(output);
                             }
                    });
                }

            var body = [];

            request.on('data', function(chunk)
                {
                    body.push(chunk);
                }).on('end', function()
                {
                    if (url.search(/.*SimpleFormMail\.js\s*$/i) != -1)
                        sfm.simpleFormMail(body, function(err, feedback)
                            {
                                if (err)
                                    {
                                         response.setHeader('Content-Type', 'text/html');
                                         response.end(err);
                                    }
                                 else
                                    {
                                         response.setHeader('Content-Type', 'text/html');
                                         response.end(feedback);
                                    }
                            });
                });

            request.on('error', function(err)
                {
                    // print error to output
                });

            response.on('error', function(err)
                {
                    //send error message to output
                });

        }).listen(8080);

The name of the formmail file is: SimpleFormMail.js . Both the server file and the formmail file are in the same directory. The formmail code is (read through):

const ms = require('./Mailsend.js');

exports.simpleFormMail = function(bodyBytesArr, callback)
    {
        body = Buffer.concat(bodyBytesArr).toString();
        body = decodeURIComponent(body);
        body = body.replace(/\+/g, " ");

        keyValueArr = body.split('&');

        keyValueMap = new Map();
        for (item of keyValueArr )
            {
                arr = item.split('=');
                keyValueMap.set(arr[0], arr[1]);
            }

        //variables
        name = keyValueMap.get('name');
        tel = keyValueMap.get('tel');
        email = keyValueMap.get('email');
        subject = keyValueMap.get('subject');
        comments = keyValueMap.get('comments');
        recipient = keyValueMap.get('recipient');


        //simple validation
        state = true;
        if (name == "")
            state = false;
        if (tel == "")
            state = false;
        if (email == "")
            state = false;
        if (comments == "")
            state = false;
        if (recipient == "")
            state = false;
        if (subject == "")
            state = false;

    
        var feedback;


        //Error feedback sending mail
        if (state == false)
            {
                error = "One or more form fields was/were not filled";
                callback(error);
            }
        else
            {

                //prepare and send mail
                //if feedback is still undefined, then no error has occured above.
                if (feedback == undefined)
                    {
                        bodyStr = name + '\n' + tel + '\n' + comments;
                        ms.setMAILFROM ('<' + email + '>');
                        ms.setRecipientsArr(['<' + recipient + '>']);
                        ms.setFrom ('<' + email + '>');
                        ms.setSubject(subject);
                        ms.setBody(bodyStr);
                        ms.sendmail(function(err, feedback)
                            {
                                if (err)
                                    {
                                        error = err;
                                        callback(error);
                                    }
                                else
                                    {
                                        feedback = "Message has been sent.";
                                        callback(null, feedback);
                                    }
                            });

                     }
   
            }

    };

That is it for this part of the series.

Chrys

Related Links

Web Development Basics with ECMAScript and MySQL
ECMAScript Validation of HTML Form Data
Web Live Text Chart Application using ECMAScript and MySQL
More Related Links
Node Mailsend
EMySQL API
Node.js Web Development Course
Major in Website Design
Low Level Programming - Writing ECMAScript Module
ECMAScript Course

BACK

Comments

Become the Writer's Follower
Send the Writer a Message