Nodemailer is sending emails as a thread if the email has the same subject as a previously sent email. But I want to send the emails as separate emails, even if they have the same subject as each other.
I have an application that sends notification emails to users. The emails all have the same subject: notification. This is causing the emails to show as a thread, at least in Gmail:
How can I make each notification email send separately?
const nodemailer = require('nodemailer');
const logger = require('./logger');
class Email {
constructor(email, to, pass) {
this.user = email;
this.to = to;
this.pass = pass;
}
get mailOptions() {
return {
from: this.user,
to: this.to,
subject: 'notification',
html: 'You received a new purchase in your shop.',
};
}
get transporter() {
const transporter = nodemailer.createTransport({
// for zoho emails
host: 'smtp.zoho.com',
port: 587,
secure: false,
auth: {
user: this.user,
pass: this.pass,
},
});
return transporter;
}
send(cb) {
this.transporter.sendMail(
this.mailOptions,
cb ||
((error, info) => {
if (error) console.log(error);
if (info) logger.log('silly', `message sent: ${info.messageId}`);
this.transporter.close();
})
);
}
sendSync() {
return new Promise((res, rej) =>
this.transporter.sendMail(this.mailOptions, (error, info) => {
if (error) rej(error);
else res(info);
this.transporter.close();
})
);
}
}
const email = new Email(
'somesendingemail#gmail.com',
'somereceivingemail#gmail.com',
'SendINgEmAIlPassWoRD'
);
email.send();
Related
My Node js code is sending proper email on localhost but in backend there showing email and password not valid ?
const nodemailer = require("nodemailer");
const sendEmail = async (subject, message, send_to, sent_from, reply_to) => {
// Create Email Transporter
const transporter = nodemailer.createTransport({
host: process.env.EMAIL_HOST,
port: 465,
secure: true,
auth: {
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASS,
},
});
// Options for sending email
const options = {
from: sent_from,
to: send_to,
reply_to: reply_to,
subject: subject,
html: message,
};
// Check email sent successfully or not
transporter.sendMail(options, function (err, info) {
if (err) {
console.log(err);
} else {
console.log(info);
}
});
};
module.exports = sendEmail;
I'm trying to find a way to set up a contact us form, when a user is submitting an enquiry I should receive an email, also the user should receive an email telling that the enquiry reached us, I figured out that I should use nodemailer to send mails, now the first step is done which I receive an email whenever the user submitted an enquiry, the question is how can I send him an email after submitting the enquiry? excuse my bad English
Nodemailer setup
//email from the contact form using the nodemailer
router.post('/send', async(req, res) => {
console.log(req.body);
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.EMAIL_USERNAME, //email resposible for sending message
pass: process.env.EMAIL_PASSWORD
}
});
const mailoptions = {
from: process.env.FROM_EMAIL,
to: process.env.EMAIL_USERNAME, //email that recives the message
subject: 'New Enquiry',
html: `<html><body><p>Name: ${req.body.name}</p><p> Email: ${req.body.email}</p><p>message: ${req.body.content}</p></body></html>`
}
transporter.sendMail(mailoptions, (err, info) => {
if (err) {
console.log('error');
res.send('message not sent'); //when its not ent
} else {
console.log('message sent' + info.response);
res.send('sent'); //when sent
}
})
});
module.exports = router;
So I tried some codes and code worked for me, it's sending to the admin and the client, hope it helps
router.post('/send', async(req, res, next) => {
console.log(req.body);
if (!req.body.name) {
return next(createError(400, "ERROR MESSAGE HERE"));
} else if (!req.body.email) {
return next(createError(400, "ERROR MESSAGE HERE"));
} else if (!req.body.email || !isEmail(req.body.email)) {
return next(createError(400, "ERROR MESSAGE HERE"));
} else if (!req.body.content) {
return next(createError(400, "ERROR MESSAGE HERE"));
}
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.EMAIL_USERNAME, //email resposible for sending message
pass: process.env.EMAIL_PASSWORD
}
});
const mailOptionsAdmin = {
from: process.env.FROM_EMAIL,
to: process.env.EMAIL_USERNAME, //email that recives the message
subject: 'New Enquiry',
html: `<html><body><p>Name: ${req.body.name}</p><p> Email: ${req.body.email}</p><p>message: ${req.body.content}</p></body></html>`
}
const mailOptionsClient = {
from: process.env.FROM_EMAIL,
to: req.body.email, //email that recives the message
subject: 'Recivied',
html: `<html><body><p>message: We recived your enquiry</p></body></html>`
}
transporter.sendMail(mailOptionsAdmin, (err, info) => {
if (err) {
console.log('error');
res.send('message not sent'); //when its not ent
} else {
console.log('message sent' + info.response);
res.send('sent'); //when sent
transporter.sendMail(mailOptionsClient)
}
})
});
I don't why i'm getting this every time I try to use Nodemailer to send emails:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent
to the client
at new NodeError (node:internal/errors:371:5)
at ServerResponse.setHeader (node:_http_outgoing:576:11)
the thing is it's working but i'm getting this error, by working I mean It sends the email.
The Code:
const sendEmail = async (email, subject, payload, template) => {
try {
// create reusable transporter object using the default SMTP transport
const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: process.env.EMAIL_USERNAME,
pass: process.env.EMAIL_PASSWORD,
},
});
const options = () => {
return {
from: process.env.FROM_EMAIL,
to: email,
subject: subject,
html: template,
};
};
// Send email
transporter.sendMail(options(), (error, info) => {
if (error) {
return error;
} else {
return res.status(200).json({
success: true,
});
}
});
} catch (error) {
throw error;
}
};
router.post("/", async (req, res, next) => {
try {
if (!req.body.newsletterEmail) {
return next(createError(400, "Please enter your email"));
} else if (!req.body.newsletterEmail || !isEmail(req.body.newsletterEmail)) {
return next(createError(400, "Please enter a valid email address"));
}
const checkEmail = await SubscribedEmails.findOne({ newsletterEmail: req.body.newsletterEmail });
if (checkEmail) {
return next(createError(400, "Email is already subscribed"));
} else {
//create new user
const newSubscribedEmail = new SubscribedEmails ({
newsletterEmail: req.body.newsletterEmail,
});
//save user and respond
const SubscribedEmail = await newSubscribedEmail.save();
res.status(200).json({
message: "Successfully subscribed",
SubscribedEmail,
});
const link = `${process.env.CLIENT_URL}/`;
await sendEmail(
SubscribedEmail.newsletterEmail,
"Welcome to our newsletter!",
{
link: link,
},
`<div> <p>Hi,</p> <p>You are subscribed to our.</p> <p> Please click the link below to view more</p> <a href=${link}>GO</a> </div>`
);
return res.status(200).send(link);
}
} catch(err) {
next(err);
}
});
This is likely due to some quirks with using Gmail with Nodemailer. Review the docs here - https://nodemailer.com/usage/using-gmail/
and configure your Gmail account here -
https://myaccount.google.com/lesssecureapps
Finally, you may run into issues with Captcha. Configure here - https://accounts.google.com/DisplayUnlockCaptcha
I'm using nodemailer to send email validations with no success, I get no errors when sending the e-mail, it actually says the e-mail was sent but I recieve nothing.
I tried sending e-mails using this e-mail (with gmail integration) and it works fine.
This is my config
import Mailer from "nodemailer";
async function sendEmail(emailData) {
const SMTP = process.env.EMAIL_SMTP;
const SENDER = Mailer.createTransport({
host: SMTP,
port: 465,
secure: true,
auth: {
user: process.env.EMAIL_SENDER,
pass: process.env.EMAIL_SENDER_PASSWORD
},
tls: {
ignoreTLS: true
}
});
const RECEIVER = {
from: process.env.EMAIL_SENDER,
to: emailData.to,
subject: emailData.subject,
text: emailData.text,
};
SENDER.sendMail(RECEIVER, function (error) {
if (error) {
console.log(error);
} else {
console.log("E-mail sent"); // E-mail sent is fired at console
}
});
await SENDER.verify(function (err, success) {
console.log({ err, success }); // {err: null, success: true}
})
}
I'm trying to send this using local env, does this work locally or the SMTP should match my domain?
I am using Nodemailer to send emails to my users.
Email used to send emails is 'xyz#toyjunction.online' not gmail.
const nodemailer = require('nodemailer');
let sendMail = async (userName, email, password) => {
return new Promise(function (resolve, reject) {
var smtpConfig = {
host: 'smtp.gmail.com',
port: 465,
secure: true, // use SSL
auth: {
user: 'xyz#toyjunciton.online',
pass:'xxxxxx'
}
};
var transporter = nodemailer.createTransport(smtpConfig);
const mailOptions = {
from: 'xyz#toyjunciton.online',
to: email,
subject: 'Demo Subject',
html: `Hi ${userName}, Your new password is ${password}.`
};
transporter.sendMail(mailOptions, (err, info) => {
let rtnStatus;
if (err) {
reject(false);
} else {
resolve(true);
}
return rtnStatus;
});
});
}
module.exports = sendMail;
Getting error:
Invalid login: 535-5.7.8 Username and Password not accepted.
I have seen a lot of solutions on the internet but not worked for me.