简体   繁体   English

使用 nodemailer 通过 Node.js 发送 email 无效

[英]Sending email via Node.js using nodemailer is not working

I've set up a basic NodeJS server (using the nodemailer module) locally ( http://localhost:8080 ) just so that I can test whether the server can actually send out emails.我已经在本地 ( http://localhost:8080 ) 设置了一个基本的 NodeJS 服务器(使用 nodemailer 模块),这样我就可以测试服务器是否真的可以发送电子邮件。

If I understand the SMTP option correctly (please correct me if I'm wrong), I can either try to send out an email from my server to someone's email account directly , or I can send the email, still using Node.js, but via an actual email account (in this case my personal Gmail account), ie using SMTP. This option requires me to login into that acount remotely via NodeJS.如果我正确理解 SMTP 选项(如果我错了请纠正我),我可以尝试从我的服务器直接向某人的 email 帐户发送 email,或者我可以发送 email,仍然使用 Node.js,但是通过实际 email 帐户(在本例中是我的个人 Gmail 帐户),即使用 SMTP。此选项要求我通过 NodeJS 远程登录该帐户。

So in the server below I'm actually trying to use NodeJs to send an email from my personal email account to my personal email account.所以在下面的服务器中,我实际上是在尝试使用 NodeJs 将 email 从我的个人 email 帐户发送到我的个人 email 帐户。

Here's my simple server:这是我的简单服务器:

var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport("SMTP", {
    service: 'Gmail',
    auth: {
        user: '*my personal Gmail address*',
        pass: '*my personal Gmail password*'
    }
});

var http = require('http');
var httpServer = http.createServer(function (request, response)
{
    transporter.sendMail({
       from: '*my personal Gmail address*',
       to: '*my personal Gmail address*',
       subject: 'hello world!',
       text: 'hello world!'
    });
}).listen(8080);

However, it's not working.但是,它不起作用。 I got an email by Google saying:我通过谷歌得到了一个 email 说:

Google Account: sign-in attempt blocked If this was you You can switch to an app made by Google such as Gmail to access your account (recommended) or change your settings at https://www.google.com/settings/security/lesssecureapps so that your account is no longer protected by modern security standards. Google 帐户:登录尝试被阻止如果这是您您可以切换到 Google 制作的应用程序,例如 Gmail 以访问您的帐户(推荐)或在https://www.google.com/settings/security/更改您的设置lesssecureapps使您的帐户不再受到现代安全标准的保护。

I couldn't find a solution for the above problem on the nodemailer GitHub page.我在 nodemailer GitHub 页面上找不到上述问题的解决方案。 Does anyone have a solution/suggestion?有人有解决方案/建议吗?

Thanks: :-)谢谢: :-)

The answer is in the message from google.答案在来自谷歌的消息中。

For the second part of the problem, and in response to对于问题的第二部分,以及响应

I'm actually simply following the steps from the nodemailer github page so there are no errors in my code我实际上只是按照 nodemailer github 页面中的步骤操作,因此我的代码中没有错误

I will refer you to the nodemailer github page, and this piece of code :我将向您推荐 nodemailer github 页面,以及这段代码:

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

It differs slightly from your code, in the fact that you have : nodemailer.createTransport("SMTP" . Remove the SMTP parameter and it works (just tested). Also, why encapsulating it in a http server? the following works :它与您的代码略有不同,因为您有: nodemailer.createTransport("SMTP" 。删除 SMTP 参数并且它可以工作(刚刚测试)。另外,为什么将它封装在 http 服务器中?以下工作:

var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport({
    service: 'Gmail',
    auth: {
        user: 'xxx',
        pass: 'xxx'
    }
});

console.log('created');
transporter.sendMail({
from: 'xxx@gmail.com',
  to: 'xxx@gmail.com',
  subject: 'hello world!',
  text: 'hello world!'
});

Outdated: refreshToken and accessToken no longer exist in JSON file output过时:JSON 文件输出中不再存在 refreshToken 和 accessToken

For those who actually want to use OAuth2 / don't want to make the app "less secure", you can achieve this by对于那些真正想要使用 OAuth2 / 不想让应用程序“不那么安全”的人,您可以通过

  1. Search "Gmail API" from the google API console and click "Enable"谷歌 API 控制台搜索“Gmail API”并点击“启用”
  2. Follow the steps at https://developers.google.com/gmail/api/quickstart/nodejs .按照https://developers.google.com/gmail/api/quickstart/nodejs 中的步骤操作。 In the quickstart.js file, changing the SCOPES var from ['https://www.googleapis.com/auth/gmail.readonly'] to ['https://mail.google.com/'] in the quickstart js file provided as suggested in troubleshooting at https://nodemailer.com/smtp/oauth2/在 quickstart.js 文件中,将快速入门 js 中的SCOPES var 从['https://www.googleapis.com/auth/gmail.readonly']更改为['https://mail.google.com/']按照https://nodemailer.com/smtp/oauth2/ 上的故障排除中的建议提供的文件
  3. After following the steps in (2), the generated JSON file will contain the acessToken , refreshToken , and expires attributes needed in the OAuth2 Examples for Nodemailer按照(2)中的步骤操作后,生成的 JSON 文件将包含acessTokenOAuth2 示例中所需的acessTokenrefreshTokenexpires属性

This way you can use OAuth2 authentication like the following这样您就可以使用 OAuth2 身份验证,如下所示

let transporter = nodemailer.createTransport({
    service: 'Gmail',
    auth: {
        type: 'OAuth2',
        user: 'user@example.com',
        clientId: '000000000000-xxx0.apps.googleusercontent.com',
        clientSecret: 'XxxxxXXxX0xxxxxxxx0XXxX0',
        refreshToken: '1/XXxXxsss-xxxXXXXXxXxx0XXXxxXXx0x00xxx',
        accessToken: 'ya29.Xx_XX0xxxxx-xX0X0XxXXxXxXXXxX0x',
        expires: 1484314697598
    }
});

instead of storing your gmail password in plaintext and downgrading the security on your account.而不是以明文形式存储您的 Gmail 密码并降低您帐户的安全性。

i just set my domain to: smtp.gmail.com and it works.我只是将我的域设置为:smtp.gmail.com 并且它有效。 I am using a VPS Vultr.我正在使用 VPS Vultr。

the code:编码:

const nodemailer = require('nodemailer');
const ejs = require('ejs');
const fs = require('fs');

let transporter = nodemailer.createTransport({
    host: 'smtp.gmail.com',
    port: 465,
    secure: true,
    auth: {
        user: 'xxx@gmail.com',
        pass: 'xxx'
    }
});

let mailOptions = {
    from: '"xxx" <xxx@gmail.com>',
    to: 'yyy@gmail.com',
    subject: 'Teste Templete ✔',
    html: ejs.render( fs.readFileSync('e-mail.ejs', 'utf-8') , {mensagem: 'olá, funciona'})
};

transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
        return console.log(error);
    }
    console.log('Message %s sent: %s', info.messageId, info.response);
});

my ejs template (e-mail.ejs):我的 ejs 模板(e-mail.ejs):

<html>
    <body>
        <span>Esse é um templete teste</span>
        <p> gerando com o EJS - <%=mensagem%> </p>
    </body>
</html>

Make sure:确保:

  • install ejs: npm install ejs --save安装 ejs: npm install ejs --save
  • install nodemailer: npm install nodemailer --save安装 nodemailer: npm install nodemailer --save
  • ping to smtp.gmail.com works: ping smtp.gmail.com ping smtp.gmail.com 有效: ping smtp.gmail.com
  • change xxx@gmail.com to your gmail email将 xxx@gmail.com 更改为您的 Gmail 电子邮件
  • change yyy@gmail.com to the email that you want to send a email将 yyy@gmail.com 更改为您要发送电子邮件的电子邮件
  • Enable less secure apps启用安全性较低的应用
  • Disable Captcha temporarily暂时禁用验证码

have a nice day ;)祝你今天过得愉快 ;)

While the above answers do work, I'd like to point out that you can decrease security from Gmail by the following TWO steps.虽然上述答案确实有效,但我想指出您可以通过以下两个步骤来降低 Gmail 的安全性。

STEP #1第1步

Google Account: sign-in attempt blocked If this was you You can switch to an app made by Google such as Gmail to access your account (recommended) or change your settings at https://www.google.com/settings/security/lesssecureapps so that your account is no longer protected by modern security standards. Google 帐户:登录尝试被阻止 如果是您您可以切换到 Google 制作的应用程序(例如 Gmail)来访问您的帐户(推荐)或在https://www.google.com/settings/security/更改您的设置lesssecureapps使您的帐户不再受现代安全标准的保护。

STEP #2第2步

In addition to enabling Allow less secure apps, you might also need to navigate to https://accounts.google.com/DisplayUnlockCaptcha and click continue.除了启用允许不太安全的应用程序外,您可能还需要导航到https://accounts.google.com/DisplayUnlockCaptcha并单击继续。

You only need App password for google auth, then replace your google password in your code.您只需要 google auth 的 App 密码,然后在您的代码中替换您的 google 密码。 go here https://myaccount.google.com/apppasswords去这里https://myaccount.google.com/apppasswords

sample code:示例代码:

const nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport({
    service: "Gmail",
    auth: {
      user: 'example@gmail.com',
      pass: 'app password here'
    }
  });
transporter.sendMail(option, function(error, info){
    if (error) {
      console.log(error);
    } else {
      console.log('Email sent: ' + info.response);
    }
});

截屏

For debugging purpose it is handy to implement a callback function (they never do on the nodemailer github page) which shows the error message (if there is one).出于调试目的,实现一个显示错误消息(如果有的话)的回调函数(他们从来没有在 nodemailer github 页面上做)是很方便的。

transporter.sendMail({
    from: from,
    to: to,
    subject: subject,
    html: text
}, function(err){
    if(err)
        console.log(err);
})

It helped me solve my problem... Turns out newer versions are not working properly:它帮助我解决了我的问题......结果是新版本无法正常工作:

"Looks like nodemailer 1.0 has breaking changes so 0.7 must be used instead: http://www.nodemailer.com/ “看起来 nodemailer 1.0 有重大变化,所以必须使用 0.7: http ://www.nodemailer.com/

Message posted on nodemailer as of 12/17/15:截至 2015 年 12 月 17 日在 nodemailer 上发布的消息:

Do not upgrade Nodemailer from 0.7 or lower to 1.0 as there are breaking changes.不要将 Nodemailer 从 0.7 或更低版本升级到 1.0,因为存在重大更改。 You can continue to use the 0.7 branch as long as you like.只要你愿意,你可以继续使用 0.7 分支。 See the documentation for 0.7 here ."请参阅此处0.7 的文档。”

I found this answer here我在这里找到了这个答案

And install smtp module as dependency:并安装 smtp 模块作为依赖项:

npm install smtp

var nodemailer = require('nodemailer');

var transporter = nodemailer.createTransport({
  service: 'gmail',
  type: "SMTP",
  host: "smtp.gmail.com",
  secure: true,
  auth: {
    user: 'writeYourGmailId@gmail.com',
    pass: 'YourGmailPassword'
  }
});

var mailOptions = {
  from: 'xyz.khan704@gmail.com',
  to: 'azran.khan704@gmail.com',
  subject: 'Sending Email to test Node.js nodemailer',
  text: 'That was easy to test!'
};

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

Go to https://myaccount.google.com/lesssecureapps and change it ON because Some apps and devices use less secure sign-in technology, which makes your account more vulnerable.转到https://myaccount.google.com/lesssecureapps并将其更改为ON,因为某些应用和设备使用安全性较低的登录技术,这会使您的帐户更容易受到攻击。 You can turn off access for these apps, which we recommend, or turn on access if you want to use them despite the risks.您可以关闭这些应用程序的访问权限(我们建议您这样做),或者如果您想使用它们而不顾风险打开访问权限。

try this code its work for me.试试这个代码对我有用。

var http = require('http');
var nodemailer = require('nodemailer');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});

  var fromEmail = 'akarthi@xyz.com';
  var toEmail = 'akarthi@xyz.com';

  var transporter = nodemailer.createTransport({
    host: 'domain',
    port: 587,
    secure: false, // use SSL
    debug: true,
      auth: {
        user: 'fromEmail@xyz.com',
        pass: 'userpassword'
      }
  });
   transporter.sendMail({
      from: fromEmail,
      to: toEmail,
      subject: 'Regarding forget password request',
      text: 'This is forget password response from your app',
      html: '<p>Your password is <b>sample</b></p>'
  }, function(error, response){
      if(error){
          console.log('Failed in sending mail');
          console.dir({success: false, existing: false, sendError: true});
          console.dir(error);
          res.end('Failed in sending mail');
      }else{
          console.log('Successful in sending email');
          console.dir({success: true, existing: false, sendError: false});
          console.dir(response);
          res.end('Successful in sending email');
      }
  });
}).listen(8000);
console.log('Server listening on port 8000');

response:回复:

Successful in sending email
{ success: true, existing: false, sendError: false }
{ accepted: [ 'akarthi@xyz.com' ],
  rejected: [],
  response: '250 2.0.0 uAMACW39058154 Message accepted for delivery',
  envelope: 
   { from: 'akarthi@xyz.com',
     to: [ 'akarthi@xyz.com' ] },
  messageId: '1479809555147-33de4987-29d605fa-6ee150f1@xyz.com' }

在此处输入图片说明

Adding to xShirase answer just providing screenshots where to enable.添加到 xShirase 答案仅提供启用的屏幕截图。 Also confirm in security that previous attempt was from you.还要安全地确认之前的尝试是由您发起的。

Xshirase deserves all upvotes.Iam just showing screenshot. Xshirase 值得所有人点赞。我只是显示屏幕截图。

You should not use gmail password for it anymore!不应该再使用 gmail密码了!

Recently google has provided a new method to use in 3rd party apps or APIs.最近谷歌提供了一种在第 3 方应用程序或 API 中使用的新方法。 You need to use App Password instead of the gmail password.您需要使用App Password而不是 gmail 密码。 But for creating it, you need to enable 2-step Authentication mode in your google account:但是要创建它,您需要在您的谷歌帐户中启用两步验证模式:

You can find steps here: https://support.google.com/mail/answer/185833?hl=en您可以在此处找到步骤: https://support.google.com/mail/answer/185833?hl=en

Here is best way send email using gmail这是使用 gmail 发送 email 的最佳方式

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

use two authentication from google => security => app password and do fill some stuff get app password使用来自谷歌的两次身份验证=>安全=>应用密码并填写一些东西获取应用密码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM