Broad Network


Writing a Node.js Formmail Code

Sending Email with ECMAScript – Part 4

ECMAScript 6

Foreword: In this part of the series I explain how to write a form mail for the Node Mailsend module.

By: Chrysanthus Date Published: 15 Jul 2016

Introduction

This is part 4 of my series, Sending Email with ECMAScript. In this part of the series I explain how to write a form mail for the Node Mailsend module. A program that prepares email from a web page form to be sent is called a formmail. You should have read the previous parts of the series before coming here, as this is a continuation.

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 call 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 .

Form Mail 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 (glance through it):

    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

ECMAScript Basics
ECMAScript Operators
Expressions in ECMAScript
Statements in ECMAScript
Custom Objects in ECMAScript
Functions in ECMAScript
ECMAScript Date Object
The ECMAScript String Object
ECMAScript String Regular Expressions
ECMAScript Template Literal
The ECMAScript Array
ECMAScript Sets and Maps
ECMAScript Number
Scopes in ECMAScript
Mastering the ECMAScript (JavaScript) eval Function
Sending Email with ECMAScript
ECMAScript Insecurities and Prevention
Advanced Course
Advanced ECMAScript Regular Expressions
Promise in ECMAScript 2015
Generator in ECMAScript 2015
ECMAScript Module
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