Нудовий продавець з 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 (для наочності, розміщений добрим коментатором нижче). Просто дозвольте один раз отримати доступ і дозвольте автореєстратору авторизуватися автоматично, це буде.
laggingreflex

3
Спробувавши все, щоб надіслати пошту через gmail за допомогою nodemailer, для мене спрацювало наступне налаштування ..
faizanjehangir

Відповіді:


136

Я вирішив це, перейшовши до наступної URL-адреси (під час підключення до google з обліковим записом, з якого я хочу надсилати пошту):

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

Там я включив менш захищені програми.

Зроблено


1
Молодці! це працює, хоча я не думаю, що це найкраща ідея ... Я отримав своє перше повідомлення електронною поштою .. Thx
ackuser

з тим, що дозволяє це не працювати навіть у місцевому середовищі. він чітко зазначив, що він працює в локальному середовищі і не працює на віддаленому сервері. що таке рішення для таату?
Адітія Сай

це не допоможе вам, якщо у вашому обліковому записі gmail є авторизований 2FA
sasha

63

Дивіться офіційний посібник сайту для підключення Gmail:

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

-

Це працює для мене після цього:

  1. Увімкнути менш захищені програми - https://www.google.com/settings/security/lesssecureapps
  2. Тимчасово відключити Captcha, щоб ви могли підключити новий пристрій / сервер - https://accounts.google.com/b/0/displayunlockcaptcha

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

то для задоволення я просто спробував це з вимкненим (менш безпечним додатком) і Vola він працював знову!


1
Крок 1 і 2 були дуже корисними. спасибі! Я спробував step1, перш ніж я побачив ваше рішення і не працював, але з step2 - це магія!
MissStack

"smptTransport не є функцією"
JWiley

Я намагався з тим, як ви поділилися з нами, але я отримую однакову помилку знову і знову {Помилка: підключіть ETIMEDOUT 74.125.68.108:265 на TCPConnectWrap.afterConnect [як oncomplete] (net.js: 1097: 14) errno: ' ETIMEDOUT ', код:' ECONNECTION ', syscall:' connect ', адреса: '74 .125.68.108', порт: 465, команда: 'CONN'}
Anwar Hussain

@AnwarHussain: Я також знову отримую ту ж помилку
Pappa S

42

Для підключення до Gmail слід використовувати маркер XOAuth2 . Не хвилюйтесь, 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()
      }
    }
  };

Вам потрібно буде зайти до Cloud 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 повинен знати, куди слід перенаправляти користувача, щоб рукостискання було завершено.
Лоран Перрін


14

Працювали чудово:

1- встановити вузловий продавець , пакет якщо він не встановлений (введіть 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

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

  1. https://www.google.com/settings/security/lesssecureapps Увімкнено це, але це не було моїм рішенням
  2. https://g.co/allowaccess Я дозволив доступ ззовні на обмежений час, і це вирішило мою проблему.

2
Посилання g.co/allowaccess саме те, що мені виправило (вже ввімкнуло меншsecureapps) - дякую!

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 ---> хост: 'smtp.gmail.com', порт: 465, безпечний: правда, працював для мене
Praveen Vishnu

@PraveenVishnu Немає проблем, якщо ви проголосуєте за цю відповідь, більше людей побачать її. Це може допомогти і їм.
Хамід

привіт, я знаю це вже старе, але ви б заперечили, де ви взяли сервісClient, privateKey та accessToken? Дякую.
Aljohn Yamaro

@AljohnYamaro Поштова служба надасть це. У моєму випадку це був Gmail. Більше ви можете прочитати тут: stackoverflow.com/questions/36214968/…
Хамід


9

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

myaccount.google.com> Вхід та безпека> Вхід у Google> Паролі програм

Це дає вам альтернативний пароль для облікового запису, тоді ви просто налаштовуєте вузлового продавця як звичайну службу 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>'

Завжди використовуйте це1. Щоб встановити пароль програми, вам потрібно встановити 2-заводські auth. Навпроти на менш захищений.
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

Чомусь лише дозвіл на менш безпечну конфігурацію додатка не працював для мене навіть у справі captcha. Мені довелося зробити ще один крок, який дозволяє налаштувати 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)
  });
});
}

У свій код потрібно додати тип SafeConnection.


2

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

Відредаговано package.json, щоб відобразити зміни тоді

npm install

3
Краще зробити оновлення npm для цього випадку. Якщо ви хочете дізнатися більше про те, як оновлення npm та npm встановлюють різні - тоді, будь ласка, дивіться цю відповідь - stackoverflow.com/questions/12478679/…
Ентоні Акентьєв

2

Просто завітайте до таких: 1–4 аутентифікація Gmail для отримання дозволів електронної пошти низького рівня не приймається перед перезапуском клієнтського браузера; 2 - Якщо ви хочете відправляти електронну пошту за допомогою nodemailer, і ви не хочете використовувати протокол xouath2 там, ви повинні написати як безпечне з'єднання: 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 використовується двічі, який з них - що?
Біранчі

Дійсно, це дуже зрозуміло. Перший - це створення налаштувань smtpTransport і секунда для надсилання пошти, використовуючи ці налаштування, що вона ідеально працює в базі сьогодні
Хаміт

2

спочатку встановіть вузловий продавець

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.