Sending SMTP emails via Netlify

Hello RW community,

I’ve been following Rob’s instructions from here in order to send emails via redwood app. Everything works on the localhost side and I do receive the emai. However, once I deploy to netlify it doesn’t work. And yes, I did make sure to copy the env variables to the netlify side as well. Localhost works flawlessly.:thinking:

Thanks in advance.

I suggest that you:

  • set your log level to debug in production
  • add log statements to show points in the execution
  • deploy to Netlify
  • open up the function logs on Netlify for graphql and any functions using email
  • try to send
  • see if any errors in log

The Netlify functions log should give you some information.

We had a report of something similar a week or so ago and they found that for some reason the function hadn’t deployed properly.

Once their redeployed, it worked.

1 Like

Thanks @dthyresson
It turned out I didn’t have the await in my sendEmail calls. I added it like below and it works now, any idea why locally works but not prod?

await sendEmail({
      to: user.email,
      subject: verificationEmail.subject(),
      html: verificationEmail.htmlBody(user),
    })

Also sendEmail looks like following:
api/src/lib/mailer.js

import * as nodemailer from 'nodemailer'

import { logger } from 'src/lib/logger'

export async function sendEmail({ to, subject, text, html }) {
  //   if (process.env.DISABLE_EMAIL === 'true') {
  //     return
  //   }
  const transporter = nodemailer.createTransport({
    host: process.env.SMTP_HOST,
    port: process.env.SMTP_PORT,
    secure: false,
    auth: {
      user: process.env.SMTP_USER,
      pass: process.env.SMTP_PASS,
    },
  })

  return transporter.sendMail(
    {
      from: process.env.AUTH_EMAIL_FROM,
      to: Array.isArray(to) ? to : [to],
      subject,
      text,
      html,
    },
    (error) => {
      if (error) {
        logger.error(
          `Failed to send '${subject}' email, check SMTP configuration`
        )
        logger.debug('This error can be ignored in development')
        logger.error(error)
      }
    }
  )
}

@dthyresson correction my solution actually didn’t help.

As you suggested, I put console.log statements as follows:

export async function sendEmail({ to, subject, text, html }) {

  console.log('Inside sendEmail function')
  console.log('process.env.SMTP_HOST: ', process.env.SMTP_HOST)
  console.log('process.env.SMTP_PORT: ', process.env.SMTP_PORT)
  console.log('process.env.SMTP_USER: ', process.env.SMTP_USER)

  const transporter = nodemailer.createTransport({
    host: process.env.SMTP_HOST,
    port: process.env.SMTP_PORT,
    secure: false,
    auth: {
      user: process.env.SMTP_USER,
      pass: process.env.SMTP_PASS,
    },
  })
  console.log('Before transporter.sendMail')

  transporter.sendMail(
    {
      from: process.env.AUTH_EMAIL_FROM,
      to: Array.isArray(to) ? to : [to],
      subject,
      text,
      html,
    },
    (err, info) => {
      if (err) {
        console.log('Error sending email: ', err)
      } else {
        console.log('Email sent envelope:', info.envelope)
        console.log('Email sent messageId:', info.messageId)
      }
    }
  )
}

Here is the log I see on the netlify side:

Feb 2, 10:49:12 PM: b5753259 INFO   process.env.SMTP_HOST:  smtp-relay.sendinblue.com
Feb 2, 10:49:12 PM: b5753259 INFO   process.env.SMTP_PORT:  587
Feb 2, 10:49:12 PM: b5753259 INFO   process.env.SMTP_USER:  myEMAIL ADDRESS
Feb 2, 10:49:12 PM: b5753259 INFO   Before transporter.sendMail

One thing about this log is interesting. It doesn’t show the last console.log message about email being sent or error. I do see those on my local env though.

Any idea what might be happening?

going from

transporter.sendMail(
    {
      from: process.env.AUTH_EMAIL_FROM,
      to: Array.isArray(to) ? to : [to],
      subject,
      text,
      html,
    },
    (err, info) => {
      if (err) {
        console.log('Error sending email: ', err)
      } else {
        console.log('Email sent envelope:', info.envelope)
        console.log('Email sent messageId:', info.messageId)
      }
    }
  )

to

const sendMail = await transporter.sendMail(
    {
      from: process.env.AUTH_EMAIL_FROM,
      to: Array.isArray(to) ? to : [to],
      subject,
      text,
      html,
    })

Solved the issue. Await statement was the key here. Also when I called this function I needed to have await in my call method.

1 Like