Phoenix's Blog

Node.js | Nodemailer

2019-11-06

Node.js - 透過 Nodemailer 寄送 Email

試著實作一個簡單類似 gmail 信箱寄信的相關功能,且可以讓使用者利用類似 word 的輸入介面來寄信

實作目標

  • 信件可含 HTML 內文
  • 信件可以附加圖片
  • 信件可夾帶檔案

安裝與設定

安裝:

1
npm install --save nodemailer

載入模組設定:mailManager.js

1
const nodemailer = require("nodemailer");

實作

開啟信箱存取權限

開始實做之前,先將 mail 設定的 低安全性應用程式存取權限 打開,這邊以 gmail 為例,先登入自己帳號後,可透過以下連結直接開始做設定,如下圖原先是已關閉 將他打開變成 已開啟

低安全性應用程式存取權限連結

發信服務的相關設定

透過 createTransport 物件設定發信的服務的對象與帳號密碼,這邊以 Gmail 為例,若不是 gmail 也可以透過hostport 設定去修改 ,最後將相關設定存放於.env

mailManager.js:

1
2
3
4
5
6
7
let transporter = nodemailer.createTransport({
host: process.env.MAIL_HOST ,
auth: {
user: process.env.MAIL_USER,
pass: process.env.MAIL_PASSWORD
}
});

.env:

1
2
3
MAIL_USER = abc@gmail.com
MAIL_PASSWORD = 123456789
MAIL_HOST = smtp.gmail.com

傳送 HTML 內文並寄信

透過 html 參數寫入 html 格式內文,透過 sendMail 方法寄出信件

mailManager.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 mailOption = {
from: process.env.MAIL_USER, //寄件者
to: 'Andy <andy@gmail.com>', //收件者
subject: 'Hey~', // 主旨
html:'<b>Test mail </b>', // html 內文
attachments: []// 夾帶檔案,後面說明
}

transporter.sendMail(mailOption,function(error, info) {//寄信方法
if (error) {
return console.log(error);
} else {
console.log("訊息已發送: " + info.response);
}
});

信件可夾帶檔案

透過 attachments 參數設定夾帶的檔案

1
2
3
4
5
6
7
8
9
10
11
12
13
mailOption = {
from: process.env.MAIL_USER, //寄件者
to: 'Andy <andy@gmail.com>', //收件者
subject: 'Hey~', // 主旨
html:'<b>Test mail </b>', // html 內文
attachments: [ {
filename: 'abc.jpg',
path: '/aa/xx/abc.jpg'
},{
filename: 'def.jpg',
path: '/aa/xx/def.jpg'
}...]
}

加入線上編輯器 - summernote

基本上上面已經達到寄信功能,但希望讓使用者上能透過線上編輯器直接讓使用者在上方修改自己喜歡的樣式,類似 word 來編輯背後幫你轉成 html 格式與樣式,所以這邊就透過 summernote 來完成線上編輯的功能

summernote 連結

設定與實作

1
2
3
4
5
6
<link href="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.12/summernote-bs4.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.12/summernote-bs4.js">

<script>
$('#summernote').summernote();
</script>

html:

1
<textarea id="summernote" name="editordata"></textarea>

點選右上角的 summernote 裡的</>(code view) 就可即時看到目前使用者所輸入轉換成 html 和 css 的內容,就可以將使用者輸入的內容傳送到 Nodemailer 的 html 裡

html 內文夾帶圖片

直接利用summernote 裡的picture 插入圖片後並寄信試試看, mail 收到後卻沒有圖片?

mail:

利用nodemailer-plugin-inline-base64 套件解決這個問題,該套件可以將 base64 編碼圖像轉換成 mail 附件的形式(CID-referenced),但不讓圖片出現在附件裡.

連結:nodemailer-plugin-inline-base64

以 cid 方式設定為例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var mailOpt = {
from: 'XXX@gmail.com',
to: 'XXX@gmail.com',
....

html: '<b>Hello world</b>,img11:<img src="cid:test_cid"><br/>img22:<img src="cid:test_cid2">', // html body
attachments : [{
filename: 'p1.png',
path: './p1.png',
cid: 'test_cid'
},{
filename: 'v1.png',
path: './v1.png',
cid: 'test_cid2'
}],

安裝:

npm install --save nodemailer-plugin-inline-base64

設定與實作:

1
2
3
4
5
6
7
8
9
10
const inlineBase64 = require('nodemailer-plugin-inline-base64');

transporter.use('compile', inlineBase64({cidPrefix: 'somePrefix_'})); //加入
transporter.sendMail(mailOption,function(error, info) {
if (error) {
return console.log(error);
} else {
console.log("訊息已發送: " + info.response);
}
});

實作結果

這邊實作一個簡單寄信的界面,能夠在頁面上輸入信件內容與上傳檔案:

實際收到信件內容:

github 連結:https://github.com/Phxww/mail-manager

參考: