Press enter to see results or esc to cancel.

Codeanywhere | Node.js | Bulk e-mail via JSON

 

A quick guide to show you how to quickly send bulk emails from JSON via the Gmail FTP server. 5-10 minutes of time for a highly time-efficient solution. Let’s go!

 

Go to File -> New Connection -> Container

Select a name for your container -> Search for Node.js (pick either Centos or Ubuntu) -> Click on ‘CREATE’
 

Alright, let’s install some dependencies first. We do that by creating a package.json file and typing in the following:

{
 "name": "bulk-email",
 "version": "1.0.0",
 "dependencies": {
  "email-templates": "^2.6.0",
  "express": "4.x.x",
  "mailer": "^0.6.7",
  "nodemailer": "^4.0.1",
  "nodemailer-smtp-transport": "^2.7.4"
 },
 "scripts": {
  "start": "node index.js"
 }
}

This will install all the required dependencies for this script. Now run ‘npm install -g’ so all the dependencies install globally. You can access the SSH Terminal by right-clicking your container and selecting ‘SSH Terminal’ from the menu.

Let’s start coding with creating a ‘index.js‘ file and typing in the following:

const nodemailer = require(‘nodemailer’);

Now you have nodemailer ready to go.

Following up, we’ll create two more files (emails.txt and mail.html). One will contain all the JSON info and one will serve us as the HTML e-mail template.

This is the JSON file where you can add all the e-mails and the content. This can be useful if you have a big excel sheet with all the e-mails and passwords which you can turn into a JSON file.

<!doctype html><html> <head> <meta name=”viewport” content=”width=device-width” /> <meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8" /> <title>Simple Transactional Email</title> <style> /* — — — — — — — — — — — — — — — — — — — GLOBAL RESETS — — — — — — — — — — — — — — — — — — — */ img { border: none; -ms-interpolation-mode: bicubic; max-width: 100%; } body { background-color: #f6f6f6; font-family: sans-serif; -webkit-font-smoothing: antialiased; font-size: 14px; line-height: 1.4; margin: 0; padding: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; } table { border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; } table td { font-family: sans-serif; font-size: 14px; vertical-align: top; } /* — — — — — — — — — — — — — — — — — — — BODY & CONTAINER — — — — — — — — — — — — — — — — — — — */ .body { background-color: #f6f6f6; width: 100%; } /* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something */ .container { display: block; Margin: 0 auto !important; /* makes it centered */ max-width: 580px; padding: 10px; width: 580px; } /* This should also be a block element, so that it will fill 100% of the .container */ .content { box-sizing: border-box; display: block; Margin: 0 auto; max-width: 580px; padding: 10px; } /* — — — — — — — — — — — — — — — — — — — HEADER, FOOTER, MAIN — — — — — — — — — — — — — — — — — — — */ .main { background: #fff; border-radius: 3px; width: 100%; } .wrapper { box-sizing: border-box; padding: 20px; } .footer { clear: both; padding-top: 10px; text-align: center; width: 100%; } .footer td, .footer p, .footer span, .footer a { color: #999999; font-size: 12px; text-align: center; } /* — — — — — — — — — — — — — — — — — — — TYPOGRAPHY — — — — — — — — — — — — — — — — — — — */ h1, h2, h3, h4 { color: #000000; font-family: sans-serif; font-weight: 400; line-height: 1.4; margin: 0; Margin-bottom: 30px; } h1 { font-size: 35px; font-weight: 300; text-align: center; text-transform: capitalize; } p, ul, ol { font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px; } p li, ul li, ol li { list-style-position: inside; margin-left: 5px; } a { color: #3498db; text-decoration: underline; } /* — — — — — — — — — — — — — — — — — — — BUTTONS — — — — — — — — — — — — — — — — — — — */ .btn { box-sizing: border-box; width: 100%; } .btn > tbody > tr > td { padding-bottom: 15px; } .btn table { width: auto; } .btn table td { background-color: #ffffff; border-radius: 5px; text-align: center; } .btn a { background-color: #ffffff; border: solid 1px #3498db; border-radius: 5px; box-sizing: border-box; color: #3498db; cursor: pointer; display: inline-block; font-size: 14px; font-weight: bold; margin: 0; padding: 12px 25px; text-decoration: none; text-transform: capitalize; } .btn-primary table td { background-color: #3498db; } .btn-primary a { background-color: #3498db; border-color: #3498db; color: #ffffff; } /* — — — — — — — — — — — — — — — — — — — OTHER STYLES THAT MIGHT BE USEFUL — — — — — — — — — — — — — — — — — — — */ .last { margin-bottom: 0; } .first { margin-top: 0; } .align-center { text-align: center; } .align-right { text-align: right; } .align-left { text-align: left; } .clear { clear: both; } .mt0 { margin-top: 0; } .mb0 { margin-bottom: 0; } .preheader { color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0; } .powered-by a { text-decoration: none; } hr { border: 0; border-bottom: 1px solid #f6f6f6; Margin: 20px 0; } /* — — — — — — — — — — — — — — — — — — — RESPONSIVE AND MOBILE FRIENDLY STYLES — — — — — — — — — — — — — — — — — — — */ @media only screen and (max-width: 620px) { table[class=body] h1 { font-size: 28px !important; margin-bottom: 10px !important; } table[class=body] p, table[class=body] ul, table[class=body] ol, table[class=body] td, table[class=body] span, table[class=body] a { font-size: 16px !important; } table[class=body] .wrapper, table[class=body] .article { padding: 10px !important; } table[class=body] .content { padding: 0 !important; } table[class=body] .container { padding: 0 !important; width: 100% !important; } table[class=body] .main { border-left-width: 0 !important; border-radius: 0 !important; border-right-width: 0 !important; } table[class=body] .btn table { width: 100% !important; } table[class=body] .btn a { width: 100% !important; } table[class=body] .img-responsive { height: auto !important; max-width: 100% !important; width: auto !important; }} /* — — — — — — — — — — — — — — — — — — — PRESERVE THESE STYLES IN THE HEAD — — — — — — — — — — — — — — — — — — — */ @media all { .ExternalClass { width: 100%; } .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div { line-height: 100%; } .apple-link a { color: inherit !important; font-family: inherit !important; font-size: inherit !important; font-weight: inherit !important; line-height: inherit !important; text-decoration: none !important; } .btn-primary table td:hover { background-color: #34495e !important; } .btn-primary a:hover { background-color: #34495e !important; border-color: #34495e !important; } } </style> </head> <body class=””> <table border=”0" cellpadding=”0" cellspacing=”0" class=”body”> <tr> <td>&nbsp;</td> <td class=”container”> <div class=”content”> <! — START CENTERED WHITE CONTAINER → <span class=”preheader”>Welcome ==name==.</span> <table class=”main”> <! — START MAIN CONTENT AREA → <tr> <td class=”wrapper” style=”text-align: center;”> <table border=”0" cellpadding=”0" cellspacing=”0"> <tr> <td> <img src=”/path/to/logo” style=”text-align: center;”/> <p>Hello ==name==,</p> <p>Welcome.</p> <table border=”0" cellpadding=”0" cellspacing=”0" class=”btn btn-primary”> <tbody> <tr> <td align=”left”> <table border=”0" cellpadding=”0" cellspacing=”0"> <tbody> <tr> <td> <a href=”http://htmlemail.io” target=”_blank”>Login</a> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <p>This is your password: ==pass==</p> </td> </tr> </table> </td> </tr> <! — END MAIN CONTENT AREA → </table> <! — START FOOTER → <div class=”footer”> <table border=”0" cellpadding=”0" cellspacing=”0"> <tr> <td class=”content-block”> <span class=”apple-link”>Company Inc, 3 Abbey Road, San Francisco CA 94102</span> <br> Don’t like these emails? <a href=”http://i.imgur.com/CScmqnj.gif”>Unsubscribe</a>. </td> </tr> <tr> <td class=”content-block powered-by”> Powered by <a href=”http://htmlemail.io”>HTMLemail</a>. </td> </tr> </table> </div> <! — END FOOTER → <! — END CENTERED WHITE CONTAINER → </div> </td> <td>&nbsp;</td> </tr> </table> </body></html>

The code is messed up in order to save on space — you can tidy it by visiting: https://dirtymarkup.com/.

In the upcoming part, we will be creating functions which will read and access the JSON file which will be stored in our container and parse all the data via nodemailer.

In line 8, replace ‘/path/to/template’ with the path to the .html file which will have your mail template inside.
In line 11, replace ‘/path/to/JSON’ with the path to your JSON file.

 

Following up we are going to create a reusable transporter object using the default SMTP transport. In this example, we will be sending e-mails via Gmail’s SMTP server.

In the ‘auth’ section, replace the two fields with your Gmail credentials.

Okay, let’s make some customisation and connect our script with our HTML template. This way, we are letting the script access our e-mail template and it’s placeholders.

So quite simple: get data from JSON -> store it -> replace /==xxx==/g from our HTML file with actual values. More info can be seen in the comments from the screenshot below.

And finally, send the e-mail and receive a message in our console so we know that everything went smoothly (if not, we’ll receive an error, obviously).

And you are done! Run the script with ‘npm start’ and your e-mails will be sent!

Additional

In order to be able to send e-mails from your script via Gmails SMTP you need to allow ‘Less secure apps’ — https://myaccount.google.com/lesssecureapps?rfn=27&rfnc=1&eid=1673352726244335489&et=0&asae=2&pli=1

Oh, and if you want, you can take a look at the source code and even clone it by clicking here.

Now it’s your turn! Visit Codeanywhere and get started!