通过 nodemailer 向多个收件人发送电子邮件
Sending email to multiple recipients via nodemailer
我正在尝试向多个收件人发送电子邮件。为此,我创建了一个收件人数组,但使用我的代码,我只能向该数组的最后一个电子邮件 ID 发送邮件 3 次。我的代码有什么问题?
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(); }
});
});
您正在异步发送电子邮件,因此您需要一个等待函数来等待所有邮件直到它们被发送,因为如果没有,您的程序将退出并且一些请求不会被满足。因此,您必须执行某种超时功能来检查电子邮件是否已发送。
您的问题是从异步代码中引用相同的 msg 对象。
foreach 在 sendMail 发送电子邮件之前完成。
因此 msg.to 将是邮件列表对象中的最后一项。
尝试 clone/copy 邮件列表 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) {
据我所知,您可以像这样获得多个收件人
"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
}
我已经试过了,效果不错。此外,从我的角度来看,如果您有能力发送,为什么还要担心 "asynchronously" 或发送电子邮件 1K 次
所有这些都只需一次,没有任何并发症?
无论如何希望这对你有所帮助,回答你的问题或者它可能对其他人有帮助
当然,我的答案可以改进..
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
}
nodemailer (v2.4.2) docs 说:
to
- Comma separated list or an array of recipients e-mail addresses that will appear on the To: field
所以你可以这样做:
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
}
异步执行此操作的一个好方法是使用异步模块中的每个函数: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
});
sendMail 方法实际上在 forEach 循环完成后得到解决,但问题是 sendMail 方法不是 return 一种承诺,因此如果您尝试等待它,它仍然无法工作。
所以您需要做的是为 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();
}
});
});
};
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)
});
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!",
});
- 您可以通过保留对象数组将电子邮件发送给多个收件人,其中名称是收件人姓名,地址是收件人电子邮件地址。
- 通过以上方式,我可以将电子邮件发送给多个收件人。
我正在尝试向多个收件人发送电子邮件。为此,我创建了一个收件人数组,但使用我的代码,我只能向该数组的最后一个电子邮件 ID 发送邮件 3 次。我的代码有什么问题?
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(); }
});
});
您正在异步发送电子邮件,因此您需要一个等待函数来等待所有邮件直到它们被发送,因为如果没有,您的程序将退出并且一些请求不会被满足。因此,您必须执行某种超时功能来检查电子邮件是否已发送。
您的问题是从异步代码中引用相同的 msg 对象。 foreach 在 sendMail 发送电子邮件之前完成。
因此 msg.to 将是邮件列表对象中的最后一项。
尝试 clone/copy 邮件列表 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) {
据我所知,您可以像这样获得多个收件人
"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
}
我已经试过了,效果不错。此外,从我的角度来看,如果您有能力发送,为什么还要担心 "asynchronously" 或发送电子邮件 1K 次 所有这些都只需一次,没有任何并发症?
无论如何希望这对你有所帮助,回答你的问题或者它可能对其他人有帮助
当然,我的答案可以改进..
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
}
nodemailer (v2.4.2) docs 说:
to
- Comma separated list or an array of recipients e-mail addresses that will appear on the To: field
所以你可以这样做:
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
}
异步执行此操作的一个好方法是使用异步模块中的每个函数: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
});
sendMail 方法实际上在 forEach 循环完成后得到解决,但问题是 sendMail 方法不是 return 一种承诺,因此如果您尝试等待它,它仍然无法工作。
所以您需要做的是为 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();
}
});
});
};
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)
});
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!",
});
- 您可以通过保留对象数组将电子邮件发送给多个收件人,其中名称是收件人姓名,地址是收件人电子邮件地址。
- 通过以上方式,我可以将电子邮件发送给多个收件人。