Reputation: 141
When I try to send an email locally it works but in production, in the network tab I get everything right just email doesn't want to send and I don't get any error.
try {
const { name, email, message } = req.body;
const transporter = nodemailer.createTransport({
port: 465,
host: "smtp.gmail.com",
auth: {
user: process.env.NEXT_PUBLIC_GMAIL_EMAIL,
pass: process.env.NEXT_PUBLIC_GMAIL_PASSWORD,
},
secure: true,
});
const mailData = {
from: process.env.NEXT_PUBLIC_GMAIL_EMAIL,
to: process.env.NEXT_PUBLIC_EMAIL_WHICH_RECIEVES_CONTACT_INFO,
subject: `Message From ${email}`,
text: message,
};
transporter.sendMail(mailData, function (err, info) {
if (err) console.log(err);
else console.log(info);
});
res.status(200).json({ message: "Email sent" });
} catch (error: any) {
res.status(500).json({ message: error.message });
}
Upvotes: 1
Views: 4020
Reputation: 11
I modified the transporter and it solved the issue. This is the whole function to send a mail. the 'html' should
import nodemailer from 'nodemailer';
import config from '../config';
export const sendEmail = async (to: string, subject: string, html: string) => {
const transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
user: config.support_email,
pass: config.support_email_password,
},
tls: {
rejectUnauthorized: false,
},
});
const mailData = {
from: config.support_email,
to,
subject,
html,
};
await new Promise((resolve, reject) => {
transporter.sendMail(mailData, (err, info) => {
if (err) {
reject(err);
} else {
resolve(info);
}
});
});
};
Upvotes: 1
Reputation: 31
for me, adding tls makes it working
const transporter = nodemailer.createTransport({
service: 'gmail',
host: 'smtp.gmail.com',
tls: {
ciphers: "SSLv3",
},
port: 587,
secure: false,
auth: {
user: process.env.MAIL_SENDER,
pass: process.env.MAIL_PASS
}
});
Upvotes: 0
Reputation: 1217
I kind of had a similar issue with nodemailer and Next.js, try to wrap the transporter
in a Promise, hopefully it works for you too:
await new Promise((resolve, reject) => {
transporter.sendMail(mailData, (err, info) => {
if (err) {
console.error(err);
reject(err);
} else {
resolve(info);
}
});
});
explanation: due to the nature of serveless functions, we have to await
for the email to be sent before moving on. if we don't the serverless function will end before sending the email(because it's short-lived)
however, you should note that this solution is good for sending a few emails, if you're planning to bulk send emails you better use a dedicated email service like sendgrid
Upvotes: 11