NodeJS send email tutorial with MySQL and nodemailer

NodeJS send email tutorial

Sending emails to users is an important feature in modern web applications. In a previous tutorial we explored how to create a dynamic photo gallery using PHP. This tutorial explores nodeJS send email using NodeMailer. Suppose you are working on a NodeJS MySQL web application that needs to send email to subscribers.

nodejs send email tutorial

 

Following tasks are performed in this tutorial.

1. Installation of MySQL and phpMyAdmin

2. Create MySQL database and a table for subscribers and insert sample data

3. Install NodeJS and generate a NodeJS, Express application

4. Create a model for subscribers

5. Display subscribers using Node ORM

7. Create a popup form to enter the subject and email body fields.

8. Send an email using nodemailer module and Ethereal, a fake SMTP service

Install MySQL and phpMyAdmin

To install MySQL with phpMyAdmin, visit WAMP or XAMPP site, download and install. After installation run WAMP or XAMPP and open phpMyAdmin by typing URL http://localhost/phpmyadmin

Create a Mysql database and table for subscribers

In phpMyAdmin, Open SQL tab and run the queries below to create a database dbsubscribers and a table subscribers. Sample data is also inserted into subscribers table.

CREATE DATABASE IF NOT EXISTS `dbsubscribers` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci;

USE `dbsubscribers`;

-- --------------------------------------------------------

--
-- Table structure for table `subscribers`
--

CREATE TABLE `subscribers` (
  `id` int(11) NOT NULL,

  `first_name` varchar(200) NOT NULL,

  `last_name` varchar(200) DEFAULT NULL,

  `email` varchar(200) NOT NULL

) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `subscribers`
--

INSERT INTO `subscribers` (`id`, `first_name`, `last_name`, `email`) VALUES
(1, 'John', 'Doe', 'john.doe@example.com'),
(2, 'Jane', 'Doe', 'jane.doe@example.com'),
(3, 'Mark', 'W', 'mark1212@example.com'),
(4, 'Jason', 'F', 'jason@example.com');

--
-- Indexes for dumped tables
--

--
-- Indexes for table `subscribers`
--
ALTER TABLE `subscribers`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `subscribers`
--
ALTER TABLE `subscribers`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;
COMMIT;

nodejs send email tutorial - db struture

Install NodeJS, Express Generator and Express

To install NodeJS, visit NodeJS site, download and install. NodeJS also installs NPM. NPM  is used as a package manager for NodeJS modules. After installation, open the command line and go to the folder where you want to create your project. To create a NodeJS project, first, you need to install express generator. Type command below to install Express Generator.

npm install express-generator -g

Create a NodeJS project using Express in nodejs send email

Express generator package installs the Express command line tool to create an express, nodejs application. Type the command below to create a project nodejs-send-emailPUG is used as a template engine.

express --view=pug nodejs-send-email

nodejs-send-email-create-project

 

Install modules and run the project

Next, change directory to the project folder and installs all required packages and modules.

cd nodejs-send-email && npm install

To run and view the app

SET DEBUG=nodejs-send-email:* & npm start

To view the running application, open browser and type the URL below. You can see the running application.

http://localhost:3000

Install ORM and NodeMailer modules.

To access database and perform queries you need to install an ORM module. Node-ORM module is used to perform relational mapping to database objects. Open command line, go to the project folder.

npm install orm

To send email, NodeMailer module is used. Install nodemailer using NPM.

npm install nodemailer --save

Create a Model for subscribers in index.js file

Open project folder in your favorite IDE. Open index.js file in routes directory. Add statement below to include node orm.

nodejs-send-email-folder-structure

var orm     = require('orm');

The application needs to connect to the database and define a model for subscribers table.

router.use(orm.express("mysql://root:@localhost:/dbsubscribers", {


  define: function (db, models, next) {


    models.subscribers = db.define("subscribers", {


    id         : Number,


    first_name : String,


    last_name  : String,


    email      : String,


  });

  next();

  }

}));

Inside router.use, a method orm.express is defined. In this method, MySQL driver is specified with root as user. Note ( : ) after username, you can specify a password after : . Localhost is used as a server and specify dbsubscriber as database. A model for subscribers table is defined.

Id, first_name, last_name and email fields are defined with data types. Id as a number, first_name, last_name and email has a string type.

Display subscribers using Node ORM

Inside router.get(‘/’)  route, remove existing code with the code given below. First, you see req.models.subscribers’s find method used without a condition using { }.  All the records from the database are fetched.

In an anonymous method, error and subscribers result set is returned. An error is thrown in case of error. Otherwise, render method is called. index template file is rendered. Title and Subscribers are assigned to view the file.

 router.get('/', function(req, res, next) {

   
   var result = req.models.subscribers.find({


   }, function(error, subscribers){


            if(error) throw error;


            res.render('index', { subscribers:subscribers, title: 'NodeJS Send Email Tutorial' });


        });
    
})

nodejs-send-email view subscribrs

Update code in layout.pug file

To display all subscribers, update code inside layout.pug and index.pug files in views directory. Open layout.pug file in views folder.

doctype html

html(lang="en")

  head

   title NodeJS Send Email

   meta(charset="utf-8")

   meta(name="viewport", content="width=device-width, initial-scale=1")

   link(rel="stylesheet", href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css")

   script(src="//ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js")

   script(src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js")

  body

   block content

In the code above bootstrap CSS, jQuery and bootstrap js files are included. After body tag note down the block content, all content from view files displays under this block.

Add code to index.pug file

Open index.pug file inside views folder and replace code. In HTML table First, Last name and Email are displayed. The last column is Action. In Action column, Send Email link is displayed. In each link, a data-toggle attribute is added with value model.

Data target contains the id of the popup div. A class js-sendemail is also added to each link, this class is used to open popup form. A data attribute, data-email is assigned the value of each user’s email.

extends layout
block content
  .container
    h2 NodeJS Send Email  
    p Click Send Email to Open a Popup form, Fill in the form and click Send Email.
    br
    table.table.table-striped
      thead
       tr
         th First Name
         th Last Name
         th Email
         th Action
      tbody
       each subscriber in subscribers
        tr
          td #{subscriber['first_name']}
          td #{subscriber['last_name']}
          td #{subscriber['email']}
          td 
            a(href="javascript:void(0)" data-toggle="modal" data-target="#emailModal" class='js-sendemail' data-email=subscriber['email']) Send Email

 

Create a popup to display form to send email

In order to use nodejs send email feature, a bootstrap popup form is created and user needs to fill in a form with subject and body fields. Id of model popup div is #emailModel with role = dialog.

When Send Email link is clicked popup form is opened. A hidden input field is added to store email of the user. Email with subject and body fields is sent to the server. Buttons to send the email and close the form are also added.

#emailModal.modal.fade(role="dialog")
      .modal-dialog
        .modal-content
          .modal-header
            button.close(type="button", data-dismiss="modal") ×
            h4.modal-title NodeJS Send Email
          .modal-body
            div#msgdiv.alert.alert-danger(style="display:none")

            form(method="post")
              input#email.form-control(type="hidden")
              .form-group
                label(for="email") Subject:
                input#subject.form-control(type="text", placeholder="Enter subject", name="subject")
              .form-group
                label(for="pwd") Body:
                textarea#body.form-control(rows="5" placeholder="Email body")
       
              button#btnemail.btn.btn-default(type="button" ) Send Email
          .modal-footer
             button.btn.btn-default(type="button", data-dismiss="modal") Close

nodejs-send-email-send-email-popup

nodejs-send-email-send-email-validation-message

If a user presses Send Email button without entering values, an error message is displayed.

jQuery Ajax code to send data to server

Using jQuery Ajax, data is sent to the server, when user clicks Send Email link. Link’s js-sendemail class Click event is triggeredBefore opening the popup form, subject and message field values are emptied and email value from data attribute of link named as data-email is fetched and assigned to email variable.

script.
    $( function() {
      
      $(".js-sendemail").on('click', function(){
           var email = $(this).attr('data-email');
           $("#email").val(email);
           $("#subject").val('');
           $("#body").val('');
           $('#msgdiv').html('');
      });
      $("#btnemail").on('click', function(){
           var email   = $("#email").val();
           var subject = $("#subject").val();
           var body    = $("#body").val();
           if(!subject || !body){
               $('#msgdiv').html("<strong>Error:</strong> All fields are required").show();
           }else{
 
            $.post( "send_email", {email:email, subject: subject, body:body  })

            .done(function( data ) {
                 
                 console.log(data.code); 
                if(data){
                  if(data['code'] == 2){ 
                    $('#msgdiv').removeClass('alert-success').addClass('alert-danger').html("<strong>Error:</strong> All fields are required").show().fadeOut(3000);
                  }else if(data['code'] == 3){ 
                    $('#msgdiv').removeClass('alert-success').addClass('alert-danger').html("<strong>Error:</strong>  Email not sent. Please try again.").show().fadeOut(3000);

                  }else if(data['code'] == 1){ 

                    $('#msgdiv').removeClass('alert-danger').addClass('alert-success').html("<strong>Success:</strong> Email sent successfully. <br /><br />Message URL: "+data['messageURL']).show();
                  }

                }else{

                  $('.error').show(3000).html("Email could not be sent. Please try again.").delay(2000).fadeOut(1000);
                }

             });
           }
      });
     
       
    });

nodejs-send-email-send-email-emailPNG

After the user fills in the subject and message fields and presses Send Email button. click method of button btnemail is triggered and values of email, subject, and body are assigned to variables.

Using jQuery AJAX  post request is sent to the server’s send_email route. If the user does not enter any of field values, an error message is displayed on the form.

Send an email using nodemailer

After the request received by the server, in send_email route subject, email and body are assigned to variables.

Email field is validated by performing a subscriber’s find method. You can see in find method a condition  {email: email } is specified.

In an anonymous method error, and the subscriber information is returned. If subscriber exists in the database and email is sent using SMTP email service provider.

req.models.subscribers.find({ email: email }, function (err, subscriber) { ... }

If you do not have an SMTP server, the nodemailer provide a fake SMTP email service Ethereal. For sending an SMTP service email, you would need a host, username,  port and password. So first a request is sent to Ethereal service to get a hostname and fake username and password.

nodemailer.createTestAccount((err, account) => { ... }

CreateTestAccount method returns an error and an account. Account variable contains the SMTP username and password. Inside CreateTestAccount method, createTransport method is called.

The host is  smtp.ethreal.email, port is 587. In an auth object host, port, username and password are assigned. After SMTP credentials are assigned to transporter variable, email options are specified with From, To email, subject and email body.

Note: In this tutorial test credentials from Ethereal SMTP server are used. On a live server, you should use your own SMTP host, port, username ans password.

Next transporter.sendMail method is called and emailOptions are passed. An error and info object are returned from this method. Info contains the messageId and URL from ethereal. MessageId and message URL is sent back to the client.

router.get('/', function(req, res, next) {

               .........


    }).post('/send_email', function(req, res, next) {
        var email     = req.body.email;

        var subject   = req.body.subject;

        var emailbody = req.body.body;

        if(!email || !subject || !emailbody){

            res.json({code: 2});

        }else{

            req.models.subscribers.find({ email: email }, function (err, subscriber) {
               
                if(err) throw err;

                if(subscriber.length){

                // Generate test SMTP service account from ethereal.email
                // Only needed if you don't have a real mail account for testing

                nodemailer.createTestAccount((err, account) => {

                    // create reusable transporter object using the default SMTP transport

                    let transporter = nodemailer.createTransport({

                        host: 'smtp.ethereal.email',

                        port: 587,

                        secure: false, // true for 465, false for other ports

                        auth: {
                            user: account.user, // generated ethereal user

                            pass: account.pass  // generated ethereal password
                        }

                    });

                    // setup email data with unicode symbols
                    let mailOptions = {

                        from: '"Info" <info@example.com>', // sender address

                        to: email, // list of receivers

                        subject: subject, // Subject line

                        text: emailbody, // plain text body

                        html: emailbody // html body

                    };

                    // send mail with defined transport object
                    transporter.sendMail(mailOptions, (error, info) => {

                        if (error) {

                            return console.log(error);
                        }

                        console.log('Message sent: %s', info.messageId);

                        // Preview only available when sending through an Ethereal account

                        console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info));

                        res.json({code:1, messageId: info.messageId, messageURL: nodemailer.getTestMessageUrl(info)});

                    });

                }); 
                
                }else{
                 
                 res.json({code: 3});
                }
            });
        }
    });

module.exports = router;

nodejs-send-email-sent-successfully

View email on Ethereal SMTP Server in nodejs send email

When you send an email using Ethereal, email is stored in Ethereal and is not sent to the recipients but it can be tested like a real SMTP server. Ethereal provides a link and messageId. So you can view the email using the provided URL as shown in the image below.

nodejs send email ethreal message

To run and view the nodejs send email app

To run nodejs send email application, open command line and type the command.

SET DEBUG=nodejs-send-email:* & npm start

To view the running application, open browser and type the URL below. You can see the running application.

http://localhost:3000

Summary

To summarize, in this nodejs send email tutorial, a MySQL database and table was created with sample data. A nodejs project was created with orm and nodemailer module. Records are displayed for all subscribers with a link to Send Email.

Clicking Send Email link a popup form is displayed with subject and body fields. After user fills in the form and clicks on Send Email button. Email is sent and the user sees a message Id and message URL.

You can download the source code of tutorial. Please follow us on twitter or like our facebook page to stay updated with upcoming articles. Leave your comments and feedback below.

 

Related Articles

 

Previous Article:  Dynamic PHP photo gallery