Javascript-форум (https://javascript.ru/forum/)
-   Node.JS (https://javascript.ru/forum/node-js-io-js/)
-   -   Функция отправки email'ов nodemailer (https://javascript.ru/forum/node-js-io-js/76178-funkciya-otpravki-email%27ov-nodemailer.html)

mcBiba 11.12.2018 18:26

Функция отправки email'ов nodemailer
 
Привет, необходимо сделать функцию отправки email'ов на node.js, если писать без функции то тестовое сообщение создается без ошибок, как переношу все в функцию, то выводит в консоли 'undefined'. Я так понял что надо асинхронно делать, приведу пример с попыткой реализации на асинхронности.

По возможности хотел получить только направление на решение, без готового кода, спасибо !

let express =require("express");
let app = express();
let server = app.listen(2800, ()=> console.log("Работа пошла"));
var nodemailer = require("nodemailer");
 
app.get('/',function(req,res){
  let userPassword = 1;
  let userEmail = 'ga@ya.ru';
  let result = 'Не вызывано';
  let main =  async (userEmail,userPassword) => {
    await nodemailer.createTestAccount(async (err, account) => {
      errortext = err;
      let transporter = nodemailer.createTransport({
        host: 'smtp.ethereal.email',
        port: 587,
        secure: false,
        auth: {
          user: account.user,
          pass: account.pass
        }
      });
      let mailOptions = {
        from: '"Heano" <games.1212@yandex.ru>',
        to: userEmail,
        subject: 'Регистрация вњ”',
        text: 'Твой пароль: '+userPassword,
        html: 'Твой пароль:<b> '+userPassword+'</b>'
      };
      await transporter.sendMail(mailOptions,(error, info) =>{
        if (error) {
          result = "Не отправлено";
        }
        else{
          result = "Отправлено";
        }
        return result;
      });
    });
  }
  main(userEmail,userPassword).then(result=>console.log(result));
});

j0hnik 11.12.2018 19:28

mcBiba,
вы хотите чтобы письмо отправлялось всякий раз когда кто-то заходит на главную?

mcBiba 11.12.2018 23:33

j0hnik,
Нет я вывел код в отдельный проект для отладки и что бы можно было поделиться проблемой. Так email отправляется при регистрации, восстановлении пароля и еще в нескольких местах (все это в другом проекте).

Audaxviator 12.12.2018 06:19

1. Убери функцию за пределы обработчика запроса (так можно делать, ага).
2. Объяви обычную человеческую функцию и просто вставь в неё код из примера
function main(userEmail, userPassword) {
  ...
}

3. Перестань приписывать к готовому примеру с сайта эти async и await - всё равно не понимаешь, зачем они и как работают, при том что весь код в Нодемейлере синхронный (за исключением колбека с ответом от smtp-сервера о результате отправки).
4. Вызови функцию в обработчике
main(userEmail, userPassword);

5. Всё.

UPD
Ну и метод createTestAccount - он не для реальной жызни, в реальной жызни он не нужен.

mcBiba 12.12.2018 16:23

Audaxviator,
Если у меня недавно профиль появился тут не значит, что я ничего не понимаю. Я это все сюда вывел и в такой вид из за неудачи. Он как обычная функция возвращает undefined.
let express =require("express");
let app = express();
let server = app.listen(2800, ()=> console.log("Работа пошла"));
var nodemailer = require("nodemailer");

app.get('/',function(req,res){
  console.log(sendEmail('f@ya.ru','1'));
});


function sendEmail(email,password){
  nodemailer.createTestAccount((err, account) => {
    errortext = err;
    let transporter = nodemailer.createTransport({
      host: 'smtp.ethereal.email',
      port: 587,
      secure: false,
      auth: {
        user: account.user,
        pass: account.pass
      }
    });
    let mailOptions = {
      from: '"Heano" <games.1212@yandex.ru>',
      to: email,
      subject: 'Регистрация ✔',
      text: 'Твой пароль: '+password,
      html: 'Твой пароль:<b> '+password+'</b>'
    };
    transporter.sendMail(mailOptions,(error, info) =>{
      if (error) {
        return false;
      }
      else{
        return true;
      }
    });
  });
}



Консоль

[nodemon] 1.18.6
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `node app.js`
Работа пошла
undefined

/Консоль

Зачем мне менять createTestAccount, если я функцию отправки не могу сделать?

SuperZen 12.12.2018 17:07

Надо sendMail завернуть в Promise и в transporter.sendMail(mailOptions,(error, info) => вызывать для true resolve, для false reject

В данном случае, он и должен возвращать undefined, потому что sendMail ничего и не возвращает %)

И в роуте надо при resolve вызывать уже res.send и тп...

SuperZen 12.12.2018 17:18

Примерно так, но надо проверять...
let express = require("express");
let app = express();
var nodemailer = require("nodemailer");

app.get('/', function (req, res) {
  sendEmail('f@ya.ru', '1').then(() => {
    console.log('sended')
    res.send('sended')
  }).catch((error) => {
    console.log(error)
    res.send('error')
    // res.send(error.message)
  })
  // console.log(sendEmail('f@ya.ru', '1'));
});

function sendEmail(email, password) {
  return new Promise((resolve, reject) => {
    nodemailer.createTestAccount((err, account) => {
      errortext = err;
      let transporter = nodemailer.createTransport({
        host: 'smtp.ethereal.email',
        port: 587,
        secure: false,
        auth: {
          user: account.user,
          pass: account.pass
        }
      });
      let mailOptions = {
        from: '"Heano" <games.1212@yandex.ru>',
        to: email,
        subject: 'Регистрация ✔',
        text: 'Твой пароль: ' + password,
        html: 'Твой пароль:<b> ' + password + '</b>'
      };
      transporter.sendMail(mailOptions, (error, info) => {
        if (error) {
          reject(error)
          // return false;
        }
        else {
          resolve()
          // return true;
        }
      });
    });
  })
}

let server = app.listen(2800, () => console.log("Работа пошла"));

Audaxviator 12.12.2018 17:23

Рас
function foo(email, password) {

	return new Promise(function(resolve, reject) {

		nodemailer.createTestAccount(function(err, account) {
			var transporter = nodemailer.createTransport({
				//service: 'Gmail',
				host: 'smtp.ethereal.email',
				port: 587,
				secure: true, // use SSL
				auth: {
					user: account.user,
					pass: account.pass
				}
			});

			var message = {
				from: '"Heano" <games.1212@yandex.ru>',
				to: email,
				subject: 'Регистрация ✔',
				text: 'Твой пароль: '+ password,
				html: 'Твой пароль:<b> '+ password+'</b>'
			};

			transporter.sendMail(message, function (err, info) {
					if (err) {
							resolve('Error:', err.message);
							return;
					}
					resolve('Server responded with ' + info.response);
			});
		});
	});
}

Два
foo('f@ya.ru', '1')
	.then(function(info) {
		console.log(info);
	})
	.catch(function(err) {
		console.log(err);
	});

SuperZen 12.12.2018 17:27

Audaxviator, в данном случае у тебя два раза resolve, так что catch не будет работать... надо для catch вызывать reject

Audaxviator 12.12.2018 17:28

Рас
function foo(email, password) {
	nodemailer.createTestAccount(function(err, account) {
		var transporter = nodemailer.createTransport({
			host: 'smtp.ethereal.email',
			port: 587,
			secure: true,
			auth: {
				user: account.user,
				pass: account.pass
			}
		});

		var message = {
			from: '"Heano" <games.1212@yandex.ru>',
			to: email,
			subject: 'Регистрация ✔',
			text: 'Твой пароль: '+ password,
			html: 'Твой пароль:<b> '+ password+'</b>'
		};

		transporter.sendMail(message, function (err, info) {
			if (err) {
				console.log('Error:' + err.message);
				return;
			}
			   console.log('Server responded with ' + info.response);
		});
	});
}

Два
foo('f@ya.ru', '1')


Часовой пояс GMT +3, время: 12:59.