Home
Support Forums

Netlify function for sending mail with nodemailer doesn't work in production

Greetings,

I have encountered a problem with netlify functions, specifically, I’m using nodemailer package to send an email from a website. Everything works fine in development and I’m able to receive mail from the site, but in a production environment, I checked the Network tab and it showing Status code 200, but the response body is empty when it should display the message “Message successfully sent” and the message doesn’t arrive in the inbox.

In netlify i checked the Function log and it displays payload with data from a form.

ContactForm.js

<Formik
              onSubmit={async (values, actions) => {
                  const options = {
                     method: 'POST',
                     body: JSON.stringify(values),
                    headers: {
                        'Content-Type': 'application/json'
                   }

               };

              await fetch('/.netlify/functions/sendmail', options)
              .then((res) => {

                actions.setSubmitting(false);
                if (res.ok) setIsSubmited(true);

         })
       catch((err) => {
            actions.setSubmitting(false);
      });
 }}
>

sendmail.js

exports.handler = async (event, context, callback) => {

   const payload = JSON.parse(event.body);

    const msg = {
        to: process.env.MAIL_USERNAME,
        from: payload.email,
        subject: `New message from ${payload.name} | ${payload.email}`,
        text: payload.message
    };

    const transporter = nodemailer.createTransport({

        host: process.env.MAIL_HOST,
        port: 587,
        secure: false,

        auth: {
            user: process.env.MAIL_USERNAME,
            pass: process.env.MAIL_PASSWORD
        },

        tls: {
            rejectUnauthorized: false
        }

    });

    try {
        await transporter.sendMail(msg, (error) => {
            if (!error) {
                callback(null, { statusCode: 200, body: 'Message successfully sent' });
            } else {
                callback(null, { statusCode: 400, body: error });
            }

        });

    } catch (e) {

        callback({ statusCode: e.code, body: e });
    }

};

Please let me know if any other information needs in order to help solve my problem.
Thank you.

Welcome to Netlify @reginatrade

Using a combination of your code and the example from Nodemailer/Ethereal Email I have this working example

const nodemailer = require("nodemailer");

exports.handler = async (event, context, callback) => {

    const transporter = nodemailer.createTransport({
        host: process.env.MAIL_HOST,
        port: 587,
        secure: false,
        auth: {
            user: process.env.MAIL_USERNAME,
            pass: process.env.MAIL_PASSWORD
        }
    });

    let info = await transporter.sendMail({
        from: `"My Name 👻" <${process.env.MAIL_USERNAME}>`,
        to: "bar@example.com, baz@example.com",
        subject: "Hello ✔",
        text: "Hello world?",
        html: "<b>Hello world?</b>",
    });

    if (info.messageId) {
        return {
            statusCode: 200,
            body: nodemailer.getTestMessageUrl(info)
        }
    }
  
    return {
        statusCode: 400,
        body: "Oops"
    }
};
1 Like

Hey, thank you for providing an example, but unfortunately, it doesn’t work in functions logs I’m getting this error

ERROR Invoke Error {"errorType":"Error","errorMessage":"Missing credentials for \"PLAIN\"","code":"EAUTH","command":"API","stack":["Error: Missing credentials for \"PLAIN\""," at t.exports._formatError (/var/task/sendmail.js:1:25819)"," at t.exports.login (/var/task/sendmail.js:1:21038)"," at /var/task/sendmail.js:1:191929"," at t.exports.<anonymous> (/var/task/sendmail.js:1:17645)"," at Object.onceWrapper (events.js:420:28)"," at t.exports.emit (events.js:314:20)"," at t.exports._actionEHLO (/var/task/sendmail.js:1:33454)"," at t.exports._processResponse (/var/task/sendmail.js:1:27841)"," at t.exports._onData (/var/task/sendmail.js:1:25511)"," at TLSSocket._onSocketData (/var/task/sendmail.js:1:17335)"]}

and response status is 500, with my provided example I was able to get status code 200, but the mail didn’t arrive

As well I need to add this parameter

tls: {
    rejectUnauthorized: false
}

otherwise, I’m getting a certificate mismatch error.

Tested in dev and its works but not in production

Have you included your credentials? MAIL_USERNAME (and other variables) need setting prior to the function build (see Build environment variables | Netlify Docs)

Is it possible your mail system (receiving) flagged the message as spam, or outright rejected it? Do you have SPF/DKIM set up on your outgoing mail address? The reason I used Ethereal Email is because if I used my normal email, I would need to add a raft settings to ensure it didn’t bounce.

Then all you need do is add that in. I did not require it for my testing so omitted it.

I tested this in both without issue.

Thank you soo much for your help, the problem actually got resolved by changing port to 465 and then I removed this line

tls: {
    rejectUnauthorized: false
}

And everything works now.

Thanks once again!

2 Likes

Hey there, @reginatrade :wave:

Thank you so much for coming back and sharing this update with the Forums :netliconfetti: This will definitely be beneficial to members who encounter something similar in the future.