npm Nodemailer:从未收到问候语

vwhgwdsa  于 2023-05-18  发布在  其他
关注(0)|答案(7)|浏览(87)

当尝试使用Nodemailer(https://github.com/nodemailer/nodemailer)在Node中发送电子邮件时,与Ethereal测试电子邮件帐户结合使用时,对Nodemailer传输器sendMail的调用引发错误Greeting never received
我尝试使用“回调方法”和“异步/等待”方法,但在两种情况下都抛出相同的错误。这两个例子都直接来自Nodemailer文档中的工作示例。也许我错过了一些简单的东西。:)
下面是产生错误的“回调方法”代码:

it('can send email with a dynamic test account', done => {
    nodemailer.createTestAccount((err, account) => {
        const transporter = nodemailer.createTransport({
            host: 'smtp.ethereal.email',
            port: 587,
            auth: {
                user: account.user, // generated ethereal user
                pass: account.pass // generated ethereal password
            }
        });

        const mailOptions = {
            from: '"Fred Foo 👻" <foo@example.com>', // sender address
            to: 'bar@example.com, baz@example.com', // list of receivers
            subject: 'Hello ✔', // Subject line
            text: 'Hello world?', // plain text body
            html: '<b>Hello world?</b>' // html body
        };

        // send mail with defined transport object
        transporter.sendMail(mailOptions, (error, info) => {
            if (error) {
                return console.log(error);
            }
            console.log('Message sent: %s', info.messageId);
            console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info));
            // Message sent: <b658f8ca-6296-ccf4-8306-87d57a0b4321@example.com>
            // Preview URL: https://ethereal.email/message/WaQKMgKddxQDoou...

            done();
        });
    });
}).timeout(10000);

下面是错误的堆栈跟踪:

{ Error: Greeting never received
    at SMTPConnection._formatError (/Users/<username>/projects/personal/learning-tests/javascript/nodemailer/node_modules/nodemailer/lib/smtp-connection/index.js:606:19)
    at SMTPConnection._onError (/Users/<username>/projects/personal/learning-tests/javascript/nodemailer/node_modules/nodemailer/lib/smtp-connection/index.js:579:20)
    at Timeout._greetingTimeout.setTimeout (/Users/<username>/projects/personal/learning-tests/javascript/nodemailer/node_modules/nodemailer/lib/smtp-connection/index.js:520:22)
    at ontimeout (timers.js:498:11)
    at tryOnTimeout (timers.js:323:5)
    at Timer.listOnTimeout (timers.js:290:5) code: 'ETIMEDOUT', command: 'CONN' }

一些额外的信息:

  • 节点版本:8.11.2
  • nodemailer版本:4.6.4
  • 操作系统:OSX version 10.12.6
laik7k3q

laik7k3q1#

在我的例子中,我需要在transporter对象上将secure键设置为true,然后它就工作了。

let transporter = nodemailer.createTransport({
        host: "mail.hostname.com",
        port: 465,
        secure: true, // true for 465, false for other ports
        auth: {
            user: 'user@hostname.com', // generated ethereal user
            pass: 'password', // generated ethereal password
        }
    });
o8x7eapl

o8x7eapl2#

在我的情况下,当我把端口586改为587时,它就工作了。

wmomyfyw

wmomyfyw3#

检查您的互联网连接,可能是关闭的。下面是一个Etheral Email和typescript的示例

import * as nodemailer from "nodemailer";

export const sendEmail = async (recipient: string, url: string, linkText: string) => {
  nodemailer.createTestAccount((err, account) => {
    if (err) {
      console.log(err);
    }
    const transporter = nodemailer.createTransport({
      host: account.smtp.host,
      port: account.smtp.port,
      secure: account.smtp.secure,
      auth: {
        user: account.user,
        pass: account.pass
      }
    });

    const message = {
      from: "Sender Name <sender@example.com>",
      to: `Recipient <${recipient}>`,
      subject: "Nodemailer is unicode friendly ✔",
      text: "Hello to myself!",
      html: `
        <html>
        <body>
        <p>Testing sparkpost API</p>
        <a href="${url}">${linkText}</a>
        </body>
        </html>`
    };

    transporter.sendMail(message, (err, info) => {
      if (err) {
        console.log("Error occurred. " + err.message);
      }

      console.log("Message sent: %s", info.messageId);
      // Preview only available when sending through an Ethereal account
      console.log("Preview URL: %s", nodemailer.getTestMessageUrl(info));
    });
  });
};
2jcobegt

2jcobegt4#

在我的例子中,/etc/postfix/main.cf中的smtpd_recipient_restrictions导致了这个问题。
变更为:

smtpd_recipient_restrictions =
   permit_mynetworks,
   permit_sasl_authenticated,
   reject_unauth_destination,
   check_policy_service unix:private/policyd-spf

现在成功了

4ktjp1zp

4ktjp1zp5#

我使用SendGrid作为电子邮件服务提供商,默认情况下,SendGrid对出站电子邮件使用机会性TLS加密。这可以防止网络犯罪分子在传输过程中阅读电子邮件的内容,即所谓的中间人攻击。您可以在sendgird官方博客https://sendgrid.com/blog/what-is-email-encryption/#:~:text= By%20default%2C%20SendGrid%20uses%20opportunistic,server%20accepts%20an%20inbound%20TLSv1中了解更多信息。
将.env文件中的secure从“false”更改为“true”,因为您需要安全地发送电子邮件。

#Mail Constant
MAIL_HOST=smtp.sendgrid.net
MAIL_PORT=465
MAIL_SECURE=true

#Mail credentials

MAIL_USERNAME=apikey
MAIL_PASSWORD= <yourAPIkey>

并从环境变量中获取secure的值,如下所示:

MailerModule.forRootAsync({
      useFactory: (configService: ConfigService) => {
        return {
          transport: {
            host: configService.get('MAIL_HOST'),
            port: +configService.get('MAIL_PORT'),
            secure: configService.get('MAIL_SECURE') === 'true',
            auth: {
              user: configService.get('MAIL_USERNAME'),
              pass: configService.get('MAIL_PASSWORD'),
            },
          },
          defaults: {
            from: '<sendgrid_from_email_address>',
          },
        };
      },
      inject: [ConfigService],
    }),
7xzttuei

7xzttuei6#

const transporter = nodemailer.createTransport({
  service: 'config.mail.service',
  port: 8000,
  auth: {
    user: 'config.mail.username',
    pass: 'config.mail.password'
  }
});

module.exports = {

  activationsMail: function (req) {
    // setup email data with unicode symbols
    const mailOptions = {
      from: '"Ecommerce" <noreply@ecommerce.com>', // sender address
      to: req.body.email, // list of receivers
      subject: 'Ecommerce Account Activate', // Subject line
      html: '<div>Please <a href="' + req.headers.host + 'user/activate/' + req.code + '" target="__new">click here</a> to active your account.</div>' // html body
    };
    console.log('PORT', req.headers.host);

    // send mail with defined transport object
    transporter.sendMail(mailOptions, function (error, info) {
      if (error) {
        console.log('Email Error', error);
      } else {
        console.log('Email sent: ' + info.response);
      }
    })
  }
};
vmjh9lq9

vmjh9lq97#

const transporter = nodemailer.createTransport({
  service: config.mail.service,
  port: 8000,
  auth: {
    user: config.mail.username,
    pass: config.mail.password
  }
});

module.exports = {

  activationsMail: function (req, data) {
    // setup email data with unicode symbols
    const link = 'http://' + req.headers.host + '/user/activate/' + data.verifyCode;
    console.log('CODE :', data.verifyCode);
    const mailOptions = {
      from: '"Ecommerce" <noreply@ecommerce.com>', // sender address
      to: req.body.email, // list of receivers
      subject: 'Please confirm your Email account', // Subject line
      html: '\n\n' + 'Please Click here to verify <a href=' + link + '> Click here</a>'
    };
    //console.log('PORT', req.headers.host);

    // send mail with defined transport object
    transporter.sendMail(mailOptions, function (error, info) {
      if (error) {
        console.log('Email Error', error);
      } else {
        // callback(true);
        console.log('Email sent: ' + info.response);
      }
    })
  };

相关问题