Nodemailer con Gmail e NodeJS


110

Provo a utilizzare nodemailer per implementare un modulo di contatto utilizzando NodeJS ma funziona solo in locale non funziona su un server remoto ...

Il mio messaggio di errore:

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

Il mio controller:

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 (per visibilità, pubblicato da un buon commentatore in basso). Consenti l'accesso una sola volta e lascia che nodemailer acceda automaticamente, lo farà.
laggingreflex

3
Dopo aver provato di tutto per inviare posta tramite gmail utilizzando nodemailer, la seguente impostazione ha funzionato per me ..
faizanjehangir

Risposte:


136

Ho risolto il problema andando al seguente URL (mentre ero connesso a google con l'account da cui voglio inviare la posta):

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

Lì ho abilitato app meno sicure.

Fatto


1
Molto bene! funziona, anche se non credo che sia l'idea migliore ... Ho ricevuto la mia prima e-mail
..

senza abilitarlo, non funzionerà nemmeno nell'ambiente locale. ha detto chiaramente che funziona in ambiente locale e non su server remoto. qual è la soluzione per thaat?
Adithya Sai

questo non può aiutarti se hai l'autenticazione 2FA nel tuo account gmail
sasha romanov

63

Vedi la guida ufficiale di nodemailer per connettere Gmail:

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

-

Funziona per me dopo aver fatto questo:

  1. Abilita app meno sicure: https://www.google.com/settings/security/lesssecureapps
  2. Disattiva temporaneamente Captcha in modo da poter connettere il nuovo dispositivo / server - https://accounts.google.com/b/0/displayunlockcaptcha

18
Il numero 2 ha risolto i miei guai. Non sono riuscito a trovare quel collegamento da nessuna parte nelle impostazioni degli account di Google. Grazie!
programmatore

1
Anch'io. In precedenza ho fatto # 1 e ho ricevuto e-mail che funzionavano su localhost, sono passato alla produzione e nulla ha funzionato. # 2 ha risolto il mio problema per la produzione. Grazie
John

49

Soluzione facile:

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:

vai qui https://myaccount.google.com/lesssecureapps e abilita le app meno sicure. Se questo non funziona allora

Passo 2

vai qui https://accounts.google.com/DisplayUnlockCaptcha e abilita / continua e poi prova.

per me il passaggio 1 da solo non ha funzionato, quindi sono dovuto andare al passaggio 2.

Ho anche provato a rimuovere il pacchetto nodemailer-smtp-transport e con mia sorpresa funziona. ma poi quando ho riavviato il mio sistema mi ha dato lo stesso errore, quindi ho dovuto andare ad accendere l'app meno sicura (l'ho disabilitata dopo il mio lavoro).

poi per divertimento l'ho appena provato con off (app meno sicura) e vola ha funzionato di nuovo!


1
I passaggi 1 e 2 sono stati molto utili. grazie! Ho provato il passaggio 1 prima di vedere la tua soluzione e non ha funzionato, ma con il passaggio 2 è una magia!
MissStack

"smptTransport non è una funzione"
JWiley

Ho provato con entrambi nel modo in cui hai condiviso con noi, ma ricevo lo stesso errore ancora e ancora {Error: connect ETIMEDOUT 74.125.68.108:465 su TCPConnectWrap.afterConnect [as oncomplete] (net.js: 1097: 14) errno: ' ETIMEDOUT ", codice:" ECONNECTION ", syscall:" connect ", indirizzo: "74 .125.68.108", porta: 465, comando: "CONN"}
Anwar Hussain

@AnwarHussain: Anch'io ricevo di nuovo lo stesso errore
Pappa S

42

Dovresti utilizzare un token XOAuth2 per connetterti a Gmail. Nessun problema, Nodemailer lo sa già:

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

Dovrai andare alla Google Cloud Console per registrare la tua app. Quindi è necessario recuperare i token di accesso per gli account che si desidera utilizzare. Puoi usare passportjs per questo.

Ecco come appare nel mio codice:

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
Esiste una soluzione più semplice per inviare un'e-mail in NodeJS con un account GMail?
tonymx227


puoi spiegare cosa fa passport.authorize e perché hai bisogno di scope, callbackurl e simili, perché non puoi farlo semplicemente con clientId & secret?
Ismail

passport.authorizeè simile a passport.authenticatetranne per il fatto che non tenta di aggiornare la sessione corrente. Devi passare callbackURLperché dopo l'handshake OAuth, Google deve sapere dove reindirizzare l'utente in modo che l'handshake venga completato.
Laurent Perrin


15

Ha funzionato bene:

1- installa nodemailer , pacchetto se non installato (digita cmd):npm install nodemailer

2- vai su https://myaccount.google.com/lesssecureapps e attiva Consenti app meno sicure .

3- scrivi codice:

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- divertiti!


11

Lo stesso problema è successo anche a me. Ho testato il mio sistema su localhost, quindi l'ho distribuito sul server (che si trova in un paese diverso), quindi quando provo il sistema sul server di produzione ho visto questo errore. Ho provato questi per risolverlo:

  1. https://www.google.com/settings/security/lesssecureapps Abilitato ma non era la mia soluzione
  2. https://g.co/allowaccess Ho consentito l'accesso dall'esterno per un periodo di tempo limitato e questo ha risolto il mio problema.

2
Il link g.co/allowaccess è stato ciò che mi ha risolto (aveva già abilitato lesssecureapps) - grazie!

10

Per me funziona in questo modo, utilizzando la porta e la sicurezza (ho avuto problemi a inviare e-mail da Gmail utilizzando PHP senza impostazioni di sicurezza)

Spero possa aiutare qualcuno.

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

tutte le configurazioni sono elencate qui (inclusi esempi)


10

Nessuna delle soluzioni di cui sopra ha funzionato per me. Ho usato il codice che esiste nella documentazione di NodeMailer . Assomiglia a questo:

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

grazie compagno ! :) thissss ---> host: 'smtp.gmail.com', port: 465, secure: true, Worked for Me
Praveen Vishnu

@PraveenVishnu Nessun problema, se voti questa risposta, più persone la vedranno. Potrebbe aiutare anche loro.
Hamid

ciao, lo so già vecchio, ma ti dispiacerebbe dove hai preso serviceClient, privateKey e accessToken? Grazie.
Aljohn Yamaro

@AljohnYamaro Il servizio di posta lo fornirà. Nel mio caso era Gmail. Puoi leggere di più qui: stackoverflow.com/questions/36214968/…
Hamid


9

Ho trovato il metodo più semplice, descritto in questo articolo menzionato nella risposta di Greg T. , era creare una password per l'app disponibile dopo aver attivato 2FA per l'account.

myaccount.google.com> Accesso e sicurezza> Accesso a Google> Password per le app

Questo ti dà una password alternativa per l'account, quindi devi semplicemente configurare nodemailer come un normale servizio SMTP.

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

Mentre Google consiglia Oauth2 come l'opzione migliore, questo metodo è semplice e non è stato ancora menzionato in questa domanda.

Suggerimento extra: ho anche scoperto che puoi aggiungere il nome della tua app all'indirizzo "da" e GMail non lo sostituisce solo con l'email dell'account come fa se provi a utilizzare un altro indirizzo. vale a dire.

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

Usando sempre questo 1. È necessario impostare l'autenticazione di fabbrica 2 per impostare la password dell'app. Opposto su meno sicuro.
gdfgdfg

8

Viene risolto utilizzando il nodemailer-smtp-transportmodulo all'interno di createTransport.

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

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

4

Se usi Express, express-maileravvolge nodemailermolto bene ed è molto facile da usare:

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

Per qualche motivo, consentire solo una configurazione dell'app meno sicura non ha funzionato per me, nemmeno la cosa del captcha. Ho dovuto fare un altro passaggio che sta abilitando la configurazione IMAP:

Dalla pagina della guida di Google: https://support.google.com/mail/answer/7126229?p=WebLoginRequired&visit_id=1-636691283281086184-1917832285&rd=3#cantsignin

  • In alto a destra, fai clic su Impostazioni Impostazioni.
  • Fare clic su Impostazioni.
  • Fare clic sulla scheda Inoltro e POP / IMAP.
  • Nella sezione "Accesso IMAP", seleziona Abilita IMAP.
  • Fare clic su Salva modifiche.

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

È necessario aggiungere il tipo secureConnection nel codice.


2

Stavo usando una vecchia versione di nodemailer 0.4.1 e ho riscontrato questo problema. Ho aggiornato alla 0.5.15 e ora tutto funziona correttamente.

Package.json modificato per riflettere le modifiche

npm install

3
È meglio eseguire l'aggiornamento npm per quel caso. Se vuoi sapere di più su come aggiornamento NPM e NPM installare diverse - quindi si prega di vedere questa risposta - stackoverflow.com/questions/12478679/...
Anthony Akentiev

2

Attendi solo quelli: 1- L'autenticazione Gmail per consentire le email di basso livello non accetta prima di riavviare il browser del client 2- Se vuoi inviare email con nodemailer e non desideri utilizzare il protocollo xouath2 lì dovresti scrivere come secureeconnection: false come sotto

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 viene utilizzato due volte, quale è cosa?
Biranchi

Davvero è molto chiaro Il primo è per la creazione di impostazioni smtpTransport e il secondo per l'invio di posta utilizzando queste impostazioni funziona perfettamente in Firebase oggigiorno
Hamit YILDIRIM

2

prima installa nodemailer

npm install nodemailer  --save

importare in un file 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");
        }
    });

lavorando nella mia applicazione

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.