I am sending email through nodemailer it goes into inbox of gmail if i run from local server but goes into spam of gmail if i run script from microsoft azure server.
following is my script
var nodemailer = require('nodemailer');
var EmailTemplates = require('swig-email-templates');
var smtpConfig = {
service: 'smtp.office365.com',
host: 'smtp.office365.com',
port: 587,
starttls: {
enable: true
},
secureConnection: true,
auth: {
user: 'xxxxx#yyyy.com',
pass: 'zzzzzz'
}
}
var templates = new EmailTemplates();
var transporter = nodemailer.createTransport(smtpConfig);
var context = {
username:'Rajesh',
email:'xxxxx#gmail.com',
link : 'www.google.co.in'
};
templates.render('activate_email.html', context, function(err, html,text, subject) {
transporter.sendMail({
from: '"Product Nameπ₯" <no-reply#xxxxx.com>', // sender address
to: 'xxxx#gmail.com',
subject: 'Account activation',
html: html,
text:text
});
});
The truth is there is no simple one line solutions for your problem :) There are numerous reasons why this can happen, and here are some of them:
Your host is marked as a spam - this happens if you have not verified your e-mail or you are sending too much e-mails from the same host. Shared hosting is commonly marked as such, and therefore mail server will regularly mark them as a spam
Your from field is different than the one you're allowed to use - as I see you're using smtp, there are strict rules for the mail you can send. Of course you can always send e-mail from mark#facebook.com, but since your SMTP's host is not facebook.com, your e-mail will pretty sure marked as spam
You can sign your e-mail in many various mails, assuring the servers that this e-mail is send from you and it has proper signature. Check online for the ways to do so.
While developing you have sent numerous alike e-mails - sending the very same "test" e-mail is a common reason for your e-mails to get blacklisted
There are emojis in your subject - that is not a 100% reason, but servers are often marking such e-mails as spams, especially in other fields (like from)
Unfortunately as I said there is no one real reason, there could be many of them. I hope this helps at least a little :)
in my case i needed to specify the form, the from need to be = to user mail
auth: {
user: "xxx#yyy.com",
pass: "password",
},
from: xxx#yyy.com,
Please get rid of the π₯ and try sending it again. I read in a article once that email clients don't like those icons because a lot of spammers are using them.
Try sending it to multiple gmail accounts. Other than that there's nothing wrong with the code. If you're on a shared hosting or local host it could also go into the junk folder. In that case you would have to look into sending the emails from a different IP, preferred in the same country as where you will send the emails to.
But first try to remove that icon!
PS. I would make this answer as a comment but I can't due to low rep.
For those who are still struggling for this problem. I suggest the following.
Make sure you add from field that matches with auth.user
let transporter = nodemailer.createTransport({
host: "smtp-mail.outlook.com",
secureConnection: false,
port: 587,
tls: {
ciphers: "SSLv3",
},
auth: {
user: <YOUR_EMAIL_ACCOUNT>,
pass: <YOUR_EMAIL_PASSWORD>,
},
from: <YOUR_EMAIL_ACCOUNT>,
});
Add text field describing your intent for the email in options payload
const mailOptions = {
from: `myCompany <mycompanyemail#gmail.com>`,
to: "recipient#gmail.com",
subject: "[MYCOMPANY] YOUR EMAIL VERIFICATION",
text: "Hello. This email is for your email verification.",
html: <h1>Hello</h1>,
};
If #1 or #2 doesn't solve your problem. Try using test-mailer and send email to their provided test email address. It will show you where your vulnerabilities are especially the part where you have to setup SPF, DKIM, and DMARC.
If you are using a custom domain setup SPF, DKIM, DMARC following this article.
Late to the party..
Try adding both HTML and Text Versions both in your emailConfig as below. That way the email will land up in the inbox. It worked for me.
var emailOptions = {
from: 'cxxxxxkxxxxx#xxxxx.com',
to: 'xxxx#xxxxxx.com',
cc:'sxxxxxxsh#xxxx.com, xxxa#xxx.com, aaaxxxx#xxxx.com',
bcc:'xxxxx.wrxxxk#xxxx.com',
subject: 'xxxxxxxxxx',
/* Adding HTML and Text Version, so the email will not land up in the Spam folder */
html: 'Hello Team! <br><br>Please find attached...<br><br>Thanks,<br>XXXXX',
text: 'Hello Team! <br><br>Please find attached...<br><br>Thanks,<br>XXXXX',
attachments: [{
// file on disk as an attachment, concatenating the file extension separately since NODE is not renaming the file properly with fs.renameSync
filename: finalFileNameWithoutExt + '.xlsx',
path: reportsLocationPathWithYearMonth + finalFileNameWithoutExt + '.xlsx' // stream this file
}]
};
HTML goes to junk, plain text doesn't
Related
I am using Nodejs with Express and I am sending an email through Sendgrid, but Sendgrid is changing the href link
var emailText = '<!DOCTYPE html><html><head><meta charset="UTF-8"></head><body>Here</body></html>'
var from_email = new helper.Email('contact#test.com');
var to_email = new helper.Email('contact#test2.com');
var subject = 'Test';
var content = new helper.Content("text/html", emailText)
var mail = new helper.Mail(from_email, subject, to_email, content);
var request = sg.emptyRequest({
method: 'POST',
path: '/v3/mail/send',
body: mail.toJSON(),
});
sg.API(request, function(error, response) {
if (error) {
console.log('Error response received');
}
console.log(response.statusCode);
console.log(response.body);
console.log(response.headers);
});
When the email arrives the following link appears:
https://u4006412.ct.sendgrid.net/wf/click?upn=rOQ9fjZGp5r0JyNfoC02LbL.....
Could someone help me solve this problem?
I believe this is caused by the URL click-tracking feature of sendgrid. It will redirect to your intended resource, but does not look pretty. You can turn it off in sendgrid, but it will disable URL tracking on all emails sent by that account. If you are integrating with a 3rd-party link-tracker such as bit.ly or have your GA on lock-down, this may not bother you.
Here's more information on the feature in sendgrid: https://sendgrid.com/docs/User_Guide/Settings/tracking.html
Turn that off and see how your emails look.
UPDATE: Whitelabeling in Sendgrid
Sendgrid also has a whitelabeling feature, allowing you to serve URLs from one of your subdomains while still tracking clicks/opens through their servers. If you are concerned about the prettiness of your links or perceived security from a UX perspective, this may be the way to go.
Check out their overview of whitelabeling and
link whitelabeling doc pages. Be sure to follow sendgrid's recommendations on domain usage in emails. This ensures a high success rate on delivery.
You can off the Sendgrid tracking for one link specifically.
To do so, You have to add clicktracking="off" before your href tag
Do it like this
<a clicktracking="off" href='https://mysite/auth/'>My Site</a>
Similar to #israa-saifullah said, you can state clicktracking="off" directly in an html link, but if you're sending through the sg api, there is a trackingSettings property that you can set on an individual message where you can specify if you want click and open-tracking enabled. clickTracking is what re-writes your URL's, and you can specify it at the HTML or Text based level. For example this disables all tracking and therefore leaves the URL's in the email untouched.
const msg = {
to: TO_ADDRESSS,
from: {
name: FROM_NAME,
email: FROM_ADDRESSS,
},
subject: SUBJECT,
text: TEXT_VERSION,
html: HTML_VERSION,
trackingSettings: {
clickTracking: {
enable: false,
enableText: false
},
openTracking: {
enable: false
}
}
This is helpful if you don't want to override tracking at the account level (in the SG Dashboard), but just for a specific use case.
Documentation here.
It is possible to change through the sendgrid settings, access the path: settingns -> tracking -> click tracking -> disabled
I don't know what I'm missing, I use the Nodemailer example:
var nodemailer = require("nodemailer");
// create reusable transport method (opens pool of SMTP connections)
var smtpTransport = nodemailer.createTransport("SMTP",{
service: "Gmail",
auth: {
user: "gmail.user#gmail.com",
pass: "userpass"
}
});
// setup e-mail data with unicode symbols
var mailOptions = {
from: "Fred Foo β <foo#blurdybloop.com>", // sender address
to: "bar#blurdybloop.com, baz#blurdybloop.com", // list of receivers
subject: "Hello β", // Subject line
text: "Hello world β", // plaintext body
html: "<b>Hello world β</b>" // html body
}
// send mail with defined transport object
smtpTransport.sendMail(mailOptions, function(error, response){
if(error){
console.log(error);
}else{
console.log("Message sent: " + response.message);
}
// if you don't want to use this transport object anymore, uncomment following line
//smtpTransport.close(); // shut down the connection pool, no more messages
});
I just changed the user and pass in auth to my gmail account info (also tried with their values), and I changed the "to" email address to my email address. I get:
{ [Error: connect ECONNREFUSED]
code: 'ECONNREFUSED',
errno: 'ECONNREFUSED',
syscall: 'connect' }
What am I missing? I don't see anything in the documentation that says I need to do anything more than this, so why won't it work? Thank you in advance.
It was a firewall issue. Turns out there was nothing wrong with the code, I just didn't understand what the error message implied.
I was also using a gmail account to send the email, you might need an Application-specific password from google to allow nodemailer to work properly.
https://support.google.com/mail/answer/1173270?hl=en
Following step:
Login gmail account.
Enable pop3 in settings tabs
Enable less secure apps at: Enable less secure apps for gmail account
Display Unlock Captcha at: Display unlock Captcha
Defined email option and sending
var mailOptions = {
host: 'smtp.gmail.com',
port: 465,
secure: true, // use SSL
auth: {
user: 'gmail_account#gmail.com',
pass: 'password'
}
}
mailer = nodemailer.createTransport(mailOptions);
mailer.sendMail({
....
}, function(err, response) {
if (err) {
console.log(err);
}
console.log(response);
});
Hope this block code help you.
ECONNREFUSED inidcates that this is some kind of connection or firewall issue.
Can you connect to smtp.gmail.com port 465 with any other application from the same machine, for example with openssl?
openssl s_client -connect smtp.gmail.com:465
if you use new nodemailer version
nodemailer.createTransport({
host,
port,
secure:,
auth:{
user,
pass
}
})
more see https://github.com/andris9/nodemailer-wellknown
In my case I just had to disable my anti virus, Avast.
To white list on avast do this:
These steps may vary according to your Avast version, including the IP used here
1) Open Avast, go to: Menu -> Settings. (It is located on the top right corner)
2) Go to General Tab -> Exceptions -> Add Exception
3) Get the IP of your gmail, it is going to be with the error, I think.
4) Now paste the IP on your exception
Hope it helps.
The actual problem fix is that you need to place the SERVICE. Better if you use ENVIRONMENT VARIABLES
var transporter = nodemailer.createTransport({
service: process.env.EMAIL_SERVICE,
auth: {
user:process.env.EMAIL_USER,
pass:process.env.EMAIL_PASSWORD
}
})
firewall problem
to block the firewall in order to send email, you need to allow port or disable all port.
allowing specific port:
$ sudo ufw allow 587
to disable firewall
$ sudo ufw disable
$ sudo ufw reset
In my node.js-App, that runs on 1 Heroku worker, needs to send out emails from time to time. The logic is the following:
var transporter = Email.createTransport({
service: 'yahoo',
auth: {
user: process.env.CRAWLER_MAIL,
pass: process.env.CRAWLER_PWD
}
});
transporter.sendMail({
from: process.env.CRAWLER_MAIL,
to: process.env.CRAWLER_RCVR_MAIL,
subject: 'subject',
text: 'text'
}, function(err, result) {
if (err !== null) {
console.log(err);
} else {
...
}
});
I tested this with foreman start and it worked fine. Nonetheless, once deployed to Heroku, the transporter always emits an error with status code '564 : We were unable to deliver your message. Please try resending your message by adding some text.'
process.env. hold the correct values, I checked for that, and text is always a string.
What could be wrong?
I was not able to replicate your problem using my account details.
Could it be related to the sender/recipient emails? Are they both #yahoo.com addresses?
There has been some chatter in forums about yahoo groups emails specifically not working and giving that error. Something to do with Yahoo changing their DMARC policy recently.
Nodemailer loads predefined "well known" services from submodule nodemailer-wellknown
This is the current definition loaded when using service: 'yahoo' in your createTransport():
https://github.com/andris9/nodemailer-wellknown/blob/master/services.json#L160
A few thing worth trying:
Switch the smtp server to plus.smtp.mail.yahoo.com.
Try the username with and without #yahoo.com
Make sure you are sending from a real email address - and not an alias.
We use Mandrill for SMTP on Heroku with our Nodemailer app.
Very reliable and the first 12k emails sent per month are free!
Can you try using it without the service option and specifying the SMTP sever manually as shown below.
var transporter = Email.createTransport(smtpTransport({
host: 'smtp.mail.yahoo.com',
port: 465,
auth: {
user: process.env.CRAWLER_MAIL,
pass: process.env.CRAWLER_PWD
}
}));
I had this problem some time ago and was solved when I bypassed the service
Try this code :
I know it looks same but there are small changes that might solve your problem. Give it a try as it worked fine with foreman start and do let me know if it did any good...
var nodemailer = require('nodemailer');
var transporter = Email.createTransport({
service: 'yahoo',
auth: {
user: 'process.env.CRAWLER_MAIL',
pass: 'process.env.CRAWLER_PWD'
}
});
transporter.sendMail({
from: 'process.env.CRAWLER_MAIL',
to: 'process.env.CRAWLER_RCVR_MAIL',
subject: 'subject',
text: 'text'
});
I'm using the Nodemailer Node.js module to interface with sendmail. However, my emails go directly to the spam folder when reached by a Gmail account. Why are my emails being shit-canned? It must be something to do with the headers of the email, but I have no idea what it could be.
I'm not really familiar with emails and what spam filters look for, so could someone please provide me with some details on what to watch out for?
Thanks for reading. :)
I've faced with the same issue and was able to fix it by updating 'from' field to this format:
from: 'Sender Name <some-random-email#gmail.com>'
complete code:
let transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 587,
secure: false,
requireTLS: true,
auth: {
user: 'some-random-email#gmail.com',
pass: 'pass'
},
from: 'some-random-email#gmail.com'
});
const mailOptions = {
from: 'Sender Name <some-random-email#gmail.com>'
to: 'some-new-random-email#gmail.com',
subject: 'Subject',
text: 'Text'
};
return transporter.sendMail(mailOptions, (error, info) => {
...
});
Here's a few reasons:
So You'd Like to Send Some Email (Through Code) (2010)
There are also blacklists of ip addresses. Anything coming from these would just be ignored or regarded as spam.
If your email is sent from a server which doesn't seem to be linked to the from address you'll have potential issues as well.
Detecting spam and trying not to be seen as spam are both non trivial things. That's why a lot of mailing lists are done through a specialist provider.
In case if your IP is blacklisted, you will need to use third party email service like:
MailJet: it's free plan has limitation of 200 mails per day. https://github.com/mailjet/mailjet-apiv3-nodejs/blob/master/README.md
SendGrid: Free plan has 100 mails/day https://sendgrid.com
Mailgun: 10000 mails/month free https://www.mailgun.com
Check their documentation for integration with your application.
data/mail.private - change to wherever your Open DKIM private key file is located.
var client = require('nodemailer').createTransport({
secure: false,
pool: true,
host: 'yourdomain.io',
port: app.nconf.get('mail:port'),
auth: {
user: app.nconf.get('mail:user'),
pass: app.nconf.get('mail:pass')
},
dkim: {
domainName: 'yourdomain.io',
keySelector: 'mail',
privateKey: require('fs').readFileSync('data/mail.private', {
encoding: 'utf8'
})
}
})
I don't know what I'm missing, I use the Nodemailer example:
var nodemailer = require("nodemailer");
// create reusable transport method (opens pool of SMTP connections)
var smtpTransport = nodemailer.createTransport("SMTP",{
service: "Gmail",
auth: {
user: "gmail.user#gmail.com",
pass: "userpass"
}
});
// setup e-mail data with unicode symbols
var mailOptions = {
from: "Fred Foo β <foo#blurdybloop.com>", // sender address
to: "bar#blurdybloop.com, baz#blurdybloop.com", // list of receivers
subject: "Hello β", // Subject line
text: "Hello world β", // plaintext body
html: "<b>Hello world β</b>" // html body
}
// send mail with defined transport object
smtpTransport.sendMail(mailOptions, function(error, response){
if(error){
console.log(error);
}else{
console.log("Message sent: " + response.message);
}
// if you don't want to use this transport object anymore, uncomment following line
//smtpTransport.close(); // shut down the connection pool, no more messages
});
I just changed the user and pass in auth to my gmail account info (also tried with their values), and I changed the "to" email address to my email address. I get:
{ [Error: connect ECONNREFUSED]
code: 'ECONNREFUSED',
errno: 'ECONNREFUSED',
syscall: 'connect' }
What am I missing? I don't see anything in the documentation that says I need to do anything more than this, so why won't it work? Thank you in advance.
It was a firewall issue. Turns out there was nothing wrong with the code, I just didn't understand what the error message implied.
I was also using a gmail account to send the email, you might need an Application-specific password from google to allow nodemailer to work properly.
https://support.google.com/mail/answer/1173270?hl=en
Following step:
Login gmail account.
Enable pop3 in settings tabs
Enable less secure apps at: Enable less secure apps for gmail account
Display Unlock Captcha at: Display unlock Captcha
Defined email option and sending
var mailOptions = {
host: 'smtp.gmail.com',
port: 465,
secure: true, // use SSL
auth: {
user: 'gmail_account#gmail.com',
pass: 'password'
}
}
mailer = nodemailer.createTransport(mailOptions);
mailer.sendMail({
....
}, function(err, response) {
if (err) {
console.log(err);
}
console.log(response);
});
Hope this block code help you.
ECONNREFUSED inidcates that this is some kind of connection or firewall issue.
Can you connect to smtp.gmail.com port 465 with any other application from the same machine, for example with openssl?
openssl s_client -connect smtp.gmail.com:465
if you use new nodemailer version
nodemailer.createTransport({
host,
port,
secure:,
auth:{
user,
pass
}
})
more see https://github.com/andris9/nodemailer-wellknown
In my case I just had to disable my anti virus, Avast.
To white list on avast do this:
These steps may vary according to your Avast version, including the IP used here
1) Open Avast, go to: Menu -> Settings. (It is located on the top right corner)
2) Go to General Tab -> Exceptions -> Add Exception
3) Get the IP of your gmail, it is going to be with the error, I think.
4) Now paste the IP on your exception
Hope it helps.
The actual problem fix is that you need to place the SERVICE. Better if you use ENVIRONMENT VARIABLES
var transporter = nodemailer.createTransport({
service: process.env.EMAIL_SERVICE,
auth: {
user:process.env.EMAIL_USER,
pass:process.env.EMAIL_PASSWORD
}
})
firewall problem
to block the firewall in order to send email, you need to allow port or disable all port.
allowing specific port:
$ sudo ufw allow 587
to disable firewall
$ sudo ufw disable
$ sudo ufw reset