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

brafdlog
fonte
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
Greg T
fonte
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: '[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);
  }
});  

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!

Zaheen
fonte
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);
      });
  });
};
Laurent Perrin
fonte
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: '[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- divirta-se!

Mohammad Masoudzadeh
fonte
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.
Ahmet Can Güven
fonte
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: '[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);
}

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

Angel M.
fonte
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: '[email protected]',
        serviceClient: '113600000000000000000',
        privateKey: '-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBg...',
        accessToken: 'ya29.Xx_XX0xxxxx-xX0X0XxXXxXxXXXxX0x',
        expires: 1484314697598
    }
}); 
Hamid
fonte
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: "[email protected]",
        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 <[email protected]>'
cipiloto
fonte
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'
    }
}));
Girish Rathod
fonte
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>
malix
fonte
4

todo o seu código está bom, apenas o que resta é apenas acessar o link https://myaccount.google.com/security

e mantenha a rolagem para baixo e você encontrará Permitir aplicativos menos seguros: LIGADO e mantenha LIGADO, você não encontrará nenhum erro.

Y. Joy Ch. Singha
fonte
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.
mel3kings
fonte
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: "[email protected]",
  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.

Aaditya
fonte
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
user1071182
fonte
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: '[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;
Hamit YILDIRIM
fonte
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: "[email protected]",
        pass: "password"
    },
    tls: {
        rejectUnauthorized: false
    }
});






 const mailOptions = {
        from: "[email protected]",
        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

arul mb
fonte