Nodemailer com Gmail e NodeJS


110

Tento usar o nodemailer para implementar um formulário de contato usando NodeJS, mas funciona apenas no local, não funciona em um servidor remoto ...

Minha mensagem de erro:

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

Meu controlador:

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

14
google.com/accounts/DisplayUnlockCaptcha (para visibilidade, postado por um bom comentarista abaixo). Apenas permita o acesso uma vez e deixe o nodemailer fazer o login automaticamente.
laggingreflex

3
Depois de tentar de tudo para enviar e-mail via gmail usando nodemailer, a seguinte configuração funcionou para mim ..
faizanjehangir

Respostas:


136

Resolvi isso acessando o seguinte url (enquanto conectado ao google com a conta da qual desejo enviar e-mails):

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

Lá eu habilitei aplicativos menos seguros.

Feito


1
Bem feito! está funcionando, embora eu não ache que seja a melhor ideia ... Recebi meu primeiro e-mail
..

sem habilitar isso, ele nem funcionará no ambiente local. ele mencionou claramente que está funcionando no ambiente local e não no servidor remoto. qual é a solução para isso?
Adithya Sai

isso não pode ajudá-lo se você tiver autenticação 2FA em sua conta do gmail
sasha romanov

63

Consulte o guia oficial do nodemailer para conectar o Gmail:

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

-

Funciona para mim depois de fazer isso:

  1. Habilite aplicativos menos seguros - https://www.google.com/settings/security/lesssecureapps
  2. Desative o Captcha temporariamente para conectar o novo dispositivo / servidor - https://accounts.google.com/b/0/displayunlockcaptcha

18
O número 2 resolveu minhas aflições. Não consegui encontrar esse link nas configurações de contas do Google. Obrigado!
programstinator

1
O mesmo aqui. Eu já fiz o # 1 e recebi e-mails funcionando no localhost, mudei para a produção e nada funcionou. # 2 corrigiu meu problema para produção. Obrigado
John

49

Solução fácil:

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

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

var mailOptions = {
  from: 'somerealemail@gmail.com',
  to: 'friendsgmailacc@gmail.com',
  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);
  }
});  

Passo 1:

vá aqui https://myaccount.google.com/lesssecureapps e habilite para aplicativos menos seguros. Se isso não funcionar, então

Passo 2

vá aqui https://accounts.google.com/DisplayUnlockCaptcha e ative / continue e tente.

para mim, a etapa 1 sozinha não funcionou, então tive que ir para a etapa 2.

Também tentei remover o pacote nodemailer-smtp-transport e, para minha surpresa, funcionou. mas quando reiniciei meu sistema deu-me o mesmo erro, então eu tive que ir e ligar o aplicativo menos seguro (eu desativei depois do meu trabalho).

em seguida, para me divertir, eu apenas tentei com off (app menos seguro) e vola funcionou novamente!


1
As etapas 1 e 2 foram muito úteis. obrigado! Eu tentei a etapa 1 antes de ver sua solução e não funcionou, mas com a etapa 2 é uma mágica!
MissStack

"smptTransport não é uma função"
JWiley

Tentei com a maneira como você compartilhou conosco, mas estou recebendo o mesmo erro repetidamente {Erro: conectar ETIMEDOUT 74.125.68.108:465 em TCPConnectWrap.afterConnect [as oncomplete] (net.js: 1097: 14) errno: ' ETIMEDOUT ', código:' ECONNECTION ', syscall:' conectar ', endereço: '74 .125.68.108', porta: 465, comando: 'CONN'}
Anwar Hussain

@AnwarHussain: Eu também estou recebendo o mesmo erro de novo
Pappa S

42

Você deve usar um token XOAuth2 para se conectar ao Gmail. Não se preocupe, o Nodemailer já sabe disso:

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

Você precisará acessar o Google Cloud Console para registrar seu aplicativo. Em seguida, você precisa recuperar tokens de acesso para as contas que deseja usar. Você pode usar passaportes para isso.

Veja como fica no meu código:

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

9
Existe uma solução mais fácil para enviar um e-mail no NodeJS com uma conta do GMail?
tonymx227


você pode explicar o que o passport.authorize faz e por que você precisa do escopo, callbackurl e outros, por que você não pode simplesmente fazer isso com clientId e secret?
Ismail

passport.authorizeé semelhante a, passport.authenticateexceto que não tenta atualizar a sessão atual. Você precisa passar callbackURLporque, após o handshake do OAuth, o Google precisa saber para onde redirecionar o usuário para que o handshake seja concluído.
Laurent Perrin


14

Funcionou bem:

1- instale o nodemailer , pacote se não estiver instalado (digite cmd):npm install nodemailer

2- vá para https://myaccount.google.com/lesssecureapps e ative Permitir aplicativos menos seguros .

3- escrever o código:

var nodemailer = require('nodemailer');

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

const mailOptions = {
    from: 'any@any.com', // sender address
    to: 'true@true.com', // 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- divirta-se!


11

O mesmo problema aconteceu comigo também. Testei meu sistema no localhost e depois implantei no servidor (que está localizado em um país diferente) e, ao tentar o sistema no servidor de produção, vi este erro. Tentei estes para consertar:

  1. https://www.google.com/settings/security/lesssecureapps Habilitado, mas não foi minha solução
  2. https://g.co/allowaccess Eu permiti o acesso de fora por um tempo limitado e isso resolveu meu problema.

2
O link g.co/allowaccess foi o que corrigiu para mim (já havia habilitado lesssecureapps) - obrigado!

10

Para mim está funcionando dessa forma, usando porta e segurança (tive problemas para enviar e-mails do gmail usando PHP sem configurações de segurança)

Espero ajudar alguém.

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: 'xxxx@gmail.com', // sender address
    to: 'yyyy@gmail.com', // 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);
}

todas as configurações estão listadas aqui (incluindo exemplos)


10

Nenhuma das soluções acima funcionou para mim. Usei o código que existe na documentação do NodeMailer . Se parece com isso:

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

obrigado parceiro ! :) thissss ---> host: 'smtp.gmail.com', porta: 465, seguro: verdadeiro, funcionou para mim
Praveen Vishnu

@PraveenVishnu Não tem problema, se você votar nesta resposta, mais pessoas a verão. Isso pode ajudá-los também.
Hamid de

Olá, Eu sei que este já é antigo, mas você se importaria de onde você conseguiu serviceClient, privateKey e accessToken? Obrigado.
Aljohn Yamaro

@AljohnYamaro O serviço de e-mail fornecerá isso. No meu caso foi o Gmail. Você pode ler mais aqui: stackoverflow.com/questions/36214968/…
Hamid


9

Descobri que o método mais simples, descrito neste artigo mencionado na resposta de Greg T , era criar uma senha de app que fica disponível após a ativação do 2FA para a conta.

myaccount.google.com> Login e segurança> Login no Google> Senhas de app

Isso lhe dá uma senha alternativa para a conta, então você apenas configura o nodemailer como um serviço SMTP normal.

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

Embora o Google recomende Oauth2 como a melhor opção, esse método é fácil e não foi mencionado nesta pergunta ainda.

Dica extra: também descobri que você pode adicionar o nome do seu aplicativo ao endereço "de" e o GMail não o substitui apenas pelo e-mail da conta, como faria se você tentar usar outro endereço. ie.

from: 'My Pro App Name <username@gmail.com>'

Sempre usando this1. Você precisa definir a autenticação de 2 fábricas para definir a senha do aplicativo. Oposto em menos seguro.
gdfgdfg

8

Ele é resolvido usando o nodemailer-smtp-transportmódulo dentro de createTransport.

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

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

4

Se você usar Express, express-mailerenvolve nodemailermuito bem e é muito fácil de usar:

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



4

Por algum motivo, apenas permitir uma configuração de aplicativo menos segura não funcionou para mim, nem mesmo a coisa do captcha. Tive que realizar outra etapa que é habilitar a configuração IMAP:

Na página de ajuda do google: https://support.google.com/mail/answer/7126229?p=WebLoginRequired&visit_id=1-636691283281086184-1917832285&rd=3#cantsignin

  • No canto superior direito, clique em Configurações Configurações.
  • Clique em Configurações.
  • Clique na guia Encaminhamento e POP / IMAP.
  • Na seção "Acesso IMAP", selecione Ativar IMAP.
  • Clique em Salvar alterações.

3
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: "mail@from.com",
  to: to,
  subject: subject,
  html: HTML
}
  , function (err, responseStatus) {
      if(responseStatus)
    console.log("checking dta", responseStatus.message);
    callback(err, responseStatus)
  });
});
}

Você deve adicionar o tipo secureConnection em seu código.


2

Eu estava usando uma versão antiga do nodemailer 0.4.1 e tive esse problema. Eu atualizei para 0.5.15 e tudo está funcionando bem agora.

Editou package.json para refletir as mudanças então

npm install

3
É melhor fazer o npm update para esse caso. Se você quiser saber mais sobre como a atualização do npm e a instalação do npm são diferentes - consulte esta resposta - stackoverflow.com/questions/12478679/…
Anthony Akentiev

2

Apenas atenda a estes: 1- A autenticação do Gmail para permitir e-mails de baixo nível não aceita antes de reiniciar o navegador do cliente 2- Se você deseja enviar e-mail com o nodemailer e não gostaria de usar o protocolo xouath2, você deve escrever como secureconnection: false como abaixo

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: 'from@gmail.com',
      to:'to@gmail.com',
      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;

smtpTransport é usado duas vezes, qual é o quê?
Biranchi

Realmente, é muito claro O primeiro é para criar configurações smtpTransport e o segundo para enviar e-mail usando essas configurações está funcionando perfeitamente no firebase hoje em dia
Hamit YILDIRIM

2

primeiro instale o nodemailer

npm install nodemailer  --save

importar para o arquivo js

const nodemailer = require("nodemailer");

const smtpTransport = nodemailer.createTransport({
    service: "Gmail",
    auth: {
        user: "example@gmail.com",
        pass: "password"
    },
    tls: {
        rejectUnauthorized: false
    }
});






 const mailOptions = {
        from: "example@gmail.com",
        to: sending@gmail.com,
        subject: "Welcome to ",
        text: 'hai send from me'.
    };


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

trabalhando em meu aplicativo

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.