Nodemailer với Gmail và NodeJS


110

Tôi cố gắng sử dụng gật đầu để triển khai biểu mẫu liên hệ bằng NodeJS nhưng nó chỉ hoạt động trên cục bộ, nó không hoạt động trên máy chủ từ xa ...

Thông báo lỗi của tôi:

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

Bộ điều khiển của tôi:

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 (để hiển thị, được đăng bởi người bình luận tốt ở bên dưới). Chỉ cần cho phép truy cập một lần và để cho gật đầu đăng nhập tự động, nó sẽ làm được.
laggingreflex

3
Sau khi thử tất cả mọi thứ để gửi mail qua gmail sử dụng nodemailer, các thiết lập sau đây làm việc cho tôi ..
faizanjehangir

Câu trả lời:


136

Tôi đã giải quyết vấn đề này bằng cách truy cập url sau (trong khi được kết nối với google bằng tài khoản tôi muốn gửi thư từ đó):

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

Ở đó, tôi đã bật các ứng dụng kém an toàn hơn.

Làm xong


1
Làm tốt! nó đang làm việc, mặc dù tôi không nghĩ rằng đó là ý tưởng tốt nhất ... Tôi đã email..Thx đầu tiên của tôi
ackuser

nếu không bật tính năng này, nó thậm chí sẽ không hoạt động trong môi trường cục bộ. ông đã đề cập rõ ràng rằng nó đang hoạt động trong môi trường cục bộ và không hoạt động trên máy chủ từ xa. giải pháp cho thaat là gì?
Adithya Sai

này không thể giúp bạn nếu bạn có 2FA auth trong tài khoản gmail của bạn
sasha Romanov

63

Xem hướng dẫn chính thức của gật đầu để kết nối Gmail:

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

-

Nó hoạt động cho tôi sau khi làm điều này:

  1. Bật các ứng dụng kém an toàn hơn - https://www.google.com/settings/security/lesssecureapps
  2. Tạm thời tắt Captcha để bạn có thể kết nối thiết bị / máy chủ mới - https://accounts.google.com/b/0/displayunlockcaptcha

18
Số 2 đã giải quyết tai ương của tôi. Tôi không thể tìm thấy liên kết đó ở bất kỳ đâu trong cài đặt tài khoản của google. Cảm ơn bạn!
chương trình

1
Ở đây cũng vậy. Trước đây tôi đã làm # 1 và nhận được email hoạt động trên localhost, chuyển sang sản xuất và không có gì hoạt động. # 2 đã khắc phục sự cố của tôi để sản xuất. Cảm ơn bạn
John

49

Giải pháp dễ dàng:

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

Bước 1:

vào đây https://myaccount.google.com/lesssecureapps và bật các ứng dụng kém an toàn hơn. Nếu điều này không hoạt động thì

Bước 2

truy cập vào đây https://accounts.google.com/DisplayUnlockCaptcha và bật / tiếp tục rồi thử.

đối với tôi bước 1 không hoạt động nên tôi phải chuyển sang bước 2.

Tôi cũng đã thử gỡ bỏ gói dịch vụ-smtp-chuyển đổi và thật ngạc nhiên là nó hoạt động. nhưng sau đó khi tôi khởi động lại hệ thống của mình, nó vẫn cho tôi một lỗi tương tự, vì vậy tôi phải bật ứng dụng kém an toàn hơn (tôi đã tắt nó sau khi làm việc).

sau đó để cho vui, tôi chỉ thử nó khi tắt (ứng dụng kém an toàn hơn) và vola nó hoạt động trở lại!


1
Bước 1 và 2 rất hữu ích. cảm ơn bạn! Tôi đã thử bước1 trước khi tôi thấy giải pháp của bạn và không hiệu quả nhưng với bước 2, đó là một điều kỳ diệu!
MissStack

"smptTransport không phải là một chức năng"
JWiley

Tôi đã thử với cả hai cách mà bạn đã chia sẻ với chúng tôi nhưng tôi lại gặp phải lỗi tương tự {Error: connect ETIMEDOUT 74.125.68.108:465 tại TCPConnectWrap. AfterConnect [as oncomplete] (net.js: 1097: 14) errno: ' ETIMEDOUT ', mã:' ECONNECTION ', syscall:' connect ', địa chỉ: '74 .125.68.108', port: 465, command: 'CONN'}
Anwar Hussain

@AnwarHussain: Tôi cũng gặp lỗi tương tự một lần nữa
Pappa S

42

Bạn nên sử dụng mã thông báo XOAuth2 để kết nối với Gmail. Đừng lo lắng, Nodemailer đã biết về điều đó:

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

Bạn sẽ cần truy cập Google Cloud Console để đăng ký ứng dụng của mình. Sau đó, bạn cần lấy mã thông báo truy cập cho tài khoản bạn muốn sử dụng. Bạn có thể sử dụng passportjs cho việc đó.

Đây là cách nó trông như thế nào trong mã của tôi:

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
Có giải pháp nào dễ dàng hơn để gửi Email trong NodeJS bằng tài khoản GMail không?
tonymx227,


bạn có thể giải thích passport.authorize làm gì và tại sao bạn cần scope, callbackurl, v.v., tại sao bạn không thể làm điều đó với clientId & secret?
Ismail

passport.authorizetương tự như passport.authenticatengoại trừ việc nó không cố gắng cập nhật phiên hiện tại. Bạn cần phải vượt qua callbackURLvì sau khi bắt tay OAuth, Google cần biết nơi chuyển hướng người dùng để quá trình bắt tay được hoàn tất.
Laurent Perrin


14

Làm việc tốt:

1- cài đặt nút , gói nếu chưa được cài đặt (gõ cmd):npm install nodemailer

2- truy cập https://myaccount.google.com/lesssecureapps và bật Cho phép ứng dụng kém an toàn hơn .

3- viết mã:

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- tận hưởng!


11

Vấn đề tương tự cũng xảy ra với tôi. Tôi đã kiểm tra hệ thống của mình trên localhost sau đó được triển khai đến máy chủ (được đặt ở quốc gia khác), sau đó khi tôi thử hệ thống trên máy chủ sản xuất, tôi đã thấy lỗi này. Tôi đã thử những điều này để sửa nó:

  1. https://www.google.com/settings/security/lesssecureapps Đã bật nó nhưng đó không phải là giải pháp của tôi
  2. https://g.co/allowaccess Tôi đã cho phép truy cập từ bên ngoài trong một thời gian giới hạn và điều này đã giải quyết được vấn đề của tôi.

2
Các g.co/allowaccess liên kết là những gì cố định nó cho tôi (có lesssecureapps đã kích hoạt) - cảm ơn!

10

Đối với tôi đang làm việc theo cách này, sử dụng cổng và bảo mật (tôi gặp sự cố khi gửi email từ gmail bằng PHP mà không có cài đặt bảo mật)

Tôi hy vọng sẽ giúp một ai đó.

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

tất cả cấu hình được liệt kê ở đây (bao gồm cả các ví dụ)


10

Không phải các giải pháp trên đã làm việc cho tôi. Tôi đã sử dụng mã tồn tại trong tài liệu của NodeMailer . Nó trông như thế này:

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

cảm ơn cậu ! :) thissss ---> host: 'smtp.gmail.com', cổng: 465, an toàn: đúng, làm việc cho tôi
Praveen Vishnu

@PraveenVishnu Không sao, nếu bạn bỏ phiếu cho câu trả lời này, nhiều người sẽ thấy nó hơn. Nó cũng có thể giúp họ.
Hamid

chào bạn, tôi biết cái này đã cũ rồi, nhưng bạn có phiền bạn lấy serviceClient, privateKey và accessToken ở đâu không? Cảm ơn bạn.
Aljohn Yamaro

@AljohnYamaro Dịch vụ thư sẽ cung cấp. Trong trường hợp của tôi, đó là Gmail. Bạn có thể đọc thêm tại đây: stackoverflow.com/questions/36214968/…
Hamid


9

Tôi đã tìm thấy phương pháp đơn giản nhất, được mô tả trong bài viết này được đề cập trong câu trả lời của Greg T , là tạo Mật khẩu ứng dụng khả dụng sau khi bật 2FA cho tài khoản.

myaccount.google.com> Đăng nhập và bảo mật> Đăng nhập vào Google> Mật khẩu ứng dụng

Điều này cung cấp cho bạn một mật khẩu thay thế cho tài khoản, sau đó bạn chỉ cần định cấu hình gật đầu như một dịch vụ SMTP bình thường.

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

Mặc dù Google khuyến nghị Oauth2 là lựa chọn tốt nhất, nhưng phương pháp này rất dễ dàng và chưa được đề cập trong câu hỏi này.

Mẹo bổ sung: Tôi cũng thấy rằng bạn có thể thêm tên ứng dụng của mình vào địa chỉ "từ" và GMail không thay thế nó chỉ bằng email tài khoản giống như cách làm nếu bạn cố gắng sử dụng một địa chỉ khác. I E.

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

Luôn sử dụng điều này1. Bạn cần đặt xác thực 2 gốc để đặt mật khẩu ứng dụng. Ngược lại trên kém an toàn.
gdfgdfg

8

Nó được giải quyết bằng cách sử dụng nodemailer-smtp-transportmô-đun bên trong createTransport.

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

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

4

Nếu bạn sử dụng Express, express-mailerkết thúc nodemailerrất đẹp và rất dễ sử dụng:

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

tất cả mã của bạn đều ổn chỉ còn lại mọi thứ là truy cập vào liên kết https://myaccount.google.com/security

và tiếp tục cuộn xuống và bạn sẽ thấy Cho phép ứng dụng kém an toàn hơn: BẬT và tiếp tục BẬT, bạn sẽ không tìm thấy lỗi.



4

Vì một số lý do, việc chỉ cho phép cấu hình ứng dụng kém an toàn hơn đã không hoạt động đối với tôi, ngay cả với hình ảnh xác thực. Tôi đã phải thực hiện một bước khác là bật cấu hình IMAP:

Từ trang trợ giúp của google: https://support.google.com/mail/answer/7126229?p=WebLoginRequired&visit_id=1-636691283281086184-1917832285&rd=3#cantsignin

  • Ở trên cùng bên phải, nhấp vào Cài đặt Cài đặt.
  • Nhấp vào Cài đặt.
  • Nhấp vào tab Chuyển tiếp và POP / IMAP.
  • Trong phần "Truy cập IMAP", chọn Bật IMAP.
  • Nhấp vào Lưu thay đổi.

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

Bạn phải thêm loại secureConnection trong mã của bạn.


2

Tôi đang sử dụng phiên bản cũ của gật đầu 0.4.1 và gặp sự cố này. Tôi đã cập nhật lên 0.5.15 và mọi thứ hiện đang hoạt động tốt.

Đã chỉnh sửa package.json để phản ánh các thay đổi sau đó

npm install

3
Tốt hơn là thực hiện cập nhật npm cho trường hợp đó. Nếu bạn muốn biết thêm về cách cập nhật NPMNPM cài đặt khác nhau - thì hãy xem câu trả lời này - stackoverflow.com/questions/12478679/...
Anthony Akentiev

2

Chỉ cần tham dự những điều đó: 1- Xác thực Gmail cho phép email cấp thấp không chấp nhận trước khi bạn khởi động lại trình duyệt máy khách của mình 2- Nếu bạn muốn gửi email bằng gật đầu và bạn không muốn sử dụng giao thức xouath2 ở đó, bạn nên viết là secureconnection: false như bên dưới

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 được sử dụng hai lần, cái nào là cái gì?
Biranchi

Thực sự nó rất rõ ràng Đầu tiên là để tạo cài đặt smtpTransport và thứ hai để gửi thư bằng cách sử dụng cài đặt này, nó hoạt động hoàn hảo trong firebase bây giờ
Hamit YILDIRIM

2

cài đặt đầu tiên gật đầu

npm install nodemailer  --save

nhập vào tệp 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");
        }
    });

làm việc trong ứng dụng của tôi

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.