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)
}
})
});
Related
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 was creating a contact form using nodemailer. I implemented it and it was working fine, but some time later I came back to do a final test in postman it started to give me the following error"message": Not Found - /contact and "stack": "Error: Not Found - /contact\n . I am not sure what's causing the error.
this is code:
const transport = {
host: 'smtp.gmail.com', // Don’t forget to replace with the SMTP host of your provider
port: 587,
secure: false, // use SSL
auth: {
user: process.env.GMAIL,
pass: process.env.PASSWORD
}
}
const transporter = nodemailer.createTransport(transport)
transporter.verify((error, success) => {
if (error) {
console.log(error);
} else {
console.log('Server is ready to take messages');
}
});
app.post('/contact', (req, res, next) => {
const name = req.body.name
const email = req.body.email
const message = req.body.message
const content = ` name: ${name} \n email: ${email} \n message: ${message} `
const mail = {
from: name,
// to: 'RECEIVING_EMAIL_ADDRESS_GOES_HERE', // Change to email address that you want to receive messages on
to: 'xxx#gmail.com', // Change to email address that you want to receive messages on
subject: 'New Message from Contact Form',
text: content
}
transporter.sendMail(mail, (err, data) => {
if (err) {
res.json({
status: 'fail'
})
} else {
res.json({
status: 'success'
})
}
})
})
I'm trying to send a mail to an email address with nodemailer + mailtrap, but i'm receving the mail in the mailtrap account... why is this happening?
here's my code:
const transport = nodemailer.createTransport({
host: "smtp.mailtrap.io",
port: 2525,
auth: {
user: "79a422a4c8485b",
pass: "492900f98e999e",
},
});
app.get("/sendMail", function (req, res) {
const rand = Math.floor(Math.random() * 100 + 54);
const link = `http://localhost:5000/verify?id=${rand}`;
const mailOptions = {
from: "sender#server.com",
to: req.query.to, // DESTINY MAIL, BUT NO MATTER WHAT I PUT IN HERE, I ONLY RECEIVE THE MAIL
// ON THE MAILTRAP ACCOUNT!
subject: "Hello ✔",
text: "Hello world ✔",
html: `Hello,<br> Please Click on the link to verify your email.<br><a href=${link}>Click here to verify</a>`,
};
console.log(mailOptions);
// smtpTransport.sendMail();
transport.sendMail(mailOptions, function (error: any, response: any) {
if (error) {
console.log("no se pudo mandar el mail porque ->", error);
res.end("error");
} else {
console.log("response", response);
console.log(`Message sent: ${response.message}`);
res.send("done");
}
});
});
What am i doing wrong?
When I am trying to send mail from Gmail. I am getting "{"msg":"invalid_request"}" error in response.
Below is the code.
var transporter = nodemailer.createTransport(
smtpTransport({
service: 'Gmail',
auth: {
xoauth2: xoauth2.createXOAuth2Generator({
user: 'pathareshekhar29#gmail.com',
pass: 'XYZ'
})
}
})
);
var mailOptions = {
from: 'pathareshekhar29#gmail.com',
to: user.empEmail,
subject: 'User Account Approval',
text: 'Demo Mail'
};
transporter.sendMail(mailOptions, function (err) {
console.log('ygcasyhgbavsdbahvbdb '+ err);
if (err) {
return res.status(500).send({ msg: err.message });
} else {
res.status(200).send('A verification email has been sent to ' + user.empEmail + '.');
}
});
Could anyone please help me to fix this error.
I can't cancel the request after sending the email successfully. How can I return properly after sending the email? This might be a callback hell, but I cant figure out how to solve it.
I tried to put some return in different parts but it didn't work.
const router = require('express').Router();
const nodemailer = require('nodemailer');
const emailExistence= require('email-existence');
module.exports = router;
// Send email when user has forgotten his/her password
router.post('/forgetPass', (req, res, next) => {
if(!req.body.email){
next(new Error("Email is required."));
return;
}
emailExistence.check(req.body.email, function(err,res){
if(err || !res){
next(new Error("The email does'nt exist."));
return;
}else{
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'myemail#gmail.com',
pass: 'mypassword'
}
});
let mailOptions = {
from: 'myemail#gmail.com',
to: req.body.email,
subject: 'Link for setting a new password',
html: 'Set a new password'
text: 'email text'
};
transporter.sendMail(mailOptions, function(error, info){
if (error) {
next(new Error("Error in sending email."));
return;
}
res.json(Object.assign(req.base, {
message: "The email has been sent successfully.",
data: info
}));
return;
});
}
});
});
Once you set your response field on successful sending, call next() as a last step, so the next middleware gets the request and sends the response back. So basically:
...
res.json(yourResponse);
next();
...
Or, if this is the last middleware, send the response back to client:
res.send(yourResponse);
I solved it in this way. The emailExistence didn't let me to use promises, so I used email-ckeck instead of it:
const router = require('express').Router();
const nodemailer = require('nodemailer');
const emailExistence= require('email-existence');
var emailCheck = require('email-check');
module.exports = router;
router.post('/forgetPass', (req, res, next) => {
if(!req.body.email){
next(new Error("Email is required."));
return;
}
// Check the req.body.email with email pattern regex
var patt = new RegExp (process.env.EMAIL_PATTERN__REGEX),
isEmail = patt.test(req.body.email);
if(!isEmail){
next(new Error("The email does'nt seem to be a valid email. If you are sure about your email validity contact the website admin."));
return;
}
return emailCheck(req.body.email)
.then(function(result){
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.EMAIL,
pass: process.env.EMAILPASSWORD
}
});
let mailOptions = {
from: process.env.EMAIL,
to: req.body.email,
subject: 'Link for setting a new password',
html: 'Set a new password from this link.'
};
return transporter.sendMail(mailOptions)
.then(function (result2) {
res.status(200).json(Object.assign(req.base, {
message: "The email has been sent successfully.",
data: null
}));
return;
},
function(error2){
next(new Error("Error in sending email."));
return;
});
},
function(error) {
next(new Error("The email does'nt seem to be a valid email. If you are sure about your email validity contact the website admin."));
return;
});
});