zevanb
zevanb

Reputation: 41

nodemailer gmail connection closed with high number of mails

I have exactly the same issue as this post : Send multipe emails using nodemailer and gmail

When sending too many emails with nodemailer and gmail, I get a 421 error, referring to too many concurrent sessions.

What can i do to avoid opening too many sessions ?

I already contact google who confirm me I wasn't blocked by any limitation ( I didn't reach the number of daily mail and there is no limit on mail/minute). I tried to wait for each mail to be sent before sending a new one; to create and close new transport at each mail, but I keep getting this error after approximately the 100th email.

Here the complete error:

{ [Error: Mail command failed: 421 4.7.0 Try again later, closing 
connection. (MAIL) e17sm2124566ede.14 - gsmtp]
code: 'EENVELOPE',
response: '421 4.7.0 Try again later, closing connection. (MAIL) 
e17sm2124566ede.14 - gsmtp',
responseCode: 421,
command: 'MAIL FROM' }

And my code :

Nodemailer settings :

function setMailTransport () {
  return nodemailer.createTransport(smtpTransport({
    service: 'gmail',
    ignoreTLS: true,
    auth: {
      xoauth2: xoauth2.createXOAuth2Generator({
        user: 'xxxxxx',
        clientId: 'xxxxxx',
        clientSecret: 'xxxxxx',
        refreshToken: 'xxxxxx'
      })
    }
  }))
}

Sending unique mail :

async function sendEmail (mail) { 
  // mail is an object {from, to, subject, text, html}
  const transport = setMailTransport()
  try {
    await transport.sendMail(mail)
    await transport.close()
    return 1
  } catch (err) {
    console.log(err)
    await transport.close()
    return 0
  }
}

Recursive async/await function to wait mail be sent before sending a new one :

async function sendAlerts (mails, index, numberOfMailSent) {
  // mails is an array of mail object, index start at 0  
  // numberOfMailSent is just a counter to know how many mails have been sent
  if (index >= mails.length) return numberOfMailSent
  const mail = mails[position]
  const newMailSent = await sendEmail(mail)
  return sendAlerts(mails, index + 1, numberOfMailSent + newMailSent)
}

Any idea of where I could have been wrong or on any other way to send more than 100 mails ?

Upvotes: 4

Views: 5132

Answers (2)

David Kahara
David Kahara

Reputation: 21

You should add the pool parameter to your nodemailer transporter config object:

export const transporter = nodemailer.createTransport({
  service: 'gmail',
  auth: {},
  pool: true
});

For additional configuration options, you can check here

Upvotes: 2

Cokadev
Cokadev

Reputation: 1

Use Pooled SMTP : https://nodemailer.com/smtp/pooled/

If pooling is used then Nodemailer keeps a fixed amount of connections open and sends the next message once a connection becomes available. It is mostly useful when you have a large number of messages that you want to send in batches or your provider allows you to only use a small amount of parallel connections.

Upvotes: -3

Related Questions