J'essaie d'envoyer un courrier électronique à plusieurs destinataires. Pour cela, j'ai créé un tableau de destinataires, mais avec mon code, je ne peux envoyer qu'un courrier électronique au dernier ID de courrier électronique du tableau trois fois. Qu'est ce qui ne va pas avec mon code?
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(); }
});
});
Votre problème est de référencer le même objet msg à partir du code async ..... Le foreach est terminé avant que sendMail n'envoie les emails.
Ainsi, msg.to sera le dernier élément de l'objet maiiliste.
Essayez de cloner/copier des msg dans maillist foreach, ou déplacez simplement la définition du msg à cet endroit:
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) {
nodemailer (v2.4.2) docs say:
to
- Liste séparée par des virgules ou un tableau d'adresses de messagerie de destinataires qui figureront dans le champ À:
alors vous pouvez juste faire:
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
}
Autant que je sache, vous pourrez avoir plusieurs destinataires comme celui-ci.
"[email protected],[email protected],[email protected],[email protected]"
Alors pourquoi tu ne fais pas quelque chose comme
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
}
J'ai déjà essayé et ça marche. En outre, de mon point de vue, pourquoi vous devez vous soucier de manière "asynchrone" ou envoyer des courriels 1K fois si vous avez la possibilité d’envoyer Tous en une seule fois sans complication?
Quoi qu'il en soit, espérons que cette aide, répondez à votre question ou il peut aider quelqu'un d'autre
Ma réponse peut sûrement être améliorée.
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
}
Un bon moyen de le faire de manière asynchrone serait d'utiliser la fonction each dans le module async: 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
});
Vous envoyez les e-mails de manière asynchrone, vous avez donc besoin d'une fonction d'attente qui attend tous les e-mails jusqu'à ce qu'ils aient été envoyés. Sinon, vous programmez des exits et certaines demandes ne sont pas satisfaites. Donc, vous devez faire une sorte de fonction de délai qui vérifie si les emails ont été envoyés.
La méthode sendMail est effectivement résolue une fois la boucle forEach terminée, mais le problème est que la méthode sendMail ne renvoie pas un type de promesse. Par conséquent, si vous essayez d'attendre cela, cela ne fonctionnera toujours pas.
vous devez donc créer une fonction distincte pour sendmail, ce qui en fait une promesse comme celle-ci.
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();
}
});
});
};
ceci permet donc d'attendre cela et donc l'itérateur attendra que le processus se termine avant de passer à la boucle suivante.
Le code complet devrait ressembler à ceci
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();
}
});
});
};