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('/');
        }
    });
}
tonymx227
źródło
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

brafdlog
źródło
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
Greg T.
źródło
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: '[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);
  }
});  

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!

Zaheen
źródł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);
      });
  });
};
Laurent Perrin
źródło
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: '[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- Baw się dobrze!

Mohammad Masoudzadeh
źródło
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.
Ahmet Can Güven
źródło
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: '[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);
}

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

Anioł M.
źródło
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: '[email protected]',
        serviceClient: '113600000000000000000',
        privateKey: '-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBg...',
        accessToken: 'ya29.Xx_XX0xxxxx-xX0X0XxXXxXxXXXxX0x',
        expires: 1484314697598
    }
}); 
Hamid
źródło
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: "[email protected]",
        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 <[email protected]>'
scipilot
źródło
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'
    }
}));
Girish Rathod
źródło
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>
malix
źródło
4

cały kod jest w porządku, tylko to, co zostało, to po prostu przejdź do linku https://myaccount.google.com/security

i przewijaj w dół, a znajdziesz Zezwalaj na mniej bezpieczne aplikacje: WŁĄCZ i pozostaw WŁĄCZ, nie znajdziesz żadnego błędu.

Y. Joy Ch. Singha
źródło
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.
mel3kings
źródło
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)
  });
});
}

Musisz dodać typ secureConnection w swoim kodzie.

aaditya
źródło
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
user1071182
źródło
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: '[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
źródło
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: "[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");
        }
    });

pracuje w mojej aplikacji

arul mb
źródło