Create dynamic html with ejs and node - html

I am trying to send dynamic mail to email IDs submitted using a form. Below is my app.js code.
//Importing Packages
var express = require('express');
var nodemailer = require('nodemailer');
var bodyParser = require('body-parser');
//Applying Express,Ejs to Node
app = express();
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({extended:true}));
//Creating Nodemailer Transport
var transporter = nodemailer.createTransport({
host: 'smtp.zoho.com',
port: 465,
secure: true,
auth: {
user: 'noreply#*****.com',
pass: '******'
}
});
//Root Route Setup
app.get('/', function(req, res){
res.render("landing")
});
//Route to send the mail
app.post('/send', function(req,res){
//Setting up Email settings
var mailOptions = {
from: 'noreply#*****.com',
to : req.body.mail,
subject: 'Verify Your Email',
generateTextFromHtml : true,
html: { path: './tmpl.html'}
};
//Execute this to send the mail
transporter.sendMail(mailOptions, function(error, response){
if(error) {
console.log(error);
} else {
console.log(response);
}
});
res.send("Mail succesfully sent!")
});
//Server &Port Settings
app.listen(3333, function(){
console.log("Server is running...")
});
Below is my Form page code, which is an ejs file
<form action="/send" method="POST">
<input type="email" name="mail" placeholder="Enter your email">
<input type="text" name="name" placeholder="Enter your name">
<input type="submit">
</form>
and below is my html template which is being mailed to the ID submitted using the form.
<html>
<body>
<h1>Hello World!</h1>
Link
</body>
</html>
How do I read the Name from the form and then include that in the Email, so that in each email, I can address to that person using a variable, like "Hello Mr {{name}}"
I am not able to figure out how to pass variable to the html file without emails blocking it as I am not able to use Javascript using Script tag inside the HTML file becuase almost all of the mail providers block JS in Email!
Can someone help me out with this please?

You can use the ejs templating engine you've already set up with express. Calling app.render() will render the template you specify as a string and pass it to its callback, plus whatever data you pass into it. So its a little ugly with callbacks, but this is a solution that doesnt add any dependencies.
In short, make your email template an ejs file named verifyEmail.ejs,
use app.render() to render it with data from the POST request body before sending the email from the app.render callback.
// app.js
app.post('/send', function(req,res){
// Use the ejs rendering engine to render your email
// Pass in the 'name' variable that is used in the template file
app.render('verifyEmail', {name: req.body.name}, function(err, html){
if (err) {
console.log('error rendering email template:', err)
return
} else {
//Setting up Email settings
var mailOptions = {
from: 'noreply#*****.com',
to : req.body.mail,
subject: 'Verify Your Email',
generateTextFromHtml : true,
// pass the rendered html string in as your html
html: html
};
//Execute this to send the mail
transporter.sendMail(mailOptions, function(error, response){
if(error) {
console.log(error);
res.send('Mail Error! Try again')
} else {
console.log(response);
res.send("Mail succesfully sent!")
}
});
}
});
});
I added some error handling, and notifying the user if the email is not sent due to a server error. The way you were calling res.send() before would tell the user the email was sent successfully before it was even sent.
Place your template folder in the same directory as your "landing" template, or wherever else your ejs files are.
Insert data into your template by calling a variable between <%= %> tags. Populate it by passing a variable of the same name when rendering the template.
From the ejs docs:
... everything inside <%= %> tags inserts itself into the returned HTML
string.
// views/verifyEmail.ejs
<html>
<body>
<h1>Hello <%= name %></h1>
Link
</body>
</html>

Related

Error when sending emails using Nodemailer

server.js:
app.post('/game',(req,res,next)=>{
//if(!emailValidator(req.body.email)){
// I would do email validations client side to but if you
// want to do server side send some html saying the email is invalid
//res.sendFile(invalidEmail.html)
//}
//else{
//I assume you have some script for sending email. I'll use nodemailer cuz its the first
//module I found
let sender = 'myemail#gmail.com'
let transporter = nodemailer.createTransport({
service:'gmail',
auth:{
user:sender,
pass:'Mypassword'
}
})
let mailOptions = {
from: sender,
to: req.body.email,
subject:'New sign up',
text:'Thanks for subscribing'
}
transporter.sendMail(mailOptions,function(error,info){
if(error){
// do somehting
console.log(error)
}
else{
console.log('Sent new user email')
req.next()
}
})
}
//}
)
index.html:
<form action="game" method="post" size="30">
<input type="text" name="email"/>
<input type="submit" />
</form>
I'm having this error:
TypeError: Cannot read property 'email' of undefined
So there is this error with my code, I'm trying to send an email with Nodemailer from a form in HTML, can someone help me fix this?
Also there is a part for email validation but I removed it as it says "emailValidator" is undefined.
Inside the main folder, create a public folder, inside it create an index.html file
<!DOCTYPE html>
<html>
<head>
<title>Simple page</title>
</head>
<body>
<form action="game" method="post" size="30">
<input type="text" name="email"/>
<input type="submit" />
</form>
</body>
</html>
Inside the main folder, create a server.js file
const express = require('express')
const app = express()
const path = require('path')
const bodyParser = require('body-parser')
const nodemailer = require('nodemailer')
app.use(bodyParser.urlencoded({ extended: false }));
app.use('/public', express.static(path.join(__dirname, 'public')));
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'))
});
app.post('/game', (req, res) => {
let senderUsername = 'example#gmail.com' // sender email address
let senderPassword = 'password'; // senders password
const transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: senderUsername,
pass: senderPassword
}
});
const mailOptions = {
from: senderUsername, // sender address
to: req.body.email, // list of receivers
subject: 'New sign up', // Subject line
html: '<p>Thanks for subscribing.</p>'// plain text body
};
transporter.sendMail(mailOptions, function (err, info) {
if(err)
console.log(err)
else {
console.log('Sent new user email')
console.log(info);
req.next()
}
});
})
const PORT = 5000;
app.listen(PORT, ()=>{
console.log(`server running on PORT ${PORT}`)
})
Note :
You may also need to follow these steps while using a google account.
Enable the settings to allow less secure apps for the Gmail account that you are using.
Here is the link: Google less secure apps
Allow access for "Display Unlock captcha option" (Allow access to your Google account)
Here is the link: Google unlock captcha
You can also explore MailJet or SendGrid for sending emails.

How to send an attachment from an upload button using nodemailer

I am trying to create a website with a form that users can fill up as well as uploading an image or a docx file through the input tag. I am using a controller because I am also using an hbs for this.
const output = `<p>You have a new message from the TIPH website<p>
<h3>Contact Details</h3>
<p>Name: ${req.body.contact_name}<p>
<h3>Inquiry</h3>
<p>${req.body.contact_inquiry}</p>
`;
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.EMAIL,
pass: process.env.PASSWORD
}
});
var mailOptions = {
from: `${req.body.contact_email}`,
to: '...',
subject: `${req.body.contact_subject}`,
html: output,
attachments: [
{
filename: `${req.body.contact_upload}`,
}
]
};
transporter.sendMail(mailOptions, function(error, info){
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
res.render('contact-us', {
layout: '/layouts/main',
title: 'Contact Us',
contact_active: true,
msg: 'Your message has been sent!'
})
}
});
In order to upload files to a node server, you should set the enctype attribute of the HTML form element to enctype="multipart/form-data"
To work with the files server side you could use multer. This middleware makes the uploaded file availabe from the req.file property.
You can then add this file to the attachments array. You can find what props you need to send to Nodemailer in their documentation.

Send data to server using socket.io with Node.js

in simple form i use:
onsubmit="return sendMessage()" action="/register"
to send data with socket.io to server:
function sendMessage() {
var name = document.getElementById("Name").value;
socket.emit('new_rgs', {
'name': name,
});
return false;
}
and i want to save result to text file too,
i use express.js to do this:
app.post('/register', urlencodedParser, (req, res) => {
var info = {};
info["name"] = req.body.Name;
fs.appendFileSync("register.json", JSON.stringify(info));
res.render('pages/register', {
"send": 1
});
});
but post method doesn't send anything :(
if you want check all codes it's here
You need to do a separate call to the /register route. What your current code does is that it only does an emit to the socket. You need a separate AJAX call towards the register route.

Node.js HTML response body

I am using the below code to post some JSON data to a url and in response I am getting a HTML page.
var request = require('request');
request.post({
url: "URL OF A WEBSITE",
headers: {
"Content-Type": "application/json"
},
body: {
my_json_obj
},
json:true
}, function(error, response, body){
console.log(error);
console.log(JSON.stringify(response));
console.log(body);
});
This code works fine I am getting a HTML page in the body tag.
I want to load that HTML page in the browser. How should I do that, I know this is a very basic question but I am very new to node.js someone please help me?
Follow the Express "Hello World" example and use your request call in the route handler:
/*jslint node:true, esversion:6*/
"use strict";
const request = require("request"),
express = require("express"),
app = express();
let my_json_obj = {},
URL_OF_WEBSITE = "http://www.google.com";
app.get("/", function (req, res) {
request.post({
url: URL_OF_WEBSITE,
headers: {
"Content-Type": "application/json"
},
body: {
my_json_obj
},
json: true
}, function (error, response, body) {
if (error) {
console.log(error);
return res.sendStatus(404);
}
console.log(JSON.stringify(response));
console.log(body);
res.send(body);
});
});
app.listen(3000, function () {
console.log("Example app listening on port 3000!");
});
node.js does have its own way to make a server, but for the sake of brevity and ease I just recommend using Express.
Are you using Express js? It would make things a lot easier when working with Node js apps.
Look into Express routing:
https://medium.com/javascript-scene/introduction-to-node-express-90c431f9e6fd
You can create an Express boilerplate in the terminal by using the command:
express yourappname
you can then put your html/css/js files inside the express-app -> 'public' folder that you just generated.
After that you create routes inside your app.js by doing something like:
// exampledomain.com/
// Loading the file index.html when user navigates to '/'
app.get('/', function(req, res){
res.sendFile(path.join(__dirname + '/public/index.html'));
});
// or
// exampledomain.com/getFileURL
// POST request (from your ajax) to '/getFileURL'
// which will then load the about.html file into the browser
app.post('/getFileURL', function(req, res){
// Do more JSON/data handling & Node js stuff here then
// send something back
res.sendFile(path.join(__dirname + '/public/about.html'));
});
There're many more useful functions with Express js, but I think Routing is what you need right now.
p.s. Very useful tools to look into when working with Node js:
Postman (Testing ajax/express/Nodejs routes and responses)
Nodemon (Starting Nodejs server automatically on save)

Display data in html/js file using NodeJs from mysql database

My index.js file is
var express = require('express');
var app = express();
var path = require('path');
var router = express.Router();
var data = require('./data/jsonData');
var createDatabase = require('./data/db');
var careateTable = require('./data/createTable');
var insert = require('./data/insert');
var bodyParser = require('body-parser');
var select = require('./data/select');
app.use(express.static(path.join(__dirname, 'www')));
app.use(express.static(path.join(__dirname, 'form')));
app.use(bodyParser());
app.get('/' , function (req , res) {
res.sendFile(path.join(__dirname + '/www/index.html'));
});
app.get('/data' ,function (req , res) {
res.json(data);
});
app.get('/form' ,function (req , res) {
res.sendFile(path.join(__dirname + '/form/index.html'));
});
app.post('/form' ,function (req , res) {
console.log(req.body.user);
console.log(req.body.password);
insert.insertModule(req.body.user , req.body.password);
res.sendFile(path.join(__dirname + '/www/index.html'));
});
app.get('/show' , function (req , res) {
var i ;
select.select( function (err, results) {
if (err == 'error') {
console.log(err);
} else {
console.log(results);
res.send(results.username);
}
});
});
app.listen(3000);
console.log("App is listning on port 3000");
and select.js is
var mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "",
database: "NodeDataBase"
});
con.connect(function (err) {
if (err) throw err;
console.log("Connected!");
});
module.exports = {
select: function (callback) {
var sql = "SELECT username , password FROM login ";
con.query(sql, function (err, result , fields) {
if (err) {
callback("error", err)
} else {
callback("success", result)
}
});
}
}
I want to show the results object data to html file , So how can i do this please suggest me.
from a get request /show it will show all userdata fetched from the database
I´ll try to explain the way it works (with the consideration on you are now able to see the data on 'http://localhost:3000/show') . Plz, guys, correct me if I do explain something in the wrong way.
There, what you have in your code, is the
Server side code
mysql: Declares connection to database (this is your database connector)
node.js: Declares methods to put/push/get data from database (your server side as is)
express.js: Declares urls to put/push/get data from database (http/https router)
Then, if we check the code, we can see the declaration of a server api - for example app.get('/show')
There, what you are saying is that express, will use the url /show with the method GET
Here is where your client appears in scene. Now, we suppose your server is up and running, waiting to serve GET petitions on http://localhost:3000/show.
If that is correct, when clicking the link you should see the user names, and now you will need an http client to connect to your http server side.
The way you can grab data on your HTML client from your server, is javascript.
Then, you will need to build an HTML file, that will also contain a javascript script (in my example written in angular).
The HTML (this is written in jade. you can convert it) should look like this:
Client HTML Code
You should create an index.html file, and paste this code
<!doctype html>
<html ng-app>
<head>
<title>My AngularJS App</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
</head>
<body>
<div ng-controller="MyCtrl">
<table>
<thead>
<tr>
<th>
<p>Name</p>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="user in users">
<td>
<p>{{user}}</p>
</td>
</tr>
</tbody>
</table>
</div>
<script>
var myApp = angular.module('myApp',[]);
function MyCtrl($scope, $http) {
//This method will call your server, with the GET method and the url /show
$http.get("http://localhost:3000/show").then(function(success){
if(success.data.length>0)
{
$scope.users=success.data;
}
});
}
</script>
</body>
</html>
This code should capture the data and show a row in the table for every name in the database.
Hope it helps, at least as a clear explanation of how the full stack (client-server) works.
May be you can use view engine such As EJS, Jade to render data from node to the front end.
If you want to render the data on the html page, i will do it like http://localhost:3000/show : with json -resonponse
var express = require('express');
var app = express();
require('json-response');
app.get('/', function(req, res){
res.ok({foo: 'bar'}, 'hello world');
});
i will return json from the link and in Index.html with the help of jquery/Ajax will hit the link , retrieve the value and show it on HTML