how to send mail with data that data from database using nodejs? - node.js

this is my code: i am getting perfect output in postman.but i want the output to send through my mail.In this code var result i am getting error i cannot able to get the responses.
var startBroadcasting = function (req, res) {
authToken = req.headers.authorization;
userAuthObj = JSON.parse(UserAuthServices.userAuthTokenValidator(authToken));
var todayDate = new Date();
var expireDate = new Date(userAuthObj.expire_date);
tokenOK = TokenValidator.validateToken(userAuthObj.user_id, authToken).then(function (userSessions) {
if (userSessions.length === 1) {
if (expireDate >= todayDate) {
template_id = req.params.id;
image_id = req.params.img_id;
TemplateController.findById(template_id, {
attributes: {
exclude: ['created_by', 'created_on', 'updated_by', 'updated_on']
},
include: [{
attributes: {
exclude: ['created_by', 'created_on', 'updated_by', 'updated_on']
},
model: Broadcasting,
where: {
id: image_id,
}
},
]
}
).then(function (templatefindByid) {
BccSetting.findAll({
where: {
template_id: template_id
}
}).then(bccSettings => {
res.status(200).json({
id: templatefindByid.id,
name: templatefindByid.name,
template_images: templatefindByid.template_images,
bcc_settings: bccSettings,
})
}).catch(err => {
console.log(err);
res.status(404).json({
message: ' not found...'
});
});
}).catch(function (err) {
console.log(err);
res.status(404).json({
message: 'not found...'
});
});
} else {
res.status(401).json({
message: 'Not ...'
});
}
} else {
res.status(401).json({
message: 'Expired...'
});
}
}).catch(function (err) {
res.status(401).json({
message: 'Expired...'
});
});
var result = "Hi " + template_images.client_name + "!We are pleased to inform you that " + template_images.client_name + " newschannel streaming has been stopped sucessfully on " +template_images.destination_type + "" +
"" +
"This email was sent from a notification-only address that cannot accept incoming email. Please do not reply to this message.";
let transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 465,
auth: true,
active: true,
secure: true,
requireTLS: true,
auth: {
user: 'trans#gmail.com',
pass: 'wertyy'
}
});
let mailOptions = {
from: 'trans#gmail.com',
to: 'wwww#gmail.com',
bcc: bcc_setting.bcc_setting,// here i want bcc setting data
subject: 'yvnuyybymyed',
html: 'result'
};
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log("mail not sent" + error.message);
}
console.log('success');
});
};

Related

how to send mails using nodemailer after a sucessful purchase in stripe

i'm trying to send an email after successfully making a payment , but i'm find it hard to add my nodemailer code in stripe,
this is my stripe code
router.post("/pay", verifyToken, (req, res) => {
let totalPrice = Math.round(req.body.totalPrice * 100);
stripe.customers
.create({
email: req.decoded.email
})
.then(customer => {
return stripe.customers.createSource(customer.id, {
source: "tok_visa"
});
})
.then(source => {
return stripe.charges.create({
amount: totalPrice,
currency: "usd",
customer: source.customer
});
})
.then(async charge => {
console.log("charge>", charge);
let order = new Order();
let cart = req.body.cart;
cart.map(product => {
order.products.push({
productID: product._id,
quantity: parseInt(product.quantity),
price: product.price
});
});
order.owner = req.decoded._id;
order.estimatedDelivery = req.body.estimatedDelivery;
await order.save();
res.json({
success: true,
message: "Successfully made a payment"
});
})
.catch(err => {
res.status(500).json({
success: false,
message: err.message
});
});
});
this is my email template
var emailTemplate = `Hello ${req.decoded.name}, \n
thank you for your order! \n
Engraving: ${newCharge.description} \n
Amount: ${newCharge.amount / 100 } \n
Your full order details are available at ecart.io/#/order-complete/${
charge.id
} \n
For questions contact your_support_email#gmail.com \n
Thank you!`;
let mailTransporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: "a#gmail.com",
pass: "sq"
}
});
let details = {
from: "a#gmail.com",
to: `${req.decoded.email}`,
subject: "shipping",
text: emailTemplate
};
mailTransporter.sendMail(details, err => {
if (err) {
console.log(err);
} else {
console.log("email sent");
}
});
tried adding it in my .then function but i'm not getting a good response I expected either an error message or the email sent to be logged but that is not happening.
do these
.then(source => {
return stripe.charges.create({
amount: totalPrice,
currency: "usd",
customer: source.customer
},
function(err, charge) {
if (err) {
console.log(err);
} else {
var emailTemplate = `Hello ${req.decoded.name}, \n
thank you for your order! \n
Amount: ${charge.amount / 100} \n
Your full order details are available at ecart.io/#/order-complete/${
charge.id
} \n
For questions contact your_support_email#gmail.com \n
Thank you!`;
let mailTransporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: "a#gmail.com",
pass: "sq"
}
});
let details = {
from: "a#gmail.com",
to: `${req.decoded.email}`,
subject: "shipping",
text: emailTemplate
};
mailTransporter.sendMail(details, err => {
if (err) {
console.log(err);
} else {
console.log("email sent");
}
});
}
},
);
})

Problem structuring two factor authentication

const login = (req, res) => {
// console.log(req.body);
// let email = req.body.email.toLowerCase();
sequelize.models.User.findOne({
where: {
email: req.body.email,
},
})
.then(async (user) => {
if (!user) {
// console.log(" email not found is true");
return res.status(401).json({
success: false,
message: " Authentication failed, Wrong Credentials",
});
}
if (user.isActive == false) {
// console.log("user is not activated", user.isActive);
return res.status(400).json({
success: false,
message: "account is not activated",
});
}
console.log("test entry");
await user.comparePassword(req.body.password, async (err, isMatch) => {
console.log(req.body.password);
if (isMatch && !err) {
console.log("user crap");
// role_id: user.role_id,
const payload = {
user_id: user.user_id,
};
const options = {
expiresIn: "10day",
};
const token = await jwt.sign(payload, process.env.SECRET, options);
console.log("sssssss", payload);
if (user.twoFactorAuth == false) {
return res.json({
success: true,
token,
});
} else {
// let mobile = user.phone;
await twoFactorAuth(user); // we call the 2fa that will send a otp to the users cellphone
// console.log("after cb");
}
} else {
return res.json({
success: false,
msg: "Authentication failed.",
});
}
});
// console.log("user crap", user.user_id);
})
.catch((error) => {
return res.status(400).send(error);
});
};
const twoFactorAuth = async (user) => {
var data = qs.stringify({
sender: "hehe",
mobile: user.phone,
channel: "sms",
});
var config = {
method: "POST",
url: "https://blablabla",
headers: {
Authorization: "Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
},
data: data,
};
axios(config)
.then( async function (response) {
console.log(JSON.stringify(response.data));
// await verifyTwoFactorAuth (realToken)
})
.catch(function (error) {
console.log(error);
});
};
const verifyTwoFactorAuth = async(req, res) => {
//console.log("tet",req);
let otpcode = req.body.otpcode;
let mobile = req.body.mobile;
var data = qs.stringify({ mobile: mobile, code: otpcode });
var config = {
method: "POST",
url: "https://blablabla",
headers: {
Authorization: "Bearer xxxxxxxxxxxxxxxxxxxxxxxx",
},
data: data,
};
axios(config)
.then(async function (response) {
console.log(JSON.stringify(response.data));
if (response.data.code == 63 || response.data.status == 200) {
return res.json({
success: true,
token,
});
} else if (response.data.code == 21 || response.data.status == 422) {
return res.status(400).json({
success: false,
message: "wrong code, check your sms again",
});
}
})
.catch(function (error) {
console.log(error);
});
};
Hello, I am looking for a structure solution to how I should implement what I want.
Scenario: user try to login, system checks for username and passoword and generates the TOKEN, system finds that 2fa is active in users settings, system sends OTP to users cellphone.
Now my struggle begins, I am not sure what to do next, I thought about storing the token in users fields as tempToken then i look for the user via users mobile and extract the token that way, but I dont believe that this is best practice.
Any ideas of how to tackle this would be appreciated ! thank you

not sure why nodemailer isnt working properly

Not sure why this isnt working properly. i think the configuration looks right but I keep getting this error :getaddrinfo ENOTFOUND smpt.mydomian.com
let transporter = nodemailer.createTransport({
host: "smtp.mydomain.com",
port: 465,
secure: true,
auth: {
user: "abc#mydomain.com",
pass: "password",
},
});
let mailOptions = {
from: email,
to: "abc#domail.com",
subject: `New Lead ${fullName}`,
text: newMail,
};
// step 3
transporter.sendMail(mailOptions, (err, data) => {
if (err) {
console.log("there is an error " + err);
} else {
console.log("mail sent successfully");
}
});
});
in my opinion its better to create a class for that just like this
class Mailer {
sendMail = async (emailAddress) => {
let transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: testUser,
pass: testPass,
},
});
const option = {
from: `${EMAIL_ADDRESS}`,
to: emailAddress,
subject: "test Subject",
text: "Test text",
};
await transporter.sendMail(option, (err, info) => {
if (!err) {
console.log(`Email sent Successfully ... !`.green.underline.bold);
return true;
} else {
console.log(
`We have problem while sendil Email ... !`.red.underline.bold
);
return false;
}
});
};
}
i hope this class help you

ejs renderFile condition to check for null

I have a mail route which is using ejs templates to choose different files. Now I want to check for different files and if the files does not exist or null it should choose default "en.ejs" file
inside ejs.renderFile I want to check for if(selectedLanguage !==null{}) but I am not sure how can I do it.
router.post('/mail', (req, res) => {
const subject = 'Test Mail';
const url = process.env.REPORT_URL;
const selectLanguage = req.body.selectedLang
sgMail.setApiKey(SGAPIKEY);
ejs.renderFile(__dirname + `/../ejs/reports/${selectLanguage}.ejs`, {
url: url
},
function (err, data) {
if (err) {
return err;
} else {
const msg = {
to: req.body.sendTo_email,
from: "test#test.com",
subject: subject,
html: data,
cc: req.body.cc,
attachments: [{
content: req.body.pdfBase64,
filename: 'file.pdf',
type: 'application/pdf',
disposition: 'attachment'
}]
};
sgMail.send(msg, error => {
if (error) {
return res.status(400).send({
sent: false
});
} else {
return res.status(200).send({
sent: true
});
}
});
}
});
});
You can check if the template file for the selected language exists (by using fs.access) and fallback to the en.ejs template before calling ejs.renderFile:
const fs = require('fs');
const getTemplateFileName = (lang, callback) => {
const defaultTemplate = __dirname + '/../ejs/reports/en.ejs';
const selectedLangTemplate = __dirname + `/../ejs/reports/${lang}.ejs`;
fs.access(selectedLangTemplate, fs.constants.F_OK, (err) => {
if (err) {
callback(defaultTemplate);
} else {
callback(selectedLangTemplate)
}
})
};
router.post('/mail', (req, res) => {
const subject = 'Test Mail';
const url = process.env.REPORT_URL;
const selectLanguage = req.body.selectedLang
sgMail.setApiKey(SGAPIKEY);
getTemplateFileName(selectLanguage, (filename) => {
ejs.renderFile(filename, { url }, function (err, data) {
if (err) {
return err;
} else {
const msg = {
to: req.body.sendTo_email,
from: "test#test.com",
subject: subject,
html: data,
cc: req.body.cc,
attachments: [{
content: req.body.pdfBase64,
filename: 'file.pdf',
type: 'application/pdf',
disposition: 'attachment'
}]
};
sgMail.send(msg, error => {
if (error) {
return res.status(400).send({
sent: false
});
} else {
return res.status(200).send({
sent: true
});
}
});
}
})
});
});

how to send mail notification in node.js from getting response

I want to send the response through mail in table format.
In mail options html I declare the res.json(streamingTemplate)== and the following error is returned:
Unhandled rejection Error: Can't set headers after they are sent. at
ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:356:11) at
ServerResponse.header
like that i got...
var sendStreamingTemplate = function (req, res) {
authToken = req.headers.authorization;
userAuthObj = JSON.parse(UserAuthServices.userAuthTokenValidator(authToken));
var todayDate = new Date();
var expireDate = new Date(userAuthObj.expire_date);
tokenOK = TokenValidator.validateToken(userAuthObj.user_id, authToken).then(function (userSessions) {
if (userSessions.length === 1) {
if (expireDate >= todayDate) {
StreamingTemplateId = req.params.id;
TemplateController.findById(StreamingTemplateId).then(function (streamingTemplate) {
if (streamingTemplate === null) {
res.status(404).json({
message: 'Streaming not found...'
})
} else {
console.log(streamingTemplate);
let transporter = nodemailer.createTransport({
host: 'smtp.zoho.com',
port: 465,
auth: true,
active: true,
secure: true,
requireTLS: true,
auth: {
user: 'aaaaaaa#domain.com',
pass: 'yyyyyyyy'
}
});
let mailOptions = {
from: 'aaaaaaa#domain.com',
to: 'bbbbbbbbb#domain.com',
subject: 'mail notification Test',
text: 'Hello !!!!!!!!!everything works fine',
html:res.json(streamingTemplate)// i want to send whatever response get i will send to through mail in table format
};
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log("mail not sent" +error.message);
}
console.log('success');
});
switch(streamingTemplate.template_name.toString().toLowerCase()){
case "stream":
res.json(streamingTemplate);
break;
case "broadcaster":
res.json(streamingTemplate);
break;
case "product":
res.json(streamingTemplate);
break;
default:
res.json(streamingTemplate);
break;
}
}
}).catch(function (err) {
res.status(500).json({
message: 'something went wrong...'
});
});
} else {
res.status(401).json({
message: 'Not Authorized...'
});
}
} else {
res.status(401).json({
message: 'Token Expired...'
});
}
}).catch(function (err) {
res.status(401).json({
message: 'Token Expired...'
});
});
};
The res.json() method is a terminal method, which ends the response writing the json specified in it. Therefore, while configuring the mailOptions, it should not be used.
let mailOptions = {
from: 'aaaaaaa#domain.com',
to: 'bbbbbbbbb#domain.com',
subject: 'mail notification Test',
text: 'Hello !!!!!!!!!everything works fine',
html: res.json(streamingTemplate) // Response should not be sent here
};
Instead, the streamingTemplate should be passed to the html argument of mailOptions.
let mailOptions = {
from: 'aaaaaaa#domain.com',
to: 'bbbbbbbbb#domain.com',
subject: 'mail notification Test',
text: 'Hello !!!!!!!!!everything works fine',
html: streamingTemplate // set the template here
};

Resources