使用Gmail和NodeJS的Nodemailer


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 2014年

3
乱投医通过使用nodemailer Gmail发送邮件后,以下设置为我工作..
faizanjehangir

Answers:


136

我通过转到以下网址(使用我要从中发送邮件的帐户连接到Google)解决了此问题:

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

我在那里启用了不太安全的应用程序。

完成了


1
做得好!这是工作,但我不认为这是一个不错的主意......我得到了我的第一个email..Thx
ackuser

如果不启用此功能,它甚至无法在本地环境中工作。他明确提到它在本地环境中运行,而不在远程服务器上运行。thaat的解决方案是什么?
Adithya Sai

如果您的gmail帐户中具有2FA身份验证,这将
无济于事

63

请参阅nodemailer的连接Gmail的官方指南:

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

--

这样做后对我有用:

  1. 启用安全性较低的应用程序-https: //www.google.com/settings/security/lesssecureapps
  2. 暂时停用验证码,以便您可以连接新设备/服务器-https://accounts.google.com/b/0/displayunlockcaptcha

18
2号解决了我的麻烦。我在Google帐户设置的任何地方都找不到该链接。谢谢!
programstinator

1
同样在这里。我以前做过#1,让电子邮件在localhost上正常工作,然后转移到生产环境中,但无济于事。#2解决了我的生产问题。谢谢
John

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很有帮助。谢谢!我在看不到您的解决方案之前尝试了step1,但没有成功,但是使用step2真是不可思议!
MissStack'9

“ smptTransport不是函数”
JWiley

我尝试了两种与您共享的方式,但是我一次又一次收到相同的错误{错误:在TCPConnectWrap.afterConnect上连接ETIMEDOUT 74.125.68.108:465 [作为未完成](net.js:1097:14)errno:' ETIMEDOUT”,代码:“ ECONNECTION”,系统调用:“ connect”,地址:“ 74.125.68.108”,端口:465,命令:“ CONN”}
Anwar Hussain,

@AnwarHussain:我也再次遇到相同的错误
Pappa S

42

您应该使用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来注册您的应用。然后,您需要检索要使用的帐户的访问令牌。您可以使用passportjs

这是我的代码中的样子:

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
有没有更简单的解决方案,可以使用GMail帐户在NodeJS中发送电子邮件?
tonymx227


你能解释passport.authorize做什么,为什么需要作用域,callbackurl等,为什么不能只用clientId和secret做呢?
Ismail

passport.authorizepassport.authenticate它类似,除了它不尝试更新当前会话。您需要通过,callbackURL因为OAuth握手之后,Google需要知道将用户重定向到何处,以便握手完成。
洛朗·佩林


14

工作正常:

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

对我来说,这种方式使用的是端口和安全性(我在使用没有安全设置的PHP使用Gmail发送电子邮件时遇到了问题)

希望对您有所帮助。

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
    }
}); 

谢谢哥们 !:)这是ssss->主机:'smtp.gmail.com',端口:465,安全:正确,为我工作
Praveen Vishnu,

@PraveenVishnu没问题,如果您对这个答案投赞成票,将会有更多的人看到它。这也可能对他们有帮助。
哈米德

嗨,我知道这已经很老了,但是您介意从哪里获得serviceClient,privateKey和accessToken?谢谢。
Aljohn Yamaro

@AljohnYamaro邮件服务将提供它。就我而言,它是Gmail。:你可以在这里阅读更多stackoverflow.com/questions/36214968/...
哈米德


9

我发现Greg T的答案本文中提到的最简单的方法是创建一个应用密码,该密码在为帐户启用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-transportcreateTransport中的模块可以解决该问题。

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

出于某种原因,仅允许不太安全的应用程序配置对我来说是无效的,即使是验证码也是如此。我必须做的另一步是启用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更新。如果您想了解更多关于如何NPM更新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");
        }
    });

在我的应用程序中工作

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.