0

I am sending bulk emails from Firebase HTTP Request using Nodemailer. Some of the emails are always missed out and it returns with this error:

Client network socket disconnected before secure TLS connection was established

Here is my code for Client-Side:

export const sendEmails = async () => {
    // Fetch All Users
    let users = []
    let data = await db.collection('users')

    data.forEach(e => {
        let data = e.data()
        let email = data['email']
        users.push({ email })
    })

    // Divide users into multiple batches of 25
    let batches = [[]], num = 0, batchSize = 25

    Promise.all(users.map(batch => {
        if (batches[num].length < batchSize) {
            batches[num].push(batch)
        } else {
            batches.push([batch])
            num++
        }
    }))

    // Send Email Request for each batch with some cooldown time. 
    Promise.all(batches.map((batch, index) => {
        setTimeout(async () => {
            await sendBroadcast(batch)
        }, 2000 * index)
    }))
}

export const sendBroadcast = async (users) => {
    const url = base + "sendBroadcast?"
    const body = JSON.stringify({ users })
    return await fetch(url, { method: "POST", body })
}

Server-Side:

let transporter = nodemailer.createTransport({
    service: 'gmail',
    pool: true,
    maxConnections: 20,
    maxMessages: 500,
    auth: {
        user: 'SOME EMAIL',
        pass: 'SOME PASSWORD',
    },
})

exports.sendBroadcast = functions.runWith({ timeoutSeconds: 540, memory: '2GB' }).https.onRequest((req, res) => {
    cors(req, res, () => {
        const body = JSON.parse(req.body)
        const users = body.users

        console.log('info', 'Send email to ' + users.length + ' users')

        users.forEach(function (to, index) {
            var msg = {
                from: 'SOME EMAIL',
                to: to.email,
                subject: "SUBJECT",
                html: "<h2> SOME HTML </h2>",
            }

            setTimeout(() => {
                return transporter.sendMail(msg, (erro, info) => {
                    if (erro) {
                        console.log('error', erro.message, 'failed to send to ' + email)
                        return res.status(500).send(erro.toString())
                    }
                    return res.send('sent')
                })
            }, 10000 * index)

        })
    })
})

I was getting the Error "Temporary System Problem. Try again later (10)" before, so I added the cooldown time and sent multiple requests in batches. But now I'm getting the TLS error. I have tried a lot of solutions online, but there is always some error due to which all emails don't get sent.

Inaara Kalani
  • 265
  • 7
  • 24
  • Have you referred to these links? https://stackoverflow.com/a/64893685/15774177, https://firebase.google.com/docs/functions/terminate-functions. – Zeenath S N May 26 '22 at 12:45
  • @ZeenathSN the solution in your link says to return the transporter.sendMail() and I'm already doing that. – Inaara Kalani May 26 '22 at 13:38
  • What is exactly wrong with an approach based on `Promise.all()`? – Renaud Tarnec May 26 '22 at 13:39
  • @RenaudTarnec it was giving this error: "Temporary System Problem. Try again later (10)" – Inaara Kalani May 27 '22 at 05:08
  • Can you check if this [stackoverflow thread](https://stackoverflow.com/questions/45756808/bulk-emails-failed-with-421-4-7-0-try-again-later) helps you? – Zeenath S N Jun 08 '22 at 11:19
  • @ZeenathSN I am already using pooling and timeout. I've already seen this thread and I'm using everything it suggested. – Inaara Kalani Jun 09 '22 at 06:05
  • Please raise [Support ticket](https://support.google.com/a/answer/1047213?hl=en) with Google workspace support with the description of your issue. – Roopa M Jun 21 '22 at 04:56

0 Answers0