Thursday, January 25, 2018

dynamic email template in Nodejs

When you are developing a web application, Mail sending feature is the most useful.In many cases, the email need to be sent, like user registration, user account activation, forgot the password, etc. Generally, in nodejs, nodemailer module is most used and familiar to send HTML email from the script. Alternatively, for increasing the email deliverability, the HTML email could be sent via SMTP server from the website. When we sending email from the website, an email template is used to make email content user-friendly and various forms, dynamic links, images, depending each company on their personal style displays. Dynamic Email Template makes it easy to manage templates for different types of emails.

=>Making the static template

EX: emailTemplate.html

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
    <title>dynamic email template</title>
</head>

<body>

    <div>
        <!--Start : Header portion-->
        <div style="clear: both;float: left;line-height: 0;margin: 30px 0; text-align: center;width: 100%;">
            <a href="https://www.example.com" style="margin: 0;padding: 0;">
                <img alt="Site Logo" src="https://www.example.com/images/site-logo.png" style="max-width: 100%;">
            </a>
        </div>
        <!--End : Header portion-->
    </div>

    <div>
        <!--Start : dynamic portion-->
        ##DYNAMIC_EMAIL_HTML##
        <!--End : dynamic portion-->
    </div>

    <div>
        <!--Start : footer portion-->
        <div>
            Feel free to contact us 24x7, our team will help you resolve any queries you my have.
        </div>
        <!--End : footer portion-->
    </div>
</body>

</html>

above email template will static in all mail, because header and footer portion will common in every email.
here, ## is used to determine that between this special character text is dynamic and change as per users. we can use any other sign instead of ##.

=>Making the dynamic template

for making dynamic templates we require the database to store this dynamic email templates.
you can use as per your database, but right now I am using MongoDB and mongoose.

EX: emailTemplate.js

/*
 * @Purpose : Store dynamic Email templates.
 */

'use strict';

/*
 *Declare variables and include mongoose
 */
var mongoose = require('mongoose');
var Schema = mongoose.Schema;

/*
 *Define structure of collection
 */
var emailTemplateSchema = new Schema({
    template_name: {
        type: String, // name of email template
        required: true
    },
    email_subject: {
        type: String, // for subject which will display in mail subject
        required: true
    },
    email_text: {
        type: String, // for email body which will display in mail message body
        required: true
    },
    is_active: {
        type: Number, // 0: inactive, 1: active
        default: 1
    },
    created_at: {
        type: Date,
        default: Date.now
    },
    updated_at: {
        type: Date,
        default: Date.now
    }
}, {collection: 'email_template'});

/*
 *Define model and export it for use in other page
 */
var EmailTemplate = mongoose.model('EmailTemplate', emailTemplateSchema);
module.exports = EmailTemplate;

after defining the model to store dynamic email template, you can insert all email templates from admin panel.

For email_text field, you can use any textarea or editor like as ckeditor, tinymc.

in this, use ## to determine that between this special character text is dynamic and change as per users. we can use any other sign instead of ##.

I have entered "User registration confirm" email template in the database which is as bellow.

=>db.email_template.find().pretty();
{
    "_id" : ObjectId("6031be0e0e1e05e64479b42e"),
    "email_subject" : "User registration confirm",
    "template_name" : "user_registration_confirm",
    "email_text" : "<div style=\" margin: 15px 0px;padding: 0;color: #555555;font-family: Arial;font-size: 15px;line-height: 25px;text-align: left;clear: both;\">\n                Hi ##user_name## ,\n            </div>\n            <div style=\" margin: 15px 0px;padding: 0;color: #555555;font-family: Arial;font-size: 14px;line-height: 24px;text-align: left;clear: both;\">\n                 Your account confirmed.\n            </div>",
    "updated_at" : ISODate("2016-05-04T09:17:02.878Z"),
    "created_at" : ISODate("2016-05-04T09:17:02.878Z"),
    "is_active" : 1,
    "__v" : 0
}

=>Use the dynamic template

Now you can use this email template in nodejs by using any nodejs mail module.
Here, we are using "nodemailer" module to sent email from script.

api.js

var express = require('express'),
    router = express.Router(),
    Lib = require("../components/lib"),
    EmailTemplate = require('../models/emailTemplate');

/**
 * user account confirmed.
 */
router
    .route("/api/user-account-confirm")
    .post(
        function (req, res) {

            //Your code for account confirmation

            //Start : Email ===========================
            EmailTemplate.findOne({
                "template_name": "user_registration_confirm",
                is_active: 1
            }, function (err, emailTemplateModel) {
                if (err) {
                    res.json({
                        status: 0,
                        code: 200,
                        type: "other",
                        message: "Oops! something went wrong."
                    });
                } else {
                    if (emailTemplateModel === null) {
                        //get static email message body
                        var message = emailTemplateModel.email_text;

                        //make static to dynamic email message body
                        message = message.replace(/##user_name##/g, req.body.user_name);

                        var params = {
                            to: user.email,
                            subject: emailTemplateModel.email_subject,
                            message: message
                        };
                        Lib.sendDynamicEmail(params, function (error, emailStatus) {
                            if (error) {
                                res.json({
                                    status: 0,
                                    code: 200,
                                    type: "other",
                                    message: "Mail sending fail."
                                });
                            } else {
                                res.json({
                                    status: 1,
                                    code: 200,
                                    type: "success",
                                    message: "Mail send successfull."
                                });
                            }
                        });
                    } else {
                        res.json({
                            status: 0,
                            code: 200,
                            type: "other",
                            message: "Oops! something went wrong."
                        });
                    }
                }
            });
            //End : Email================================
        });

 module.exports = router;


lib.js

/*
 * @Purpose : Create all common used functions
 */

'use strict';

var path = require('path');
var fs = require("fs");
var nodemailer = require('nodemailer');
var smtpTransport = require('nodemailer-smtp-transport');

exports.sendDynamicEmail = function (params, callback) {

    //Get email template
    var emailTemplatesHtml = fs.readFileSync(path.join("emailTemplates.html")).toString(); // here pass your application full path like (/var/www/html/...)

    //Replace static text "##DYNAMIC_EMAIL_HTML##" for make middle portion dynamic
    var message = emailTemplatesHtml.replace(/##DYNAMIC_EMAIL_HTML##/g, params.message);

    // create transporter object using the default SMTP transport
    var transporter = nodemailer.createTransport(smtpTransport({
        host: "smtp host",
        secure: true,
        auth: {
            user: "smtp email id",
            pass: "smtp password"
        },
        tls: {
            rejectUnauthorized: false
        }
    }));

    transporter.sendMail({
        from: "send from email id",
        to: params.to, // receiver
        subject: params.subject,
        html: message // body
    }, function (error, response) { //callback
        callback(error, response);
    });

};

Now, you can send email as per parameter "req.body.user_name", which will replace username.

You can also replace multiple like as bellow

var message = emailTemplateModel.email_text;
message = message.replace(/##user_name##/g, req.body.user_name);
message = message.replace(/##user_image##/g, req.body.image);
message = message.replace(/##user_gender##/g, req.body.user_gender);

As like this you can make many dynamic email templates for forgot password, reset password, etc.

No comments:

Post a Comment