Nodemailer: Greeting Never Received
When Trying to Send Email Within Node Using Nodemailer (), the Call to the sendMail of the Nodemailer Transporter Is Raising the Error Greeting Never Received...
When trying to send email within Node using Nodemailer (), the call to the sendMail of the Nodemailer transporter is raising the error Greeting never received when using in conjunction with an Ethereal test email account.
I have tried using both a "callback approach" and also an "async/await" approach, but the same error is thrown in both scenarios. Both examples are pretty much straight from the working examples in the Nodemailer documentation. Maybe I'm missing something simple? :)
Here is the "callback approach" code that is producing the error:
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 👻" <[email protected]>', // sender address
to: '[email protected], [email protected]', // 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: <[email protected]>
// Preview URL:
done();
});
});
}).timeout(10000);
And here is the stacktrace of the error:
{ 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' }
And some additional info:
- node version:
8.11.2 - nodemailer version:
4.6.4 - operating system:
OSX version 10.12.6
7 Answers
In my case I needed to set the secure key to true on the transporter object and then it worked.
let transporter = nodemailer.createTransport({
host: "mail.hostname.com",
port: 465,
secure: true, // true for 465, false for other ports
auth: {
user: '[email protected]', // generated ethereal user
pass: 'password', // generated ethereal password
}
});
In my case, when I have changed port 586 to 587, then it worked.
Check your internet connection probably its down . below is an example with Etheral Email with 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 <[email protected]>",
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));
});
});
};
In my case the smtpd_recipient_restrictions in /etc/postfix/main.cf was causing this issue.
Changed it to:
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
check_policy_service unix:private/policyd-spf
and now it works!
I am using SendGrid as an email sevice provider and by default, SendGrid uses opportunistic TLS encryption for outbound emails. This prevents cybercriminals from reading the contents of an email while it’s in transit, known as a man-in-the-middle attack.You can explore about it more in the sendgird official blog
Change secure from 'false' to the 'true' in your .env file as you need to send email securely.
#Mail Constant
MAIL_HOST=smtp.sendgrid.net
MAIL_PORT=465
MAIL_SECURE=true
#Mail credentials
MAIL_USERNAME=apikey
MAIL_PASSWORD= <yourAPIkey>
and fetch the value of secure form your environment variables like this :
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],
}),
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" <[email protected]>', // 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);
}
})
}
};
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 = ' + req.headers.host + '/user/activate/' + data.verifyCode;
console.log('CODE :', data.verifyCode);
const mailOptions = {
from: '"Ecommerce" <[email protected]>', // 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);
}
})
};