Отправка JSON для отправки электронной почты с помощью Nodemailer либо отправляет почту, но зависает, либо выдает ошибку - PullRequest
0 голосов
/ 05 октября 2019

Я работаю над приложением MERN с базовой формой контакта, которая использует Nodemailer для отправки электронного письма. Я хочу получить какой-то ответ от сервера, который может отображаться во внешнем интерфейсе, например «Почта отправлена» или «Почта не отправлена» и т. Д.

Это была моя первая попытка (код с сервера. js), на примере здесь :

myRoutes.route('/send-mail').post(async function(req, res) {
  let testAccount = await nodemailer.createTestAccount();

  // create reusable transporter object using the default SMTP transport
  let transporter = nodemailer.createTransport({
      host: 'smtp.ethereal.email',
      port: 587,
      secure: false, // true for 465, false for other ports
      auth: {
          user: testAccount.user, // generated ethereal user
          pass: testAccount.pass // generated ethereal password
      }
  });

  let senderName = req.body.senderName;
  let senderEmail = req.body.senderEmail;
  let subject = req.body.subject;
  let message = req.body.message;
  let toEmail = req.body.toEmail;

  // send mail with defined transport object
  let info = await transporter.sendMail({
      from: `"${senderName}" <${senderEmail}>`, // sender address
      to: toEmail, // receiver address
      subject: subject, // Subject line
      text: message, // plain text body
      html: message
  });

  console.log('Message sent: %s', info.messageId);
  // Message sent: <b658f8ca-6296-ccf4-8306-87d57a0b4321@example.com>

  // Preview only available when sending through an Ethereal account
  console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info));
  // Preview URL: https://ethereal.email/message/WaQKMgKddxQDoou...
});

Это работает (почта отправляется, а URL предварительного просмотра записывается на консоль), но отправляет запрос на серверпросто зависает, пока время не истечет. Итак, поскольку мне все равно нужно было сделать это, чтобы получить ответы от сервера, который уведомит пользователя на внешнем интерфейсе, я решил добавить обратный вызов после функции sendMail.

Код собратный вызов:

myRoutes.route('/send-mail').post(async function(req, res) {
  let testAccount = await nodemailer.createTestAccount();

  // create reusable transporter object using the default SMTP transport
  let transporter = nodemailer.createTransport({
      host: 'smtp.ethereal.email',
      port: 587,
      secure: false, // true for 465, false for other ports
      auth: {
          user: testAccount.user, // generated ethereal user
          pass: testAccount.pass // generated ethereal password
      }
  });

  let senderName = req.body.senderName;
  let senderEmail = req.body.senderEmail;
  let subject = req.body.subject;
  let message = req.body.message;
  let toEmail = req.body.toEmail;

  // send mail with defined transport object
  let info = await transporter.sendMail({
      from: `"${senderName}" <${senderEmail}>`, // sender address
      to: toEmail, // receiver address
      subject: subject, // Subject line
      text: message, // plain text body
      html: message
  },function(){
    res.json('Mail sent!');
  }).catch(err => {
    res.json("Couldn't send the mail for some reason");
  });

  console.log('Message sent: %s', info.messageId);
  // Message sent: <b658f8ca-6296-ccf4-8306-87d57a0b4321@example.com>

  // Preview only available when sending through an Ethereal account
  console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info));
  // Preview URL: https://ethereal.email/message/WaQKMgKddxQDoou...
});

Получает сообщение «Письмо отправлено!»ответ от сервера, но сервер выдает эту ошибку: UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'catch' of undefined, и он не регистрирует идентификатор сообщения или URL предварительного просмотра, поэтому я не уверен, действительно ли он отправил письмо или нет.

Iпопытался передать err в качестве параметра функции до перехвата, но это не помогло.

Я также попытался полностью удалить перехват (см. ниже):

myRoutes.route('/send-mail').post(async function(req, res) {
  let testAccount = await nodemailer.createTestAccount();

  // create reusable transporter object using the default SMTP transport
  let transporter = nodemailer.createTransport({
      host: 'smtp.ethereal.email',
      port: 587,
      secure: false, // true for 465, false for other ports
      auth: {
          user: testAccount.user, // generated ethereal user
          pass: testAccount.pass // generated ethereal password
      }
  });

  let senderName = req.body.senderName;
  let senderEmail = req.body.senderEmail;
  let subject = req.body.subject;
  let message = req.body.message;
  let toEmail = req.body.toEmail;

  // send mail with defined transport object
  let info = await transporter.sendMail({
      from: `"${senderName}" <${senderEmail}>`, // sender address
      to: toEmail, // receiver address
      subject: subject, // Subject line
      text: message, // plain text body
      html: message
  },function(){
    res.json('Mail sent!');
  });

  console.log('Message sent: %s', info.messageId);
  // Message sent: <b658f8ca-6296-ccf4-8306-87d57a0b4321@example.com>

  // Preview only available when sending through an Ethereal account
  console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info));
  // Preview URL: https://ethereal.email/message/WaQKMgKddxQDoou...
});

Это получает «Письмо отправлено!»Ответ снова, но сервер теперь выдает эту ошибку: UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'messageId' of undefined

Есть идеи, как я могу заставить это работать? Мне просто нужна простая контактная форма, которая при отправке отправляет ответы с сервера со статусом, сообщающим нам, отправлено письмо или нет.

1 Ответ

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

Вы забыли добавить возврат, попробуйте так:

let info = await transporter.sendMail({
      from: `"${senderName}" <${senderEmail}>`, // sender address
      to: toEmail, // receiver address
      subject: subject, // Subject line
      text: message, // plain text body
      html: message
  }).then((data)=>{return data}).catch((error)=> {return error});

if(info.messageId){
   console.log('Message sent: %s', info.messageId);
   res.json({message:'Mail sent!'});
}else{
   console.log('Message Not sent');
   res.json({message:'Mail not sent!'});
}
...