Nodemailer z Gmailem i NodeJS


110

Próbuję użyć Nodemailer do zaimplementowania formularza kontaktowego za pomocą NodeJS, ale działa tylko na lokalnym, nie działa na zdalnym serwerze ...

Mój komunikat o błędzie:

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

Mój kontroler:

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 (ze względu na widoczność, zamieszczone przez dobrego komentatora poniżej). Po prostu zezwól na dostęp raz i pozwól nodemailerowi zalogować się automatycznie.
laggingreflex

3
Po wypróbowaniu wszystkiego, aby wysłać pocztę przez Gmaila przy użyciu Nodemailer, następujące ustawienie zadziałało ...
faizanjehangir

Odpowiedzi:


136

Rozwiązałem to, przechodząc do następującego adresu URL (podczas połączenia z Google z kontem, z którego chcę wysyłać pocztę):

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

Tam włączyłem mniej bezpieczne aplikacje.

Gotowe


1
Dobra robota! działa, chociaż nie sądzę, żeby to był najlepszy pomysł ... Otrzymałem pierwszego e
maila ..

bez umożliwienia tego nie będzie działać nawet w środowisku lokalnym. wyraźnie wspomniał, że działa w środowisku lokalnym i nie działa na zdalnym serwerze. jakie jest rozwiązanie dla tego?
Adithya Sai,

to nie pomoże, jeśli masz uwierzytelnianie 2FA na swoim koncie Gmail
sasha romanov

64

Zobacz oficjalny przewodnik firmy Nodemailer dotyczący łączenia się z Gmailem:

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

-

Działa dla mnie po zrobieniu tego:

  1. Włącz mniej bezpieczne aplikacje - https://www.google.com/settings/security/lesssecureapps
  2. Wyłącz tymczasowo Captcha, aby móc podłączyć nowe urządzenie / serwer - https://accounts.google.com/b/0/displayunlockcaptcha

19
Numer 2 rozwiązał moje problemy. Nie udało mi się znaleźć tego linku w ustawieniach kont Google. Dziękuję Ci!
programista

1
To samo tutaj. Wcześniej zrobiłem numer 1 i otrzymałem e-maile pracujące na hoście lokalnym, przeniosłem się do produkcji i nic nie działało. # 2 naprawił mój problem z produkcją. Dziękuję
John

49

Łatwe rozwiązanie:

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

Krok 1:

przejdź tutaj https://myaccount.google.com/lesssecureapps i włącz dla mniej bezpiecznych aplikacji. Jeśli to nie zadziała, to

Krok 2

przejdź tutaj https://accounts.google.com/DisplayUnlockCaptcha i włącz / kontynuuj, a następnie spróbuj.

dla mnie sam krok 1 nie zadziałał, więc musiałem przejść do kroku 2.

próbowałem również usunąć pakiet nodemailer-smtp-transport i ku mojemu zaskoczeniu działa. ale kiedy ponownie uruchomiłem system, dostałem ten sam błąd, więc musiałem iść i włączyć mniej bezpieczną aplikację (wyłączyłem ją po pracy).

potem dla zabawy po prostu wypróbowałem to z wyłączoną (mniej bezpieczną aplikacją) i vola znowu zadziałało!


1
Krok 1 i 2 były bardzo pomocne. Dziękuję Ci! Wypróbowałem krok 1, zanim zobaczyłem twoje rozwiązanie, i nie zadziałało, ale w kroku 2 to magia!
MissStack

„smptTransport nie jest funkcją”
JWiley

Próbowałem z obydwoma sposobami, w jakie nam udostępniłeś, ale ciągle otrzymuję ten sam błąd {Błąd: podłącz ETIMEDOUT 74.125.68.108:465 do TCPConnectWrap.afterConnect [as oncomplete] (net.js: 1097: 14) errno: ' ETIMEDOUT ', kod:' ECONNECTION ', wywołanie systemowe:' connect ', adres: '74 .125.68.108', port: 465, polecenie: 'CONN'}
Anwar Hussain

@AnwarHussain: Ja też znowu otrzymuję ten sam błąd
Pappa S,

42

Należy użyć XOAuth2 żeton do łączenia się z Gmailem. Bez obaw, Nodemailer już o tym wie:

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

Aby zarejestrować swoją aplikację, musisz przejść do Google Cloud Console . Następnie musisz odzyskać tokeny dostępu dla kont, których chcesz używać. Możesz do tego użyć paszportjs .

Oto jak to wygląda w moim kodzie:

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
Czy istnieje łatwiejsze rozwiązanie do wysyłania wiadomości e-mail w NodeJS z kontem GMail?
tonymx227


Czy możesz wyjaśnić, co robi passport.authorize i dlaczego potrzebujesz zakresu, callbackurl i tym podobnych, dlaczego nie możesz tego zrobić po prostu z clientId & secret?
Ismail,

passport.authorizejest podobny do passport.authenticatetego, że nie próbuje zaktualizować bieżącej sesji. Musisz przejść, callbackURLponieważ po uzgodnieniu OAuth Google musi wiedzieć, gdzie przekierować użytkownika, aby uzgadnianie zostało zakończone.
Laurent Perrin


15

Działa dobrze:

1- zainstaluj nodemailer , pakiet, jeśli nie jest zainstalowany (wpisz cmd):npm install nodemailer

2- Wejdź na https://myaccount.google.com/lesssecureapps i włącz Zezwalaj na mniej bezpieczne aplikacje .

3- wpisz kod:

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- Baw się dobrze!


11

Mnie też przydarzył się ten sam problem. Przetestowałem swój system na hoście lokalnym, a następnie wdrożyłem go na serwer (który znajduje się w innym kraju), a następnie, gdy próbowałem system na serwerze produkcyjnym, zobaczyłem ten błąd. Próbowałem to naprawić:

  1. https://www.google.com/settings/security/lesssecureapps Włączone, ale nie było to moje rozwiązanie
  2. https://g.co/allowaccess Pozwoliłem na dostęp z zewnątrz przez ograniczony czas i to rozwiązało mój problem.

2
G.co/allowaccess związek właśnie stała się dla mnie (było już włączone lesssecureapps) - dzięki!

10

U mnie działa w ten sposób, używając portu i zabezpieczeń (miałem problemy z wysyłaniem e-maili z Gmaila przy użyciu PHP bez ustawień zabezpieczeń)

Mam nadzieję, że komuś pomogę.

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

wszystkie konfiguracje są tutaj wymienione (w tym przykłady)


10

Żadne z powyższych rozwiązań nie zadziałało. Użyłem kodu, który istnieje w dokumentacji NodeMailer . To wygląda tak:

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

Dzięki stary ! :) thissss ---> host: „smtp.gmail.com”, port: 465, secure: true, Worked for Me
Praveen Vishnu,

@PraveenVishnu Nie ma problemu, jeśli zagłosujesz za tą odpowiedzią, więcej osób ją zobaczy. To też może im pomóc.
Hamid,

Cześć, wiem, że to już stara, ale czy nie miałbyś nic przeciwko, skąd masz serviceClient, privateKey i accessToken? Dziękuję Ci.
Aljohn Yamaro

@AljohnYamaro Usługa pocztowa to zapewni. W moim przypadku był to Gmail. Możesz przeczytać więcej tutaj: stackoverflow.com/questions/36214968/…
Hamid


9

Odkryłem, że najprostszą metodą, opisaną w tym artykule wymienionym w odpowiedzi Grega T. , było utworzenie hasła do aplikacji, które jest dostępne po włączeniu 2FA dla konta.

myaccount.google.com> Logowanie i bezpieczeństwo> Logowanie do Google> Hasła do aplikacji

To daje alternatywne hasło do konta, a następnie konfigurujesz nodemailer jako normalną usługę SMTP.

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

Chociaż Google zaleca Oauth2 jako najlepszą opcję, ta metoda jest łatwa i nie została jeszcze wspomniana w tym pytaniu.

Dodatkowa wskazówka: odkryłem również, że możesz dodać nazwę swojej aplikacji do adresu „nadawcy”, a Gmail nie zastępuje go tylko adresem e-mail konta, jak ma to miejsce w przypadku próby użycia innego adresu. to znaczy.

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

Zawsze używam tego 1. Aby ustawić hasło aplikacji, musisz ustawić 2-fabryczne uwierzytelnianie. Naprzeciwko mniej bezpieczne.
gdfgdfg

8

Rozwiązuje się go za pomocą nodemailer-smtp-transportmodułu wewnątrz createTransport.

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

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

4

Jeśli używasz Expressu, bardzo ładnie się express-mailerowija nodemaileri jest bardzo łatwy w użyciu:

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

Z jakiegoś powodu samo zezwolenie na mniej bezpieczną konfigurację aplikacji nie działało dla mnie, nawet w przypadku captcha. Musiałem zrobić kolejny krok, który włącza konfigurację IMAP:

Ze strony pomocy Google: https://support.google.com/mail/answer/7126229?p=WebLoginRequired&visit_id=1-636691283281086184-1917832285&rd=3#cantsignin

  • W prawym górnym rogu kliknij Ustawienia Ustawienia.
  • Kliknij opcję Ustawienia.
  • Kliknij kartę Przekazywanie i POP / IMAP.
  • W sekcji „Dostęp IMAP” wybierz Włącz IMAP.
  • Kliknij Zapisz zmiany.

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

Musisz dodać typ secureConnection w swoim kodzie.


2

Używałem starej wersji Nodemailer 0.4.1 i miałem ten problem. Zaktualizowałem do wersji 0.5.15 i teraz wszystko działa dobrze.

Edytowano plik package.json, aby odzwierciedlić zmiany

npm install

3
Lepiej jest zrobić aktualizację npm dla tego przypadku. Jeśli chcesz dowiedzieć się więcej o tym, w jaki sposób aktualizacja npm i npm instalują się inaczej - zapoznaj się z tą odpowiedzią - stackoverflow.com/questions/12478679/…
Anthony Akentiev

2

Po prostu weź udział w tych: 1- Uwierzytelnianie Gmaila dla zezwalania na e-maile niskiego poziomu nie jest akceptowane przed ponownym uruchomieniem przeglądarki klienta 2- Jeśli chcesz wysyłać e-maile za pomocą nodemailer i nie chcesz tam używać protokołu xouath2, napisz jako bezpieczne połączenie: false jak poniżej

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 jest używany dwukrotnie, który z nich jest czym?
Biranchi

Naprawdę jest to bardzo jasne Pierwsze z nich dotyczy tworzenia ustawień smtpTransport, a drugie do wysyłania poczty przy użyciu tych ustawień, które teraz działają doskonale w firebase
Hamit YILDIRIM

2

najpierw zainstaluj nodemailer

npm install nodemailer  --save

zaimportować do pliku 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");
        }
    });

pracuje w mojej aplikacji

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.