Nodemailer con Gmail y NodeJS

110

Intento usar nodemailer para implementar un formulario de contacto usando NodeJS pero funciona solo en local, no funciona en un servidor remoto ...

Mi mensaje de error:

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

Mi 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
fuente
14
google.com/accounts/DisplayUnlockCaptcha (para visibilidad, publicado por un buen comentarista a continuación). Solo permita el acceso una vez y deje que nodemailer inicie sesión automáticamente, lo hará.
laggingreflex
3
Después de intentar todo lo posible para enviar correo a través de Gmail usando nodemailer, el siguiente ajuste trabajó para mí ..
faizanjehangir

Respuestas:

136

Resolví esto yendo a la siguiente URL (mientras estaba conectado a Google con la cuenta desde la que quiero enviar correo):

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

Allí habilité aplicaciones menos seguras.

Hecho

brafdlog
fuente
1
¡Bien hecho! está funcionando, aunque no creo que sea la mejor idea ... Recibí mi primer correo
electrónico ..
sin habilitar esto, ni siquiera funcionará en el entorno local. mencionó claramente que está funcionando en un entorno local y no en un servidor remoto. ¿Cuál es la solución para eso?
Adithya Sai
esto no puede ayudarlo si tiene autenticación 2FA en su cuenta de gmail
sasha romanov
63

Consulte la guía oficial de nodemailer para conectar Gmail:

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

-

Funciona para mí después de hacer esto:

  1. Habilite aplicaciones menos seguras: https://www.google.com/settings/security/lesssecureapps
  2. Desactive Captcha temporalmente para que pueda conectar el nuevo dispositivo / servidor: https://accounts.google.com/b/0/displayunlockcaptcha
Greg T
fuente
18
El número 2 resolvió mis problemas. No pude encontrar ese enlace en ninguna parte de la configuración de cuentas de Google. ¡Gracias!
programstinator
1
Igual que aquí. Anteriormente hice el # 1 y obtuve correos electrónicos trabajando en localhost, pasé a producción y nada funcionó. # 2 solucionó mi problema de producción. Gracias
Juan
49

Solución 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);
  }
});  

Paso 1:

ve aquí https://myaccount.google.com/lesssecureapps y habilite las aplicaciones menos seguras. Si esto no funciona entonces

Paso 2

ve aquí https://accounts.google.com/DisplayUnlockCaptcha y habilite / continúe y luego intente.

Para mí, el paso 1 solo no funcionó, así que tuve que ir al paso 2.

También intenté eliminar el paquete nodemailer-smtp-transport y, para mi sorpresa, funciona. pero luego, cuando reinicié mi sistema, me dio el mismo error, así que tuve que ir y encender la aplicación menos segura (la deshabilité después de mi trabajo).

Luego, por diversión, lo probé con apagado (aplicación menos segura) y ¡funcionó de nuevo!

Zaheen
fuente
1
Los pasos 1 y 2 fueron muy útiles. ¡gracias! Probé el paso 1 antes de ver su solución y no funcionó, pero con el paso 2 es mágico
MissStack
"smptTransport no es una función"
JWiley
Intenté con las dos formas que compartiste con nosotros, pero recibo el mismo error una y otra vez {Error: connect ETIMEDOUT 74.125.68.108:465 en TCPConnectWrap.afterConnect [as oncomplete] (net.js: 1097: 14) errno: ' ETIMEDOUT ', código:' ECONNECTION ', syscall:' connect ', address: '74 .125.68.108', port: 465, command: 'CONN'}
Anwar Hussain
@AnwarHussain: También obtengo el mismo error otra vez
Pappa S
42

Debes usar un token XOAuth2 para conectarte a Gmail. No se preocupe, Nodemailer ya lo sabe:

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

Deberá ir a Google Cloud Console para registrar su aplicación. Luego, debe recuperar los tokens de acceso para las cuentas que desea usar. Puedes usar passportjs para eso.

Así es como se ve en mi 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
fuente
9
¿Existe una solución más sencilla para enviar un correo electrónico en NodeJS con una cuenta de GMail?
tonymx227
¿Puede explicar qué hace passport.authorize y por qué necesita alcance, callbackurl y demás, por qué no puede hacerlo simplemente con clientId & secret?
Ismail
passport.authorizees similar a passport.authenticateexcepto que no intenta actualizar la sesión actual. Debe aprobar callbackURLporque después del apretón de manos de OAuth, Google necesita saber dónde redirigir al usuario para que se complete el apretón de manos.
Laurent Perrin
14

Funcionó bien:

1- instale nodemailer , paquete si no está instalado (escriba cmd):npm install nodemailer

2- vaya a https://myaccount.google.com/lesssecureapps y active Permitir aplicaciones menos seguras .

3- escribir 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- ¡disfruta!

Mohammad Masoudzadeh
fuente
11

También me pasó el mismo problema. Probé mi sistema en localhost y luego lo implementé en el servidor (que se encuentra en un país diferente) y luego, cuando probé el sistema en el servidor de producción, vi este error. Probé estos para solucionarlo:

  1. https://www.google.com/settings/security/lesssecureapps Lo habilité pero no fue mi solución
  2. https://g.co/allowaccess Permití el acceso desde afuera por un tiempo limitado y esto resolvió mi problema.
Ahmet Can Güven
fuente
2
El enlace g.co/allowaccess fue lo que lo solucionó (ya había habilitado lesssecureapps). ¡Gracias!
10

Para mí, está trabajando de esta manera, usando el puerto y la seguridad (tuve problemas para enviar correos electrónicos desde gmail usando PHP sin configuraciones de seguridad)

Espero ayudar a alguien.

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 las configuraciones se enumeran aquí (incluidos los ejemplos)

Ángel M.
fuente
10

Ninguna de las soluciones anteriores funcionó para mí. Usé el código que existe en la documentación de NodeMailer . Se parece a esto:

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
fuente
gracias amigo ! :) thissss ---> host: 'smtp.gmail.com', puerto: 465, seguro: verdadero, funcionó para mí
Praveen Vishnu
@PraveenVishnu No hay problema, si vota a favor de esta respuesta, más personas la verán. También podría ayudarlos.
Hamid
hola, sé que este ya es antiguo, pero ¿te importaría de dónde sacaste serviceClient, privateKey y accessToken? Gracias.
Aljohn Yamaro
@AljohnYamaro El servicio de correo se lo proporcionará. En mi caso fue Gmail. Puede leer más aquí: stackoverflow.com/questions/36214968/…
Hamid
9

Encontré el método más simple, descrito en este artículo mencionado en la respuesta de Greg T , era crear una contraseña de aplicación que está disponible después de activar 2FA para la cuenta.

myaccount.google.com> Inicio de sesión y seguridad> Iniciar sesión en Google> Contraseñas de aplicaciones

Esto le da una contraseña alternativa para la cuenta, luego configura nodemailer como un servicio SMTP normal.

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

Si bien Google recomienda Oauth2 como la mejor opción, este método es fácil y aún no se ha mencionado en esta pregunta.

Consejo adicional: también descubrí que puede agregar el nombre de su aplicación a la dirección "de" y GMail no lo reemplaza solo con el correo electrónico de la cuenta como lo hace si intenta usar otra dirección. es decir.

from: 'My Pro App Name <[email protected]>'
scipilot
fuente
Siempre usando this1. Debe configurar la autenticación de fábrica 2 para configurar la contraseña de la aplicación. Frente a menos seguro.
gdfgdfg
8

Se resuelve usando el 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
fuente
4

Si usa Express, se express-mailerenvuelve nodemailermuy bien y es muy 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
fuente
4

todo su código está bien, solo lo que queda es solo ir al enlace https://myaccount.google.com/security

y siga desplazándose hacia abajo y encontrará Permitir aplicaciones menos seguras: ON y mantenga ON, no encontrará ningún error.

Y. Joy Ch. Singha
fuente
4

Por alguna razón, solo permitir la configuración de la aplicación menos segura no funcionó para mí, incluso el captcha. Tuve que hacer otro paso que habilita la configuración de IMAP:

Desde la página de ayuda de Google: https://support.google.com/mail/answer/7126229?p=WebLoginRequired&visit_id=1-636691283281086184-1917832285&rd=3#cantsignin

  • En la esquina superior derecha, haz clic en Configuración Configuración.
  • Haz clic en Configuración.
  • Haga clic en la pestaña Reenvío y POP / IMAP.
  • En la sección "Acceso IMAP", seleccione Habilitar IMAP.
  • Haga clic en Guardar cambios.
mel3kings
fuente
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)
  });
});
}

Debe agregar el tipo de conexión segura en su código.

aaditya
fuente
2

Estaba usando una versión anterior de nodemailer 0.4.1 y tuve este problema. Actualicé a 0.5.15 y todo está funcionando bien ahora.

Paquete.json editado para reflejar los cambios luego

npm install
usuario1071182
fuente
3
Es mejor hacer una actualización npm para ese caso. Si desea saber más sobre cómo la actualización de npm y la instalación de npm son diferentes, consulte esta respuesta - stackoverflow.com/questions/12478679/…
Anthony Akentiev
2

Solo asista a los siguientes: 1- La autenticación de Gmail para permitir correos electrónicos de bajo nivel no acepta antes de reiniciar el navegador de su cliente 2- Si desea enviar un correo electrónico con nodemailer y no desea usar el protocolo xouath2 allí, debe escribir como conexión segura: falso como a continuación

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
fuente
smtpTransport se usa dos veces, ¿cuál es qué?
Biranchi
Realmente es muy claro El primero es para crear configuraciones de smtpTransport y el segundo para enviar correo usando esta configuración funciona perfectamente en firebase hoy en día
Hamit YILDIRIM
2

primera instalación de nodemailer

npm install nodemailer  --save

importar al archivo 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");
        }
    });

trabajando en mi aplicación

arul mb
fuente