如何在这个控制器函数中包含这个 nodemailer 函数?
How to include this nodemailer function inside this controller function?
我正在尝试创建一个表单,该表单首先将数据发送到 Mongo 数据库,然后通过 Nodemailer 通过电子邮件发送该数据。这是 2 个函数:
控制器功能
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 和电子邮件正文中的其他选项是错误的方式。
创建单独的 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 文件中访问它们以创建自定义消息或标题或名称
我建议围绕 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
returns 一个 Promise,我们将在您的控制器中处理。
控制器
首先,您可以导入从 email-client.js
导出的 sendEmail
函数,然后您可以在您的控制器中使用它。请注意,我已将控制器更改为 async & prefer mongoose 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."
});
}
};
此处最简单的形式是将函数与回调(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 链中的下一个 link,这比在同一范围内嵌套 promise 链只是为了访问要好相同的值。然后,当任一方法失败时,您也有 catch()
的单点。
也就是说,已经引起注意,当前 API 在没有回调的情况下调用时实际上会 return 一个 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."
}
};
还需要注意的是,这种方法是串行执行的。因此,除非正确保存数据,否则此处不会发送邮件。这可能是也可能不是您想要的情况,但简单地创建包装 Promise 至少应该遵循正确的方向。
导出您的 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();
});
});
};
我正在尝试创建一个表单,该表单首先将数据发送到 Mongo 数据库,然后通过 Nodemailer 通过电子邮件发送该数据。这是 2 个函数:
控制器功能
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 和电子邮件正文中的其他选项是错误的方式。
创建单独的 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 文件中访问它们以创建自定义消息或标题或名称
我建议围绕 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
returns 一个 Promise,我们将在您的控制器中处理。
控制器
首先,您可以导入从 email-client.js
导出的 sendEmail
函数,然后您可以在您的控制器中使用它。请注意,我已将控制器更改为 async & prefer mongoose 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."
});
}
};
此处最简单的形式是将函数与回调(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 链中的下一个 link,这比在同一范围内嵌套 promise 链只是为了访问要好相同的值。然后,当任一方法失败时,您也有 catch()
的单点。
也就是说,已经引起注意,当前 API 在没有回调的情况下调用时实际上会 return 一个 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."
}
};
还需要注意的是,这种方法是串行执行的。因此,除非正确保存数据,否则此处不会发送邮件。这可能是也可能不是您想要的情况,但简单地创建包装 Promise 至少应该遵循正确的方向。
导出您的 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();
});
});
};