Nodemailer with Gmail and NodeJS

Javascriptnode.jsNodemailer

Javascript Problem Overview


I try to use nodemailer to implement a contact form using NodeJS but it works only on local it doesn't work on a remote server...

My error message :

[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' }

My controller :

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('/');
	    }
	});
}

Javascript Solutions


Solution 1 - Javascript

I solved this by going to the following url (while connected to google with the account I want to send mail from):

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

There I enabled less secure apps.

Done

Solution 2 - Javascript

See nodemailer's official guide to connecting Gmail:

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

It works for me after doing this:

  1. Enable less secure apps - https://www.google.com/settings/security/lesssecureapps
  2. Disable Captcha temporarily so you can connect the new device/server - https://accounts.google.com/b/0/displayunlockcaptcha

Solution 3 - Javascript

Easy Solution:

var nodemailer = require('nodemailer');
var smtpTransport = require('nodemailer-smtp-transport');

var transporter = nodemailer.createTransport(smtpTransport({
  service: 'gmail',
  host: 'smtp.gmail.com',
  auth: {
    user: '[email protected]',
    pass: 'realpasswordforaboveaccount'
  }
}));

var mailOptions = {
  from: '[email protected]',
  to: '[email protected]',
  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);
  }
});  

Step 1:

go here https://myaccount.google.com/lesssecureapps and enable for less secure apps. If this does not work then

Step 2

go here https://accounts.google.com/DisplayUnlockCaptcha and enable/continue and then try.

for me step 1 alone didn't work so i had to go to step 2.

i also tried removing the nodemailer-smtp-transport package and to my surprise it works. but then when i restarted my system it gave me same error, so i had to go and turn on the less secure app (i disabled it after my work).

then for fun i just tried it with off(less secure app) and vola it worked again!

Solution 4 - Javascript

You should use an XOAuth2 token to connect to Gmail. No worries, Nodemailer already knows about that:

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

You'll need to go to the Google Cloud Console to register your app. Then you need to retrieve access tokens for the accounts you wish to use. You can use passportjs for that.

Here's how it looks in my code:

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

Solution 5 - Javascript

Worked fine:

1- install nodemailer, package if not installed (type in cmd) : npm install nodemailer

2- go to https://myaccount.google.com/lesssecureapps and turn on Allow less secure apps.

3- write code:

var nodemailer = require('nodemailer');

var transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: {
        user: '[email protected]',
        pass: 'truePassword'
    }
});

const mailOptions = {
    from: '[email protected]', // sender address
    to: '[email protected]', // 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- enjoy!

Solution 6 - Javascript

I had the same problem. Allowing "less secure apps" in my Google security settings made it work!

Solution 7 - Javascript

Same problem happened to me too. I tested my system on localhost then deployed to the server (which is located at different country) then when I try the system on production server I saw this error. I tried these to fix it:

  1. https://www.google.com/settings/security/lesssecureapps Enabled it but it was not my solution
  2. https://g.co/allowaccess I allowed access from outside for a limited time and this solved my problem.

Solution 8 - Javascript

Non of the above solutions worked for me. I used the code that exists in the documentation of NodeMailer. It looks like this:

let transporter = nodemailer.createTransport({
    host: 'smtp.gmail.com',
    port: 465,
    secure: true,
    auth: {
        type: 'OAuth2',
        user: '[email protected]',
        serviceClient: '113600000000000000000',
        privateKey: '-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBg...',
        accessToken: 'ya29.Xx_XX0xxxxx-xX0X0XxXXxXxXXXxX0x',
        expires: 1484314697598
    }
}); 

Solution 9 - Javascript

Try disabling captchas in your gmail account; probably being triggered based on IP address of requestor. See: https://stackoverflow.com/questions/1607828/how-to-use-gmail-as-a-free-smtp-server-and-overcome-captcha

Solution 10 - Javascript

For me is working this way, using port and security (I had issues to send emails from gmail using PHP without security settings)

I hope will help someone.

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: '[email protected]', // sender address
    to: '[email protected]', // 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);
}

all the config are listed here (including examples)

Solution 11 - Javascript

It is resolved using nodemailer-smtp-transport module inside createTransport.

var smtpTransport = require('nodemailer-smtp-transport');

var transport = nodemailer.createTransport(smtpTransport({
    service: 'gmail',
    auth: {
        user: '*******@gmail.com',
        pass: '*****password'
    }
}));

Solution 12 - Javascript

I found the simplest method, described in this article mentioned in Greg T's answer, was to create an App Password which is available after turning on 2FA for the account.

myaccount.google.com > Sign-in & security > Signing in to Google > App Passwords

This gives you an alternative password for the account, then you just configure nodemailer as a normal SMTP service.

var smtpTransport = nodemailer.createTransport({
	host: "smtp.gmail.com",
	port: 587,
	auth: {
		user: "[email protected]",
		pass: "app password"
	}
});

While Google recommend Oauth2 as the best option, this method is easy and hasn't been mentioned in this question yet.

Extra tip: I also found you can add your app name to the "from" address and GMail does not replace it with just the account email like it does if you try to use another address. ie.

from: 'My Pro App Name <[email protected]>'

Solution 13 - Javascript

If you use Express, express-mailerwrapsnodemailervery nicely and is very easy to use:

//# 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>

Solution 14 - Javascript

For some reason, just allowing less secure app config did not work for me even the captcha thing. I had to do another step which is enabling IMAP config:

From google's help page: https://support.google.com/mail/answer/7126229?p=WebLoginRequired&visit_id=1-636691283281086184-1917832285&rd=3#cantsignin

  • In the top right, click Settings Settings.
  • Click Settings.
  • Click the Forwarding and POP/IMAP tab.
  • In the "IMAP Access" section, select Enable IMAP.
  • Click Save Changes.

Solution 15 - Javascript

Many answers advice to allow less secure apps which is honestly not a clean solution.

Instead you should generate an app password dedicated to this use:

  1. Log in to your Google account
  2. Go to security
  3. Under Signing in to Google enable 2-Step Verification
  4. Under Signing in to Google click on App passwords.
  5. You'll now generate a new password. Select the app as Mail and the device as Other (Custom name) and name it.
  6. Save the app password

You can now use this app password instead of your log in password.

Solution 16 - Javascript

all your code is okay only the things left is just go to the link https://myaccount.google.com/security

and keep scroll down and you will found Allow less secure apps: ON and keep ON, you will find no error.

Solution 17 - Javascript

Just add "host" it will work .

host: 'smtp.gmail.com'

Then enable "lesssecureapps" by clicking bellow link

https://myaccount.google.com/lesssecureapps

Solution 18 - Javascript

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: "[email protected]",
  to: to,
  subject: subject,
  html: HTML
}
  , function (err, responseStatus) {
      if(responseStatus)
    console.log("checking dta", responseStatus.message);
    callback(err, responseStatus)
  });
});
}

You must add secureConnection type in you code.

Solution 19 - Javascript

I was using an old version of nodemailer 0.4.1 and had this issue. I updated to 0.5.15 and everything is working fine now.

Edited package.json to reflect changes then

npm install

Solution 20 - Javascript

Just attend those: 1- Gmail authentication for allow low level emails does not accept before you restart your client browser 2- If you want to send email with nodemailer and you wouldnt like to use xouath2 protocol there you should write as secureconnection:false like below

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: '[email protected]',
      to:'[email protected]',
      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;

Solution 21 - Javascript

first install nodemailer

npm install nodemailer  --save

import in to js file

const nodemailer = require("nodemailer");

const smtpTransport = nodemailer.createTransport({
    service: "Gmail",
    auth: {
        user: "[email protected]",
        pass: "password"
    },
    tls: {
        rejectUnauthorized: false
    }
});






 const mailOptions = {
        from: "[email protected]",
        to: [email protected],
        subject: "Welcome to ",
        text: 'hai send from me'.
    };


    smtpTransport.sendMail(mailOptions, function (error, response) {
        if (error) {
            console.log(error);
        }
        else {
            console.log("mail sent");
        }
    });

working in my application

Solution 22 - Javascript

You may need to "Allow Less Secure Apps" in your Gmail account (it's all the way at the bottom). You also may need to "Allow access to your Google account". You also may need to "Allow access to your Google account".

Solution 23 - Javascript

This is my Nodemailer configuration which worked after some research.

Step 1: Enable lesssecureapp

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

Step 2: The Nodemailer configuration for Gmail

> Setting up the transporter : A transporter is going to be an object that can send mail. It is the transport configuration object, connection URL, or a transport plugin instance

let transporter = nodemailer.createTransport({
	service: 'gmail',                              // the service used
	auth: {
		user: process.env.EMAIL_FROM,              // authentication details of sender, here the details are coming from .env file
		pass: process.env.EMAIL_FROM_PASSWORD,
	},
});

> Writing the message

const message = {
	from: '[email protected]',                         // sender email address
    to: "[email protected], [email protected]",   // reciever email address
    subject: `The subject goes here`,
    html: `The body of the email goes here in HTML`,
    attachments: [
    {
      filename: `${name}.pdf`,
      path: path.join(__dirname, `../../src/assets/books/${name}.pdf`),
      contentType: 'application/pdf',
    },
  ],

> Sending the mail

transporter.sendMail(message, function (err, info) {
	if (err) {                                            // if error
		console.log(err);
	} else {
		console.log(info);                                // if success
	}
});

Solution 24 - Javascript

I also had issues with nodemailer email sending when running on Vercel lambda in production.

What fixed it in my case was to await for sendMail Promise to resolve.

I also added nodemailer-smtp-transport like suggested in this thread but I don't think it made a difference.

Here is my whole function:

const nodemailer = require('nodemailer');
const smtpTransport = require('nodemailer-smtp-transport');


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


async function contact(req: any, res: any) {
    try {
        const response = await transporter.sendMail({
            from: '"*** <***gmail.com>', // sender address
            to: "***@gmail.com", // list of receivers
            subject: `***`, // Subject line
            html: `${req.body.message}<br/><br/>${req.body.firstname} ${req.body.lastname} - <b>${req.body.email}</b>`, // html body
        });
    } catch (error: any) {
        console.log(error);
        return res.status(error.statusCode || 500).json({ error: error.message });
    }

    return res.status(200).json({ error: "" });
}

export default contact;

Solution 25 - Javascript

There is another option to use SendGrid for email delivery with no failure. A lot of the time, Nodemailer gives failure for mail which could happen frequently.

Nodemailer can be found in the link.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questiontonymx227View Question on Stackoverflow
Solution 1 - JavascriptbrafdlogView Answer on Stackoverflow
Solution 2 - JavascriptGreg TView Answer on Stackoverflow
Solution 3 - JavascriptZaheenView Answer on Stackoverflow
Solution 4 - JavascriptLaurent PerrinView Answer on Stackoverflow
Solution 5 - JavascriptMohammad MasoudzadehView Answer on Stackoverflow
Solution 6 - JavascriptDaniel says Reinstate MonicaView Answer on Stackoverflow
Solution 7 - JavascriptAhmet Can GüvenView Answer on Stackoverflow
Solution 8 - JavascriptHamidView Answer on Stackoverflow
Solution 9 - JavascriptsfndView Answer on Stackoverflow
Solution 10 - JavascriptAngel M.View Answer on Stackoverflow
Solution 11 - JavascriptGirish RathodView Answer on Stackoverflow
Solution 12 - JavascriptscipilotView Answer on Stackoverflow
Solution 13 - JavascriptmalixView Answer on Stackoverflow
Solution 14 - Javascriptmel3kingsView Answer on Stackoverflow
Solution 15 - JavascriptEmericView Answer on Stackoverflow
Solution 16 - JavascriptY. Joy Ch. SinghaView Answer on Stackoverflow
Solution 17 - JavascriptMilan PanigrahiView Answer on Stackoverflow
Solution 18 - JavascriptaadityaView Answer on Stackoverflow
Solution 19 - Javascriptuser1071182View Answer on Stackoverflow
Solution 20 - JavascriptHamit YILDIRIMView Answer on Stackoverflow
Solution 21 - Javascriptarul mbView Answer on Stackoverflow
Solution 22 - JavascriptdonkeyView Answer on Stackoverflow
Solution 23 - Javascriptconfused_View Answer on Stackoverflow
Solution 24 - JavascriptMatthieu DsprzView Answer on Stackoverflow
Solution 25 - JavascriptHimanshu JoshiView Answer on Stackoverflow