Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nodemailer in vercel not sending email in production

I'm using Nodemailer to send emails in my serverless Next.js project, deployed in Vercel, which works perfectly in development mode. But I'm having problems in production. No error returned, everything works the same way as is development mode, except I don't receive any email.

I have another project built with React and deployed in Heroku where I send emails the same way and it works fine, development and production, so I understand the problem is with Vercel.

Yes, I enabled "Allow Less Secured Apps" in Google account and yes, I enabled Captcha.

I also read this https://vercel.com/docs/solutions/email but it doesn't really make me understand what I should do in my case. I can see it's a matter of SMTP but I don't know what exactly.

Anybody experienced this kind of problem? How can I fix this?

const transporter = nodemailer.createTransport({
    host: "smtp.gmail.com",
    port: 465,
    auth: {
        user: [email protected],
        pass: myEmailPass
    }
});
            
const mailOptions = {
    from: `${req.body.name} ${req.body.email}`,
    to: [email protected],
    subject: `${req.body.subject}`,
    text: `Text: ${req.body.text}`
}
            
transporter.sendMail(mailOptions, (err, res) => {
    if(err) {
          console.log(err);
    } else {
          console.log("success");
    }
});

UPDATE

I changed to SendGrid: made an account, created an API Key, and changed the code like so(instead the one above):

sgMail.setApiKey(process.env.SENDGRID_API_KEY);
const msg = {
    to: `[email protected]`,
    from: `[email protected]`,
    subject: `${req.body.subject}`,
    text: `${req.body.text}`
};
sgMail
.send(msg)
.then(() => {
     console.log('email sent')
})
.catch((error) => {
     console.error("error", error)
});

It logs out "email sent" but I don't receive any email. It's the same problem like with Nodemailer. I'm confused now...

like image 963
Daniel Ioanitescu Avatar asked Jan 08 '21 15:01

Daniel Ioanitescu


People also ask

What is nodemailer?

Nodemailer is a module for Node.js applications to allow easy as cake email sending. The project got started back in 2010 when there was no sane option to send email messages, today it is the solution most Node.js users turn to by default. Nodemailer is licensed under MIT license. See license details in the License page.

How to send emails from Vercel without restrictions?

To send emails from Vercel without restrictions, we recommend the use of a third-party mail services: By using one of the services listed above, you will also benefit from analytics, scheduling, and many other features exclusively available from a specialized service.

Can I use SMTP with Vercel?

– Vercel Docs Can I use SMTP with Vercel? While the Vercel platform does not block outgoing SMTP connections, it is recommended to use a third-party service to send email. To send emails from Vercel without restrictions, we recommend the use of a third-party mail services:

How do I install nodemailer?

How to Install Nodemailer. Install nodemailer using the following command: npm install nodemailer. Nodemailer’s API is pretty simple and requires us to do the following: Create a Transporter object; Create a MailOptions Object; Use the Transporter.sendMail method; To create a transporter object, we do the following:


Video Answer


4 Answers

I ran into this issue and managed to fix it and keep using nodemailer by adding in promises with async/await.

const nodemailer = require("nodemailer");

export default async (req, res) => {

const { firstName, lastName, email, message } = JSON.parse(req.body);

const transporter = nodemailer.createTransport({
    port: 465,
    host: "smtp.gmail.com",
    auth: {
        user: "[email protected]",
        pass: "password",
    },
    secure: true,
});

await new Promise((resolve, reject) => {
    // verify connection configuration
    transporter.verify(function (error, success) {
        if (error) {
            console.log(error);
            reject(error);
        } else {
            console.log("Server is ready to take our messages");
            resolve(success);
        }
    });
});

const mailData = {
    from: {
        name: `${firstName} ${lastName}`,
        address: "[email protected]",
    },
    replyTo: email,
    to: "[email protected]",
    subject: `form message`,
    text: message,
    html: `${message}`,
};

await new Promise((resolve, reject) => {
    // send mail
    transporter.sendMail(mailData, (err, info) => {
        if (err) {
            console.error(err);
            reject(err);
        } else {
            console.log(info);
            resolve(info);
        }
    });
});

res.status(200).json({ status: "OK" });
};
like image 135
shuggs Avatar answered Oct 21 '22 00:10

shuggs


This problem is really confusing indeed. I've managed to fix this by simply adding async/await. This is because streaming responses (fire-and-forget functions) are not supported by Vercel.

Source: https://vercel.com/docs/platform/limits#streaming-responses

like image 40
yvog Avatar answered Oct 21 '22 00:10

yvog


I have already encountered the same problem, nodemailer was not working on vercel but on heroku everything worked perfectly. it is specified in the doc that vercel does not block stmp connections but according to what I have experienced, in practice stmp connections are blocked. what you can do is use an alternative to nodemailer. use sendgrid and it works fine

An article on how integrating Sendgrid with Next.js

like image 2
enoch Avatar answered Oct 21 '22 00:10

enoch


I had a similar issue with Nodemailer but I fixed it by first adding the environment variables in Vercel then commit to the github(It will automatically be uploaded on vercel). So add the variables to vercel first for it to take effect

like image 2
Bryan Bandela Avatar answered Oct 21 '22 00:10

Bryan Bandela