Nodemailer с Gmail и NodeJS


110

Я пытаюсь использовать nodemailer для реализации контактной формы с помощью NodeJS, но он работает только на локальном компьютере, он не работает на удаленном сервере ...

Мое сообщение об ошибке:

[website.fr-11 (out) 2013-11-09T15:40:26] { [AuthError: Invalid login - 534-5.7.14 <https://accounts.google.com/ContinueSignIn?sarp=1&scc=1&plt=AKgnsbvlX
[website.fr-11 (out) 2013-11-09T15:40:26] 534-5.7.14 V-dFQLgb7aRCYApxlOBuha5ESrQEbRXK0iVtOgBoYeARpm3cLZuUS_86kK7yPis7in3dGC
[website.fr-11 (out) 2013-11-09T15:40:26] 534-5.7.14 N1sqhr3D2IYxHAN3m7QLJGukwPSZVGyhz4nHUXv_ldo9QfqRydPhSvFp9lnev3YQryM5TX
[website.fr-11 (out) 2013-11-09T15:40:26] 534-5.7.14 XL1LZuJL7zCT5dywMVQyWqqg9_TCwbLonJnpezfBLvZwUyersknTP7L-VAAL6rhddMmp_r
[website.fr-11 (out) 2013-11-09T15:40:26] 534-5.7.14 A_5pRpA> Please log in via your web browser and then try again.
[website.fr-11 (out) 2013-11-09T15:40:26] 534-5.7.14 Learn more at https://support.google.com/mail/bin/answer.py?answer=787
[website.fr-11 (out) 2013-11-09T15:40:26] 534 5.7.14 54 fr4sm15630311wib.0 - gsmtp]
[website.fr-11 (out) 2013-11-09T15:40:26]   name: 'AuthError',
[website.fr-11 (out) 2013-11-09T15:40:26]   data: '534-5.7.14 <https://accounts.google.com/ContinueSignIn?sarp=1&scc=1&plt=AKgnsbvlX\r\n534-5.7.14 V-dFQLgb7aRCYApxlOBuha5ESrQEbRXK0iVtOgBoYeARpm3cLZuUS_86kK7yPis7in3dGC\r\n534-5.7.14 N1sqhr3D2IYxHAN3m7QLJGukwPSZVGyhz4nHUXv_ldo9QfqRydPhSvFp9lnev3YQryM5TX\r\n534-5.7.14 XL1LZuJL7zCT5dywMVQyWqqg9_TCwbLonJnpezfBLvZwUyersknTP7L-VAAL6rhddMmp_r\r\n534-5.7.14 A_5pRpA> Please log in via your web browser and then try again.\r\n534-5.7.14 Learn more at https://support.google.com/mail/bin/answer.py?answer=787\r\n534 5.7.14 54 fr4sm15630311wib.0 - gsmtp',
[website.fr-11 (out) 2013-11-09T15:40:26]   stage: 'auth' }

Мой контроллер:

exports.contact = function(req, res){
    var name = req.body.name;
    var from = req.body.from;
    var message = req.body.message;
    var to = '*******@gmail.com';
    var smtpTransport = nodemailer.createTransport("SMTP",{
        service: "Gmail",
        auth: {
            user: "******@gmail.com",
            pass: "*****"
        }
    });
    var mailOptions = {
        from: from,
        to: to, 
        subject: name+' | new message !',
        text: message
    }
    smtpTransport.sendMail(mailOptions, function(error, response){
        if(error){
            console.log(error);
        }else{
            res.redirect('/');
        }
    });
}

14
google.com/accounts/DisplayUnlockCaptcha (для наглядности опубликовано хорошим комментатором внизу). Просто разрешите доступ один раз и позвольте nodemailer автоматически войти в систему, и он будет.
laggingreflex

3
После того, как я попробовал все для отправки почты через Gmail с помощью nodemailer, у меня сработал следующий параметр ..
faizanjehangir

Ответы:


136

Я решил это, перейдя по следующему URL-адресу (при подключении к Google с учетной записью, с которой я хочу отправлять почту):

https://www.google.com/settings/security/lesssecureapps

Там я включил менее безопасные приложения.

Готово


1
Отлично сработано! он работает, хотя я не думаю , что это самая лучшая идея ... Я получил свой первый email..Thx
ackuser

без включения этого он не будет работать даже в локальной среде. он четко упомянул, что он работает в локальной среде и не работает на удаленном сервере. какое решение для этого?
Адитья Саи

это не поможет вам, если у вас есть двухфакторная аутентификация в вашей учетной записи
Gmail

64

См. Официальное руководство nodemailer по подключению Gmail:

https://community.nodemailer.com/using-gmail/

-

У меня это работает после этого:

  1. Включите менее безопасные приложения - https://www.google.com/settings/security/lesssecureapps
  2. Временно отключите Captcha, чтобы вы могли подключить новое устройство / сервер - https://accounts.google.com/b/0/displayunlockcaptcha

19
Номер 2 решил мои проблемы. Я не мог найти эту ссылку в настройках учетных записей Google. Спасибо!
programstinator

1
Тоже самое. Раньше я делал №1 и получал письма, работающие на localhost, перешел на продакшн, и ничего не работало. # 2 исправлена ​​моя проблема с производством. Спасибо
Джон

49

Простое решение:

var nodemailer = require('nodemailer');
var smtpTransport = require('nodemailer-smtp-transport');

var transporter = nodemailer.createTransport(smtpTransport({
  service: 'gmail',
  host: 'smtp.gmail.com',
  auth: {
    user: 'somerealemail@gmail.com',
    pass: 'realpasswordforaboveaccount'
  }
}));

var mailOptions = {
  from: 'somerealemail@gmail.com',
  to: 'friendsgmailacc@gmail.com',
  subject: 'Sending Email using Node.js[nodemailer]',
  text: 'That was easy!'
};

transporter.sendMail(mailOptions, function(error, info){
  if (error) {
    console.log(error);
  } else {
    console.log('Email sent: ' + info.response);
  }
});  

Шаг 1:

перейдите сюда https://myaccount.google.com/lesssecureapps и включите менее безопасные приложения. Если это не сработает, тогда

Шаг 2

перейдите сюда https://accounts.google.com/DisplayUnlockCaptcha и включите / продолжите, а затем попробуйте.

для меня только шаг 1 не сработал, поэтому мне пришлось перейти к шагу 2.

Я также попытался удалить пакет nodemailer-smtp-transport, и, к моему удивлению, он работает. но затем, когда я перезапустил свою систему, у меня возникла такая же ошибка, поэтому мне пришлось пойти и включить менее безопасное приложение (я отключил его после работы).

затем для удовольствия я просто попробовал выключить (менее безопасное приложение), и он снова заработал!


1
Шаги 1 и 2 были очень полезны. Спасибо! Я попробовал шаг 1, прежде чем увидел ваше решение, и не работал, но с шагом 2 это волшебство!
MissStack

«smptTransport не является функцией»
JWiley

Я пробовал использовать оба способа, которыми вы поделились с нами, но снова и снова получаю одну и ту же ошибку {Ошибка: подключите ETIMEDOUT 74.125.68.108:465 в TCPConnectWrap.afterConnect [as oncomplete] (net.js: 1097: 14) errno: ' ETIMEDOUT ', код:' ECONNECTION ', системный вызов:' connect ', адрес: '74 .125.68.108', порт: 465, команда: 'CONN'}
Анвар Хусейн

@AnwarHussain: Я снова получаю ту же ошибку
Pappa S

43

Вы должны использовать токен XOAuth2 для подключения к Gmail. Не беспокойтесь, Nodemailer уже знает об этом:

var smtpTransport = nodemailer.createTransport('SMTP', {
    service: 'Gmail',
    auth: {
      XOAuth2: {
        user: smtpConfig.user,
        clientId: smtpConfig.client_id,
        clientSecret: smtpConfig.client_secret,
        refreshToken: smtpConfig.refresh_token,
        accessToken: smtpConfig.access_token,
        timeout: smtpConfig.access_timeout - Date.now()
      }
    }
  };

Вам нужно будет перейти в Google Cloud Console, чтобы зарегистрировать приложение. Затем вам нужно получить токены доступа для учетных записей, которые вы хотите использовать. Вы можете использовать для этого паспортные данные .

Вот как это выглядит в моем коде:

var passport = require('passport'),
    GoogleStrategy = require('./google_oauth2'),
    config = require('../config');

passport.use('google-imap', new GoogleStrategy({
  clientID: config('google.api.client_id'),
  clientSecret: config('google.api.client_secret')
}, function (accessToken, refreshToken, profile, done) {
  console.log(accessToken, refreshToken, profile);
  done(null, {
    access_token: accessToken,
    refresh_token: refreshToken,
    profile: profile
  });
}));

exports.mount = function (app) {
  app.get('/add-imap/:address?', function (req, res, next) {
    passport.authorize('google-imap', {
        scope: [
          'https://mail.google.com/',
          'https://www.googleapis.com/auth/userinfo.email'
        ],
        callbackURL: config('web.vhost') + '/add-imap',
        accessType: 'offline',
        approvalPrompt: 'force',
        loginHint: req.params.address
      })(req, res, function () {
        res.send(req.user);
      });
  });
};

9
Есть ли более простое решение для отправки электронной почты в NodeJS с учетной записью GMail?
tonymx227


Можете ли вы объяснить, что делает Passport.authorize и почему вам нужна область видимости, callbackurl и т. д., почему вы не можете просто сделать это с помощью clientId и secret?
Исмаил

passport.authorizeаналогичен, за passport.authenticateисключением того, что не пытается обновить текущий сеанс. Вам нужно пройти, callbackURLпотому что после рукопожатия OAuth Google должен знать, куда перенаправить пользователя, чтобы рукопожатие было завершено.
Laurent Perrin


15

Работали нормально:

1- установить nodemailer , если пакет не установлен (введите cmd):npm install nodemailer

2- перейдите на https://myaccount.google.com/lesssecureapps и включите Разрешить менее безопасные приложения .

3- написать код:

var nodemailer = require('nodemailer');

var transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: {
        user: 'trueUsername@gmail.com',
        pass: 'truePassword'
    }
});

const mailOptions = {
    from: 'any@any.com', // sender address
    to: 'true@true.com', // list of receivers
    subject: 'test mail', // Subject line
    html: '<h1>this is a test mail.</h1>'// plain text body
};

transporter.sendMail(mailOptions, function (err, info) {
    if(err)
        console.log(err)
    else
        console.log(info);
})

4- наслаждайтесь!


11

Та же проблема случилась и со мной. Я протестировал свою систему на локальном хосте, затем развернул ее на сервере (который находится в другой стране), а затем, когда я попробовал систему на производственном сервере, я увидел эту ошибку. Я попробовал это исправить:

  1. https://www.google.com/settings/security/lesssecureapps Включил, но это не было моим решением
  2. https://g.co/allowaccess Я разрешил доступ извне в течение ограниченного времени, и это решило мою проблему.

2
G.co/allowaccess ссылка была то , что установил ее для меня (было уже включен lesssecureapps) - спасибо!

10

Для меня работает так, используя порт и безопасность (у меня были проблемы с отправкой писем из Gmail с использованием PHP без настроек безопасности)

Надеюсь кому то поможет.

var sendEmail = function(somedata){
  var smtpConfig = {
    host: 'smtp.gmail.com',
    port: 465,
    secure: true, // use SSL, 
                  // you can try with TLS, but port is then 587
    auth: {
      user: '***@gmail.com', // Your email id
      pass: '****' // Your password
    }
  };

  var transporter = nodemailer.createTransport(smtpConfig);
  // replace hardcoded options with data passed (somedata)
  var mailOptions = {
    from: 'xxxx@gmail.com', // sender address
    to: 'yyyy@gmail.com', // list of receivers
    subject: 'Test email', // Subject line
    text: 'this is some text', //, // plaintext body
    html: '<b>Hello world ✔</b>' // You can choose to send an HTML body instead
  }

  transporter.sendMail(mailOptions, function(error, info){
    if(error){
      return false;
    }else{
      console.log('Message sent: ' + info.response);
      return true;
    };
  });
}

exports.contact = function(req, res){
   // call sendEmail function and do something with it
   sendEmail(somedata);
}

здесь перечислены все конфигурации (включая примеры)


10

Ни одно из вышеперечисленных решений не помогло мне. Я использовал код, который есть в документации NodeMailer . Выглядит это так:

let transporter = nodemailer.createTransport({
    host: 'smtp.gmail.com',
    port: 465,
    secure: true,
    auth: {
        type: 'OAuth2',
        user: 'user@example.com',
        serviceClient: '113600000000000000000',
        privateKey: '-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBg...',
        accessToken: 'ya29.Xx_XX0xxxxx-xX0X0XxXXxXxXXXxX0x',
        expires: 1484314697598
    }
}); 

Спасибо дружище ! :) thissss ---> host: 'smtp.gmail.com', порт: 465, secure: true, работал на меня
Правин Вишну

@PraveenVishnu Нет проблем, если вы проголосуете за этот ответ, его увидят больше людей. Это могло бы помочь и им.
Хамид

привет, я знаю это уже старый, но не могли бы вы, где вы взяли serviceClient, privateKey и accessToken? Спасибо.
Альджон Ямаро,

@AljohnYamaro Почта предоставит его. В моем случае это был Gmail. Вы можете прочитать больше здесь: stackoverflow.com/questions/36214968/…
Хамид,


9

Я обнаружил, что самый простой метод, описанный в этой статье, упомянутой в ответе Грега Т , - это создать пароль приложения, который будет доступен после включения 2FA для учетной записи.

myaccount.google.com> Вход и безопасность> Вход в Google> Пароли приложений

Это дает вам альтернативный пароль для учетной записи, после чего вы просто настраиваете nodemailer как обычную службу SMTP.

var smtpTransport = nodemailer.createTransport({
    host: "smtp.gmail.com",
    port: 587,
    auth: {
        user: "username@gmail.com",
        pass: "app password"
    }
});

Хотя Google рекомендует Oauth2 как лучший вариант, этот метод прост и еще не упоминался в этом вопросе.

Дополнительный совет: я также обнаружил, что вы можете добавить свое имя приложения к адресу «от», и GMail не заменяет его только адресом электронной почты учетной записи, как это происходит, если вы пытаетесь использовать другой адрес. т.е.

from: 'My Pro App Name <username@gmail.com>'

Всегда использую this1. Вам нужно установить 2-заводскую аутентификацию, чтобы установить пароль приложения. Напротив, менее надежно.
gdfgdfg

8

Это решается с помощью nodemailer-smtp-transportмодуля внутри createTransport.

var smtpTransport = require('nodemailer-smtp-transport');

var transport = nodemailer.createTransport(smtpTransport({
    service: 'gmail',
    auth: {
        user: '*******@gmail.com',
        pass: '*****password'
    }
}));

4

Если вы используете Express, express-mailerобертывания nodemailerочень красиво и очень проста в использовании:

//# config/mailer.js    
module.exports = function(app) {
  if (!app.mailer) {
    var mailer = require('express-mailer');
    console.log('[MAIL] Mailer using user ' + app.config.mail.auth.user);
    return mailer.extend(app, {
      from: app.config.mail.auth.user,
      host: 'smtp.gmail.com',
      secureConnection: true,
      port: 465,
      transportMethod: 'SMTP',
      auth: {
        user: app.config.mail.auth.user,
        pass: app.config.mail.auth.pass
      }
    });
  }
};

//# some.js
require('./config/mailer.js)(app);
app.mailer.send("path/to/express/views/some_view", {
  to: ctx.email,
  subject: ctx.subject,
  context: ctx
}, function(err) {
  if (err) {
    console.error("[MAIL] Email failed", err);
    return;
  }
  console.log("[MAIL] Email sent");
});

//#some_view.ejs
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title><%= subject %></title>
  </head>
  <body>
  ... 
  </body>
</html>

4

весь ваш код в порядке, осталось только перейти по ссылке https://myaccount.google.com/security

и продолжайте прокручивать вниз, и вы найдете Разрешить менее безопасные приложения: ВКЛЮЧИТЬ и удерживайте ВКЛ, вы не найдете ошибок.



4

По какой-то причине просто разрешить менее безопасную конфигурацию приложения у меня не сработало, даже с капчей. Мне пришлось сделать еще один шаг, который включает конфигурацию IMAP:

Со страницы справки Google: https://support.google.com/mail/answer/7126229?p=WebLoginRequired&visit_id=1-636691283281086184-1917832285&rd=3#cantsignin

  • В правом верхнем углу нажмите "Настройки".
  • Щелкните Настройки.
  • Откройте вкладку Пересылка и POP / IMAP.
  • В разделе «Доступ по протоколу IMAP» выберите Включить IMAP.
  • Щелкните Сохранить изменения.

3
exports.mailSend = (res, fileName, object1, object2, to, subject,   callback)=> {
var smtpTransport = nodemailer.createTransport('SMTP',{ //smtpTransport
host: 'hostname,
port: 1234,
secureConnection: false,
//   tls: {
//     ciphers:'SSLv3'
// },
auth: {
  user: 'username',
  pass: 'password'
}

});
res.render(fileName, {
info1: object1,
info2: object2
}, function (err, HTML) {

smtpTransport.sendMail({
  from: "mail@from.com",
  to: to,
  subject: subject,
  html: HTML
}
  , function (err, responseStatus) {
      if(responseStatus)
    console.log("checking dta", responseStatus.message);
    callback(err, responseStatus)
  });
});
}

Вы должны добавить в свой код тип secureConnection.


2

Я использовал старую версию nodemailer 0.4.1 и столкнулся с этой проблемой. Я обновился до 0.5.15, и теперь все работает нормально.

Отредактировал package.json, чтобы отразить изменения, затем

npm install

3
В этом случае лучше сделать обновление npm . Если вы хотите узнать больше о том , как обновление НПМ и НПМ установить разные - тогда смотрите этот ответ - stackoverflow.com/questions/12478679/...
Энтони Akentiev

2

Просто обратите внимание на них: 1 - Аутентификация Gmail для разрешения низкоуровневых электронных писем не принимает перед перезапуском клиентского браузера 2 - Если вы хотите отправлять электронную почту с помощью nodemailer, и вы не хотите использовать протокол xouath2, вы должны написать как secureconnection: false, как показано ниже

const routes = require('express').Router();
var nodemailer = require('nodemailer');
var smtpTransport = require('nodemailer-smtp-transport');



routes.get('/test', (req, res) => {
  res.status(200).json({ message: 'test!' });
});

routes.post('/Email', (req, res) =>{

    var smtpTransport = nodemailer.createTransport({
        host: "smtp.gmail.com",
        secureConnection: false,
        port: 587,
        requiresAuth: true,
        domains: ["gmail.com", "googlemail.com"],
        auth: {
            user: "your gmail account", 
            pass: "your password*"
        }
});  

  var mailOptions = {
      from: 'from@gmail.com',
      to:'to@gmail.com',
      subject: req.body.subject,
      //text: req.body.content,
      html: '<p>'+req.body.content+' </p>'
  };

  smtpTransport.sendMail(mailOptions, (error, info) => {
    if (error) {
        return console.log('Error while sending mail: ' + error);
    } else {
        console.log('Message sent: %s', info.messageId);
    }
    smtpTransport.close();
});  

})

module.exports = routes;

smtpTransport используется дважды, какой из них какой?
Biranchi

Действительно, это очень ясно. Первый предназначен для создания настроек smtpTransport, а второй - для отправки почты с использованием этих настроек, он отлично работает в настоящее время в
firebase

2

сначала установите nodemailer

npm install nodemailer  --save

импортировать в файл js

const nodemailer = require("nodemailer");

const smtpTransport = nodemailer.createTransport({
    service: "Gmail",
    auth: {
        user: "example@gmail.com",
        pass: "password"
    },
    tls: {
        rejectUnauthorized: false
    }
});






 const mailOptions = {
        from: "example@gmail.com",
        to: sending@gmail.com,
        subject: "Welcome to ",
        text: 'hai send from me'.
    };


    smtpTransport.sendMail(mailOptions, function (error, response) {
        if (error) {
            console.log(error);
        }
        else {
            console.log("mail sent");
        }
    });

работаю в моем приложении

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.