通过nodemailer向多个收件人发送电子邮件

时间:2015-02-15 15:16:50

标签: javascript node.js nodemailer

我正在尝试向多个收件人发送电子邮件。为此,我创建了一个收件人数组,但是使用我的代码,我只能将邮件发送到阵列的最后一次电子邮件ID三次。我的代码出了什么问题?

var nodemailer = require("nodemailer");

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

var maillist = [
  '****.sharma3@****.com',
  '****.bussa@****.com',
  '****.gawri@****.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(); }
  });
});

9 个答案:

答案 0 :(得分:28)

nodemailer(v2.4.2)docs说:

  

to - 逗号分隔列表或收件人电子邮件地址数组,将显示在收件人:字段

所以你可以这样做:

var maillist = [
  '****.sharma3@****.com',
  '****.bussa@****.com',
  '****.gawri@****.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
}

答案 1 :(得分:21)

据我所知,您将能够获得这样的多个收件人

"mail1@mail.com,mail2@mail.com,mail3@mail.com,mail4@mail.com"

那你为什么不做

这样的事情
var maillist = '****.sharma3@****.com, ****.bussa@****.com, ****.gawri@****.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
}

我已经尝试过并且正在运作。此外,从我的角度来看,为什么你不得不担心&#34;异步&#34;如果您有发送的能力,可以发送1K次电子邮件 所有这些都只有一次没有任何并发​​症?

无论如何希望得到这个帮助,回答你的问题或者它可能对其他人有帮助

当然,我的答案可以改善......

答案 2 :(得分:8)

您的问题是从异步代码引用相同的msg对象。 forema在sendMail发送电子邮件之前完成。

所以msg.to将成为maiilist对象的最后一项。

尝试在maillist foreach中克隆/复制msg,或者只是将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) {

答案 3 :(得分:4)

var maillist = [
  '****.sharma3@****.com',
  '****.bussa@****.com',
  '****.gawri@****.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
}

答案 4 :(得分:4)

异步执行此操作的一种好方法是使用异步模块中的每个函数: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
});

答案 5 :(得分:3)

let info = await transporter.sendMail({
  from: [{ name: "sender Name", address: "sender@example.com" }], // sender address
  to: [
    { name: "Receiver Name 1", address: "receiver1@example.com" },
    { name: "Receiver Name 2", address: "receiver2@example.com" },
  ],
  subject: "Hey you, awesome!",
  html: "<b>This is bold text</b>",
  text: "This is text version!",
});
  • 您可以将电子邮件保存在名称是收件人姓名和地址是收件人电子邮件地址的对象数组中。
  • 通过上述方式,我可以向多个收件人发送电子邮件。

答案 6 :(得分:1)

在forEach循环完成之后,sendMail方法实际上已得到解决,但是问题是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 :(得分:0)

您正在异步发送电子邮件,因此您需要一个等待所有邮件的等待函数,直到它们被发送为止,因为如果没有,您编程退出并且某些请求未得到满足。因此,您必须执行一种超时功能,以检查是否已发送电子邮件。

答案 8 :(得分:0)

maillist.forEach(function (to, i , array) {
  (function(i,to){
     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(); }
  });
})(i,to)
});