Node.js: 使用 Nodemailer 傳送 Email

使用 Nodemailer 來傳送 Email。文件可參考 Nodemailer

安裝與設定 nodemailer

npm install --save nodemailer

在 app.js 載入模組並設定使用的服務、帳號、密碼。這裡使用方便的 Gmail。

var nodemailer = require('nodemailer');

var mailTransport = nodemailer.createTransport('SMTP', {
  service: 'Gmail',
  auth: {
    user: credentials.gmail.user,
    pass: credentials.gmail.password,
  },
});

或需要直接連到 SMTP 伺服器,也是可以的。

var mailTransport = nodemailer.createTransport('SMTP', {
  host: 'smtp.mailservice.com',
  secureConnecton: true,
  port: 587,
  auth: {
    user: credentials.mailservice.user,
    pass: credentials.mailservice.pass,
  },
});

更新 credentials.js 檔案。我們將帳號與密碼這種敏感資訊放在 credentials 裡面。

module.exports = {
  cookieSecret: 'your cookie secret goes here',
  gmail: {
    user: 'user name',
    pass: 'password here...',
  },
};

然後下指令 npm start 就可以傳送 Email 了。

Demo

收到信了~

Node - 使用Nodemailer傳送Email

傳送 HTML Email

我們使用 html 欄位裝載 HTML Email。

mailTransport.sendMail(
  {
    from: 'Meadowlark Travel <cythilya@gmail.com>',
    to: 'Cythilya <cythilya@gmail.com>',
    subject: 'Hi :)',
    html: '<h1>Hello</h1><p>Nice to meet you.</p>',
  },
  function(err) {
    if (err) {
      console.log('Unable to send email: ' + err);
    }
  },
);

Demo

Node - 使用Nodemailer傳送Email

使用 View 來傳送 HTML Email

準備一個 HTML 樣版 - cart-thank-you.handlebars

我們將電子報的內容製成樣版,之後再從 Server 端取資料套版。

<body>
  <h1>Thank You!</h1>
  <p>Hi, .{.{ cart.name }.}.</p>
  <p>Thank you for booking your trip with Meadowlark Travel.</p>
</body>

備註:由於部落格會把花括號吃掉,因此在左右加一個點,例如「.{.{ }.}.」。

送出信件

送出表單後,會寄一封信到信箱。(備註:這邊都是做範例練習用的,所以不要計較為何使用訂閱電子報的表單,卻收到購物車相關的信件 XD)

var mailTransport = nodemailer.createTransport({
  service: 'Gmail',
  auth: {
    user: credentials.gmail.user,
    pass: credentials.gmail.pass,
  },
});

app.post('/newsletter', function(req, res) {
  var name = req.body.name || '',
    email = req.body.email;

  var cart = {
    name: name,
    email: email,
  };

  res.render(
    'email/cart-thank-you',
    {
      layout: null,
      cart: cart,
    },
    function(err, html) {
      if (err) {
        console.log('error in email template');
      }
      mailTransport.sendMail(
        {
          from: '"Meadowlark Travel": cythilya@gmail.com',
          to: email,
          subject: 'Thank You for Book your Trip with Meadowlark',
          html: html,
        },
        function(err) {
          if (err) {
            console.error('Unable to send confirmation: ' + err.stack);
          }
        },
      );
    },
  );

  res.render('cart-thank-you', {
    cart: cart,
  });

  return res.redirect(303, '/thankyou');
});

Demo

Node - 使用Nodemailer傳送Email

封裝 Email 功能

封裝成一支 javascript 檔案 - email.js

var nodemailer = require('nodemailer');

module.exports = function(credentials) {
  var mailTransport = nodemailer.createTransport('SMTP', {
    service: 'Gmail',
    auth: {
      user: credentials.gmail.user,
      pass: credentials.gmail.pass,
    },
  });
  var from = '"Meadowlark Travel" <cythilya@gmail.com>';
  var errorRecipient = 'cythilya@gmail.com';
  return {
    send: function(to, subj, body) {
      mailTransport.sendMail(
        {
          from: 'Meadowlark Travel <cythilya@gmail.com>',
          to: 'Cythilya <cythilya@gmail.com>',
          subject: 'Hi :)',
          html: '<h1>Hello</h1><p>Nice to meet you.</p>',
        },
        function(err) {
          if (err) {
            console.log('Unable to send email: ' + err);
          }
        },
      );
    },
    emailError: function(message, filename, exception) {
      var body =
        '<h1>Meadowlark Travel Site Error</h1>' + 'message:<br><pre>' + message + '</pre><br>';
      if (exception) body += 'exception:<br><pre>' + exception + '</pre><br>';
      if (filename) body += 'filename:<br><pre>' + filename + '</pre><br>';
      mailTransport.sendMail(
        {
          from: from,
          to: errorRecipient,
          subject: 'Meadowlark Travel Site Error',
          html: body,
          generateTextFromHtml: true,
        },
        function(err) {
          if (err) {
            console.log('Unable to send email: ' + err);
          }
        },
      );
    },
  };
};

使用這個封裝檔案

var emailService = require('./lib/email.js')(credentials);
emailService.send(
  'cythilya@gmail.com',
  'Hood River tours on sale today!',
  "Get 'em while they're hot!",
);

把 Email 當成網站監控工具

假設網站有任何問題,我們都可以寄一封信來通知…

if (err) {
  email.sendError('the widget broke down!', __filename);
  // ... display error message to user
}

或…

try {
  // do something iffy here....
} catch (ex) {
  email.sendError('the widget broke down!', __filename, ex);
  // ... display error message to user
}

但這不是代替 log 的方法,之後會再討論相關議題。

相關閱讀


這篇文章的原始位置在這裡-Node - 使用 Nodemailer 傳送 Email

由於部落格搬遷至此,因此在這裡放了一份,以便閱讀;部份文章片段也做了些許修改,以期提供更好的內容。

node.js