我正在尝试创建一个表单,该表单首先将数据发送到Mongo数据库,然后再通过Nodemailer的电子邮件发送该数据。这是两个功能:
控制器功能
exports.createListing = (req, res) => {
// Validate request
if(!req.body.content) {
return res.status(400).send({
message: "Fields can not be empty"
});
}
const listing = new Listing({
title: req.body.title,
city: req.body.city,
street: req.body.street,
businessname: req.body.businessname,
description: req.body.description
});
listing.save()
.then(data => {
res.send(data);
}).catch(err => {
res.status(500).send({
message: err.message || "Some error occurred while creating the listing."
});
});
};
NodeMailer功能
var smtpTransport = nodemailer.createTransport({
service: 'Gmail',
port: 465,
auth: {
user: 'YOUR_GMAIL_SERVER',
pass: 'YOUR_GMAIL_PASSWORD'
}
});
var mailOptions = {
to: data.email,
subject: 'ENTER_YOUR_SUBJECT',
html: `<p>${data.title}</p>
<p>${data.city}</p>
<p>${data.street}</p>`,
...
};
smtpTransport.sendMail(mailOptions,
(error, response) => {
if (error) {
res.send(error)
} else {
res.send('Success')
}
smtpTransport.close();
});
如何在上面的“创建清单”功能中包括该Nodemailer部分,以及如何在电子邮件正文中包括该已提交的数据。我认为电子邮件正文中的当前data.title和其他选项是错误的方式。
答案 0 :(得分:1)
这里最简单的形式是将函数与回调(nodemailer一个)包装在Promise中:
exports.createListing = (req, res) => {
// Validate request
if(!req.body.content) {
return res.status(400).send({
message: "Fields can not be empty"
});
}
// Set options after the request was verified.
const smtpTransport = nodemailer.createTransport({
service: 'Gmail',
port: 465,
auth: {
user: 'YOUR_GMAIL_SERVER',
pass: 'YOUR_GMAIL_PASSWORD'
}
});
const listing = new Listing({
title: req.body.title,
city: req.body.city,
street: req.body.street,
businessname: req.body.businessname,
description: req.body.description
});
listing.save()
.then(data => new Promise((resolve, reject) => {
var mailOptions = {
to: data.email,
subject: 'ENTER_YOUR_SUBJECT',
html: `<p>${data.title}</p>
<p>${data.city}</p>
<p>${data.street}</p>`,
...
};
smtpTransport.sendMail(mailOptions,
(error, response) => {
if (error) {
reject(error);
} else {
resolve(data);
}
});
})
.then(data => {
smtpTransport.close(); // this awaited the actual send
res.send(data);
}
.catch(err => {
res.status(500).send({
message: err.message || "Some error occurred while creating the listing."
});
});
};
请注意,此处的resolve(data)
有效地将结果传递到Promise链中的下一个链接,这比在相同范围内嵌套Promise链只是为了访问相同的值要好。然后,当其中任何一种方法失败时,您还将获得catch()
的单点。
也就是说,已经引起注意的是,当前的API实际上在没有回调的情况下调用时会返回Promise
,但是您可能需要按顺序使用async
和await
语法使访问更干净:
exports.createListing = async (req, res) => { // <-- mark block as async
// Validate request
if(!req.body.content) {
return res.status(400).send({
message: "Fields can not be empty"
});
}
// Set options after the request was verified.
const smtpTransport = nodemailer.createTransport({
service: 'Gmail',
port: 465,
auth: {
user: 'YOUR_GMAIL_SERVER',
pass: 'YOUR_GMAIL_PASSWORD'
}
});
const listing = new Listing({
title: req.body.title,
city: req.body.city,
street: req.body.street,
businessname: req.body.businessname,
description: req.body.description
});
try { // try..catch for error handling
let data = await listing.save(); // await the save
var mailOptions = {
to: data.email,
subject: 'ENTER_YOUR_SUBJECT',
html: `<p>${data.title}</p>
<p>${data.city}</p>
<p>${data.street}</p>`,
...
};
await smtpTransport.sendMail(mailOptions); // await the sendMail
smtpTransport.close(); // this awaited the actual send
res.send(data);
} catch(err) {
res.status(500).send({
essage: err.message || "Some error occurred while creating the listing."
}
};
同样重要的是要注意,这种方法在执行中是 serial 。因此,除非正确保存数据,否则不会发送邮件。这可能是您的预期情况,也可能不是您的预期情况,但是仅创建包装Promise至少应遵循正确的方向。
答案 1 :(得分:0)
创建单独的mail.js或anyname.js
var config = require('../config/config.js');
var nodemailer = require('nodemailer');
var smtpTransport = nodemailer.createTransport({
service :"gmail",
host: "smtp.gmail.com",
auth :
{
user: config.email,
pass: config.password
}
});
// setup email data with unicode symbols
var mailOptions = {
from: config.email,
to: 'user to send',
subject :'message',
text :' "Hi",\n You have successfully created an account"',
html: '<b>Welcome?</b>' // html body
};
// sends mail
module.exports.sendMail = function()
{
// send mail with defined transport object
smtpTransport.sendMail(mailOptions, (error, info) => {
if (error)
{
return console.log(error);
}
console.log('Message sent: %s', info.messageId);});
}
现在将此文件导入控制器js文件
var mailer = require('./mail.js');
并像下面一样使用它
mailer.sendMail()
您可以在sendMail函数中传递值或参数,并在mail.js文件中访问它们以创建自定义消息或标题或任何名称
答案 2 :(得分:0)
我建议围绕nodemailer创建一个包装器模块,因此您可以多次重用sendEmail
函数。
为自己创建一个名为email-client.js
的文件或任何您想要的文件。在此模块中,您可以在smtpTransport
上创建一个闭包,而仅导出sendEmail
函数。
电子邮件客户端
const nodemailer = require("nodemailer");
const smtpTransport = nodemailer.createTransport({
service: "Gmail",
port: 465,
auth: {
user: "YOUR_GMAIL_SERVER",
pass: "YOUR_GMAIL_PASSWORD"
}
});
async function sendMail({ to, subject, html }) {
return smtpTransport.sendMail({ to, subject, html });
}
module.exports = {
sendMail
};
注意:smtpTransport.sendMail
返回一个Promise,我们将在您的控制器内部处理该Promise。
控制器
首先,您可以导入从sendEmail
导出的email-client.js
函数,然后可以在控制器中使用它。请注意,我已将控制器更改为async,并更喜欢猫鼬Model.create(使测试变得更容易了)。
const { sendEmail } = require("./email-client.js");
exports.createListing = async (req, res) => {
try {
if (!req.body.content) {
return res.status(400).send({
message: "Fields can not be empty"
});
}
const listing = await Listing.create({
title: req.body.title,
city: req.body.city,
street: req.body.street,
businessname: req.body.businessname,
description: req.body.description
});
await sendEmail({
to: "blabla",
subject: "blabla",
html: `<p>${listing.title}</p>
<p>${listing.city}</p>
<p>${listing.street}</p>`
});
return res.send("Success");
} catch (error) {
return res.status(500).send({
message:
error.message ||
"Some error occurred while creating the listing."
});
}
};
答案 3 :(得分:0)
导出sendMail方法并将其导入到控制器中。
控制器功能
let sendMail = require('your nodemailer file').sendMail;
exports.createListing = (req, res) => {
// Validate request
if(!req.body.content) {
return res.status(400).send({
message: "Fields can not be empty"
});
}
const listing = new Listing({
title: req.body.title,
city: req.body.city,
street: req.body.street,
businessname: req.body.businessname,
description: req.body.description
});
listing.save()
.then(data => {
sendMail({
title: req.body.title,
city: req.body.city,
street: req.body.street})
res.send(data);
}).catch(err => {
res.status(500).send({
message: err.message || "Some error occurred while creating the listing."
});
});
};
NodeMailer功能
var smtpTransport = nodemailer.createTransport({
service: 'Gmail',
port: 465,
auth: {
user: 'YOUR_GMAIL_SERVER',
pass: 'YOUR_GMAIL_PASSWORD'
}
});
module.exports.sendmail = (data)=>{
return new Promise((resolve,reject)=>{
var mailOptions = {
to: data.email,
subject: 'ENTER_YOUR_SUBJECT',
html: `<p>${data.title}</p>
<p>${data.city}</p>
<p>${data.street}</p>`,
...
};
smtpTransport.sendMail(mailOptions,
(error, response) => {
if (error) {
reject(error);
} else {
resolve('Success');
}
smtpTransport.close();
});
});
};