14

I've got a basic email setup done for sending an email using Nodemailer with AngularJS and NodeJS and I've got the project deployed on heroku.

The emailing seems to be working just fine when I am running the app on heroku, but when I get it deployed to Heroku no emails are sent.

For authentication, I am using a Gmail address and I also have a bcc to another Gmail address. So from and bcc addresses are two different Gmail addresses. The from address is the same as the address used for authentication.

Could somebody help me with resolving this issue?

Edit: Adding code

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

router.post('/send',function(req,res){

    var mailOptions = {
        from: 'Foo Bar ✔ <foobar@gmail.com>',
        to: req.body.email,
        subject: "Hello " + req.body.email,
        text: 'Hello ' + req.body.email + '✔',
        html: "<p>Hello " + req.body.email + " </p>",
        bcc: "fred@gmail.com"
    };
    transporter.sendMail(mailOptions, function(error, info){
        if(error){
            console.log(error);
        }else{
            console.log('Message sent: ' + info.response);
            res.send(200);
        }
    });        
});
turivishal
  • 34,368
  • 7
  • 36
  • 59
skip
  • 12,193
  • 32
  • 113
  • 153
  • Please include the error message. – Peter Lyons Sep 05 '14 at 20:18
  • @PeterLyons: Error: Invalid login, responseCode: 534, code: 'EAUTH'. – skip Sep 05 '14 at 20:29
  • Well, got any theories? Seems pretty clearly wrong credentials to me. – Peter Lyons Sep 05 '14 at 20:34
  • @PeterLyons: Looking forward to hear one from you as I could get the app working when testing locally. Am just wondering if its a captcha issue that gmail might be asking me to use when using my gmail credentials through heroku. So may be turning that off might make gmail happy? – skip Sep 05 '14 at 20:37
  • 7
    @PeterLyons: Yep, looked like I had to go here https://accounts.google.com/DisplayUnlockCaptcha and turn off this security precaution off from my gmail account for allowing the machine I've got my application deployed on through heroku to be able to send the emails through my gmail account using nodemailer. Good stuff by gmail. – skip Sep 05 '14 at 20:44
  • 2
    Cool. See the [nodemailer warning about trying to send bulk mail with services not explicitly intended for that](https://github.com/andris9/Nodemailer#delivering-bulk-mail). Consider switching to a real service designed for transactional email from applications such as mailgun, postmarkapp, sendgrid, amazon SES, etc. – Peter Lyons Sep 05 '14 at 20:46
  • https://accounts.google.com/b/0/DisplayUnlockCaptcha allowing login access to new devices or machines works fine but for a short period of time. – Valeed Anjum Sep 08 '21 at 05:45

6 Answers6

24

I believe this is an issue with google account security.

  • Google blocked your sign-in to use the mailing features due to an unknown device (location).

A few step to verify this:

  • Start your server locally and sends the email.

  • Check your account alerts for unknown sign-in.

This can be temporally resolved by: https://accounts.google.com/DisplayUnlockCaptcha

A more permanent resolution would be to change your password to a stronger level:

upper case letter + lower case letter + special symbols + numbers

turivishal
  • 34,368
  • 7
  • 36
  • 59
Alex Yan
  • 2,115
  • 1
  • 10
  • 8
10

Instead of using direct gmail credentials like this

auth: {
    user: 'foobar@gmail.com',
    pass: 'foobar'
}

Use OAuth2

 auth: {
    type: 'OAuth2',
    user: 'user@example.com',
    accessToken: 'ya29.Xx_XX0xxxxx-xX0X0XxXXxXxXXXxX0x'
}

Google blocks the heroku IPs (unsafe), if we are using direct credentials like you mentioned above. You can refer this Medium article here

Ebin Xavier
  • 359
  • 5
  • 8
4

5 years later, I still struggled this problem (all answers found on SO failed in my case). Here is what I did, for now everything works smoothly:

  • Install SendGrid addon to your Heroku app (Free plan gives you 12k messages a month)
  • Go to SendGrid panel
  • Go to Marketing -> Senders to add your sender bot, configure it like this:
  • From = any_address@heroku.com
  • Reply = your_gmail@gmail.com

enter image description here

enter image description here

  • Configure NodeMailer like so:

      const nodemailer = require('nodemailer'),
          sgTransport = require('nodemailer-sendgrid-transport');
    
      const mailTransporter = nodemailer.createTransport(sgTransport({
          auth: {
              api_key: process.env.ADMIN_EMAIL_API_KEY // your api key here, better hide it in env vars
          }
      }))
    
  • To send an email now, you have to add your gmail in 'Reply To' field, like so:

      mailTransporter.sendMail({
          from: `"Admin" <any_address@heroku.com>`,
          to: 'receiver@hotmail.com',
          replyTo: 'your_gmail@gmail.com',
          subject: 'Something',
          html: `Boom !`
      });
    

I think that's all, in case I forgot something, please add a comment below

DamianoPantani
  • 1,168
  • 2
  • 13
  • 23
  • that made it for me. seems like heroku is sometimes blocked from gmail. https://help.heroku.com/CFG547YP/why-am-i-getting-errors-when-sending-email-with-gmail-via-smtp – Luc Nov 23 '20 at 18:35
  • One suggestion: Use 'sender' email address in 'from'. https://app.sendgrid.com/settings/sender_auth/senders – Utkarsh Nov 18 '21 at 08:36
0

Try updating nodemailer package (using "npm update nodemailer" command)

var transporter = nodemailer.createTransport({
    host: 'smtp.gmail.com',
    port: 465,
    secure: true,
    auth: {
        user: 'youremai@gmail.com', // Your email id
        pass: 'pwd123' // Your password
    },
    tls: {
        // do not fail on invalid certs
        rejectUnauthorized: false
    }
});
router.post('/send',function(req,res){

    var mailOptions = {
        from: 'Foo Bar ✔ <foobar@gmail.com>',
        to: req.body.email,
        subject: "Hello " + req.body.email,
        text: 'Hello ' + req.body.email + '✔',
        html: "<p>Hello " + req.body.email + " </p>",
        bcc: "fred@gmail.com"
    };
    transporter.sendMail(mailOptions, function(error, info){
        if(error){
            console.log(error);
        }else{
            console.log('Message sent: ' + info.response);
            res.send(200);
        }
    });        
});
0

I know I'm too late but hopefully someone will find it helpful.

At the time of writing, Less Secure Apps is no longer supported by google. And you can't use your google account password.

You're gonna have to generate a new app password.

  1. Follow this link
  2. In the "Select App" dropdown, select Other and give the app a name (could be anything)
  3. Copy the password and replace it with your original password

It works on Local machine and Heroku.

const client = nodemailer.createTransport({
    service: "Gmail",
    auth: {
        user: "username@gmail.com",
        pass: "Google-App-Password-Without-Spaces"
    }
});

client.sendMail(
    {
        from: "sender",
        to: "recipient",
        subject: "Sending it from Heroku",
        text: "Hey, I'm being sent from the cloud"
    }
)

App passwords only work if 2-step verification is turned on. You can do so here

KRKI
  • 1
  • 3
0

Also if your app password is in your .env file you have to add it to the config vars in the settings tab of your app at heroku.

Tyler2P
  • 2,324
  • 26
  • 22
  • 31