Отправка электронной почты нескольким получателям через nodemailer

Я пытаюсь отправить электронное письмо нескольким получателям. Для этого я создал массив получателей, но с моим кодом я могу только отправить почту на последний идентификатор электронной почты массива три раза. Что не так с моим кодом?

var nodemailer = require("nodemailer");

var smtpTransport = nodemailer.createTransport(
"SMTP",{
  host: '',
  //  secureConnection: true,         // use SSL
  port: 25
});

var maillist = [
  '****[email protected]****.com',
  '****[email protected]****.com',
  '****[email protected]****.com',
];

var msg = {
    from: "******", // sender address
    subject: "Hello ✔", // Subject line
    text: "Hello This is an auto generated Email for testing  from node please ignore it  ✔", // plaintext body
    cc: "*******"    
    //  html: "<b>Hello world ✔</b>" // html body
}


maillist.forEach(function (to, i , array) {
  msg.to = to;

  smtpTransport.sendMail(msg, function (err) {
    if (err) { 
      console.log('Sending to ' + to + ' failed: ' + err);
      return;
    } else { 
      console.log('Sent to ' + to);
    }

    if (i === maillist.length - 1) { msg.transport.close(); }
  });
});

Ответ 1

Ваша проблема связана с тем же самым msg-объектом из асинхронного кода. Задание foreach завершается до того, как sendMail отправит электронные письма.

Итак, msg.to будет последним элементом из объекта майилист.

Попробуйте клонировать/копировать msg внутри maillist foreach или просто переместить определение msg:

maillist.forEach(function (to, i , array) {


  var msg = {
        from: "******", // sender address
        subject: "Hello ✔", // Subject line
        text: "Hello This is an auto generated Email for testing  from node please ignore it  ✔", // plaintext body
        cc: "*******"    
        //  html: "<b>Hello world ✔</b>" // html body
    }
  msg.to = to;

  smtpTransport.sendMail(msg, function (err) {

Ответ 2

nodemailer (v2.4.2) docs говорят:

to - Список разделенных запятыми или массив адресов электронной почты получателей, которые появятся в поле Кому:

чтобы вы могли просто сделать:

var maillist = [
  '****[email protected]****.com',
  '****[email protected]****.com',
  '****[email protected]****.com',
];

var msg = {
    from: "******", // sender address
    subject: "Hello ✔", // Subject line
    text: "Hello This is an auto generated Email for testing  from node please ignore it  ✔", // plaintext body
    cc: "*******",
    to: maillist
}

Ответ 3

Насколько я знаю, вы сможете получить несколько получателей, таких как

"[email protected],[email protected],[email protected],[email protected]"

Итак, почему вы не делаете что-то вроде

var maillist = '****[email protected]****.com, ****[email protected]****.com, ****[email protected]****.com';

var msg = {
    from: "******", // sender address
    to: maillist,
    subject: "Hello ✔", // Subject line
    text: "Hello This is an auto generated Email for ...  ✔", // plaintext body
    cc: "*******"    
    //  html: "<b>Hello world ✔</b>" // html body
}

Я уже пробовал и работает. Кроме того, с моей точки зрения, почему вам приходится беспокоиться о "асинхронном" или отправлять электронные письма 1 тыс. Раз, если у вас есть возможность отправки все они только один раз без каких-либо осложнений?

В любом случае надеюсь, что эта помощь, ответьте на ваш вопрос или это может помочь кому-то еще

Конечно, мой ответ можно улучшить..

Ответ 4

var maillist = [
  '****[email protected]****.com',
  '****[email protected]****.com',
  '****[email protected]****.com',
];

maillist.toString();

var msg = {
    from: "******", // sender address
    to: maillist,
    subject: "Hello ✔", // Subject line
    text: "Hello This is an auto generated Email for testing  from node please ignore it  ✔", // plaintext body
    cc: "*******"    
    //  html: "<b>Hello world ✔</b>" // html body
}

Ответ 5

Хорошим способом сделать это асинхронно будет использование каждой функции в асинхронном модуле: https://caolan.github.io/async/docs.html#each

var async = require("async");

async.each(maillist, function(to, callback){

    msg.to = to;

    smtpTransport.sendMail(msg, function (err) {
        if (err) { 
            console.log('Sending to ' + to + ' failed: ' + err);
            callback(err);
        } else { 
            console.log('Sent to ' + to);
            callback();
        }
    });
}, function(err){
    if(err){
        console.log("Sending to all emails failed:" + err);
    }

    //Do other stuff or return appropriate value here
});

Ответ 6

Метод sendMail фактически разрешается после завершения цикла forEach, но проблема в том, что метод sendMail не возвращает тип обещания, поэтому, если вы попытаетесь дождаться этого, он все равно не будет работать.

так что вам нужно создать отдельную функцию для sendmail, поэтому сделайте это как обещание

    const send = (transporter: any, mailOptions: any) => {
    return new Promise((resolve, reject) => {
        transporter.sendMail(mailOptions, (error: any, info: any) => {
          if (error) {
            return reject(error);
          } else {
            return resolve();
          }
        });
    });
    };

так что это позволяет ожидать этого, и, следовательно, итератор будет ждать завершения процесса, прежде чем перейти к следующему циклу.

Полный код должен выглядеть следующим образом

    let transporter = nodemailer.createTransport({
      host: "mail.smtp.com", // your server host address
      port: 587, // port
      secure: false, // use TLS // true for 465, false for other ports
      auth: {
        user: EMAIL_USER, // your email address
        pass: EMAIL_PSW, // your password
      },
      tls: {
        rejectUnauthorized: false
      }
    });

    // store an array of errors if any
    let successful: any[] = [];
    let failed: any[] = [];
    await recipients.forEach(async (to, i) => {
      let mailOptions = {
        from, // sender address
        to, // list of receivers
        subject, // Subject line
        text // plain text body
      };

      if (html) {
        (mailOptions as any).html = html;
      }

      // send mail with defined transport object
      // here we use the fuction we created which is now a promise
      await send(transporter, mailOptions)
        .then(() => {
          successful.push({ success: true, to });
        })
        .catch(reason => {
          failed.push({ success: false, to, message: reason });
        });
      if (i === recipients.length - 1) {
        if (failed.length === recipients.length) {
          return reject({ failed });
        } else {
          return resolve({ successful, failed });
        }
      }
    });
  });


const send = (transporter: any, mailOptions: any) => {
return new Promise((resolve, reject) => {
    transporter.sendMail(mailOptions, (error: any, info: any) => {
      if (error) {
        return reject(error);
      } else {
        return resolve();
      }
    });
});
};

Ответ 7

Вы отправляете письма асинхронно, так что вам нужна функция ожидания, ожидающая всех писем, пока они не были отправлены, потому что если нет, вы выполняете выходы и некоторые из запросов не выполняются. Поэтому вам нужно выполнить функцию таймаута, которая проверяет, отправлены ли письма.

Ответ 8

Sher aik wari feer sher :) Я люблю N лигу Sher aik wari feer sher :) Я люблю N лигу Sher aik wari feer sher :) Я люблю N лигу Sher aik wari feer sher :) Я люблю N лигу Sher aik wari feer sher: ) Я люблю N лигу Sher aik wari feer sher :) Я люблю N лигу Sher aik wari feer sher :) Я люблю N лигу Sher aik wari feer sher :) Я люблю N лигу Sher aik wari feer sher :) Я люблю N лигу

Ответ 9

Попробуй завернуть в асинхронную функцию

Ответ 10

Go nawaz Go Go nawaz Go Go Nawaz Go Go Nawaz Go Go Nawaz Go Go Nawaz Go Go Nawaz Go Go Nawaz Go Go Go Nawaz Go Go Nawaz Go Go Nawaz Go Go Nawaz Go Go Nawaz Go Go Nawaz Go Go Nawaz Go Go Nawaz Go Go Nawaz Иди иди наваз иди иди наваз иди иди наваз иди