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

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


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

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

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!


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

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: '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- ¡disfruta!


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.

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


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: 'user@example.com',
        serviceClient: '113600000000000000000',
        privateKey: '-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBg...',
        accessToken: 'ya29.Xx_XX0xxxxx-xX0X0XxXXxXxXXXxX0x',
        expires: 1484314697598
    }
}); 

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: "username@gmail.com",
        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 <username@gmail.com>'

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

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>



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.

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

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


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

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: '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 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: "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");
        }
    });

trabajando en mi aplicación

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.