Как включить эту функцию nodemailer в эту функцию контроллера? - PullRequest
0 голосов
/ 03 октября 2019

Я пытаюсь создать форму, которая сначала отправит данные в базу данных 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 functon

 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 и другие параметры в теле письма неверны.

Ответы [ 4 ]

1 голос
/ 03 октября 2019

Наиболее простой формой здесь было бы просто обернуть функцию обратным вызовом (нодмалером) в 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) здесь эффективно проходит через результат кследующая ссылка в цепочке обещаний, которая лучше, чем вложение цепочек обещаний в той же области, просто чтобы иметь доступ к одному и тому же значению. Тогда у вас также есть единственная точка для 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 в исполнении. Так что здесь письмо не отправляется, если данные не сохранены правильно. Это может или не может быть вашим предполагаемым случаем, но простое создание Обещания должно как минимум соответствовать правильному направлению.

0 голосов
/ 03 октября 2019

Экспортируйте ваш метод 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();
        });
});
};
0 голосов
/ 03 октября 2019

Я бы предложил создать модуль-обертку вокруг nodemailer, поэтому вы можете использовать функцию sendEmail несколько раз.

Создайте себе файл с именем email-client.js или как хотите. В этом модуле вы можете создать замыкание через smtpTransport и экспортировать только функцию sendEmail.

email-клиент

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 возвращает обещание, с которым мы будем иметь дело внутри вашего контроллера.

контроллер

Сначала вы можете импортировать функцию sendEmail, экспортированную из email-client.js, затем вы можете использовать ее в своем контроллере. Обратите внимание, что я изменил контроллер на async и предпочел 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."
        });
    }
};
0 голосов
/ 03 октября 2019

Создайте отдельный 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 для создания собственного сообщения, заголовка или имени любого

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...