1

I need to extend the functionality of my SMTP feature to handle bulk emails. It works fine, however when a big amount of emails presented it sends them very slowly (about 2-3 per second). Our current AWS plan allows up to 15 emails per second. I read NodeMailer documentation and tried to implement the SES SDK, however it crashes my app right away.

Here is an error:

/home/node/app/node_modules/@aws-sdk/client-ses/dist-cjs/protocols/Aws_query.js:3734
         if (input.ReplacementTags?.length === 0) {
                                   ^
 
 SyntaxError: Unexpected token '.'
     at wrapSafe (internal/modules/cjs/loader.js:915:16)
     at Module._compile (internal/modules/cjs/loader.js:963:27)
     at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
     at Module.load (internal/modules/cjs/loader.js:863:32)
     at Function.Module._load (internal/modules/cjs/loader.js:708:14)
     at Module.require (internal/modules/cjs/loader.js:887:19)
     at require (internal/modules/cjs/helpers.js:74:18)
     at Object.<anonymous> (/home/node/app/node_modules/@aws-sdk/client-ses/dist-cjs/commands/CloneReceiptRuleSetCommand.js:8:21)
     at Module._compile (internal/modules/cjs/loader.js:999:30)
     at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
 [nodemon] app crashed - waiting for file changes before starting...

Here is my dependency list:

"@aws-sdk/client-ses": "^3.204.0",
"@aws-sdk/credential-provider-node": "^3.204.0",
"nodemailer": "^6.4.16"

And here is my nodeMailer code:

require('dotenv').config()
const nodemailer = require('nodemailer')
const Settings = require('./agentLogic/settings')
const Util = require('./util')

let aws = require('@aws-sdk/client-ses') // new feature I'm trying to implement
let {defaultProvider} = require('@aws-sdk/credential-provider-node') // new feature I'm trying to implement

const ses = new aws.SES({
  apiVersion: '2010-12-01',
  region: 'us-west-2',
  defaultProvider,
}) // new feature I'm trying to implement

let currentSMTP = {}

async function emailService() {
  currentSMTP = await Settings.getSMTP()

  const decryptedPassword = Util.decrypt(
    currentSMTP.dataValues.value.auth.pass,
    currentSMTP.dataValues.value.IV,
  )

  const transporter = nodemailer.createTransport({
    host: currentSMTP.dataValues.value.host,
    // Defaults to 587 if "secure" is false or no value provided or 465 if true
    port:
      currentSMTP.dataValues.value.encryption === false
        ? 587
        : !currentSMTP.dataValues.value.encryption
        ? 587
        : currentSMTP.dataValues.value.encryption,
    // False for STARTTLS (must use port 587), true for TLS (must use port 465)
    secure: !currentSMTP.dataValues.value.encryption
      ? false
      : currentSMTP.dataValues.value.encryption,
    auth: {
      user: currentSMTP.dataValues.value.auth.mailUsername
        ? currentSMTP.dataValues.value.auth.mailUsername
        : currentSMTP.dataValues.value.auth.email,
      pass: decryptedPassword,
    },
    tls: {
      // Change to "false" to not fail on invalid certs
      rejectUnauthorized: true,
    },
    SES: {ses, aws}, // new feature I'm trying to implement
    sendingRate: 15, // new feature I'm trying to implement (I need this to match our current AWS SMTP plan of 15 emails/second)
  })

  return transporter
}

const sendMail = async (message) => {
  const transporter = await emailService()

  return new Promise((resolve, reject) => {
    transporter.sendMail(message, (error, info) => {
      if (error) {
        console.log('Error occurred')
        console.log(error.message)
        reject('error')
      } else {
        console.log('Message sent successfully!')
        console.log(nodemailer.getTestMessageUrl(info))
        resolve(true)
      }
      // Only needed when using pooled connections
      transporter.close()
    })
  })
}

Please, note that by default all the SMTP settings are not set. The user may or may not set the SMTP on demand. But the app comes without some SMTP preset values (such as host, username, email etc)

Can anyone help me understand why I'm getting and how to fix it?

Simon Nazarenko
  • 107
  • 2
  • 11
  • 2
    What version of Node is running this? You need at least v14.0.0 to support [optional chaining](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining#browser_compatibility) – Phil Nov 10 '22 at 00:48
  • my docker is on node v12. Let me see if I can upgrade that really quick – Simon Nazarenko Nov 10 '22 at 00:52
  • you were right, Phil. It was the compatibility issue. – Simon Nazarenko Nov 10 '22 at 01:08
  • 2
    It's always a good idea to keep an eye on the [EOL dates for Node versions](https://endoflife.date/nodejs) – Phil Nov 10 '22 at 01:11
  • I'm getting this on v14.18.0. Does anyone have a fix / alternative solution? – Rusty Apr 21 '23 at 18:35

0 Answers0