📧 Node-RED e-mail ノードガイド
📦 パッケージ情報:
- パッケージ名: node-red-node-email
- 種別: Node-RED公式アドオンノード(node-red-nodesコレクション)
- ライセンス: Apache-2.0
- 内部利用ライブラリ: nodemailer
- Node.js要件: v18以上(v3.x以降)
📖 1. 概要
node-red-node-emailは、Node-REDからメールを送信・受信するための公式アドオンノードです。SMTP/IMAP/POP3プロトコルに対応し、IoTアラート通知からメール自動処理まで幅広い用途に利用できます。
パッケージに含まれるノード
📤 e-mail(出力ノード)
SMTPを使ってメールを送信します。HTML形式のメール、添付ファイル付きメールにも対応しています。
📥 e-mail in(入力ノード)
IMAP4またはPOP3でメールを受信し、新着メールをフローに渡します。定期的なポーリングで監視します。
郵便システムに例えると
e-mailノードは「郵便局」のようなものです。
- e-mail(送信)= 窓口から手紙を投函する(SMTPサーバーに依頼)
- e-mail in(受信)= 自分の郵便受けを定期的にチェックする(IMAP/POP3で確認)
inject
→
本文作成
→
e-mail
e-mail in
→
解析処理
→
debug
🔧 2. インストール
方法1: パレットマネージャー(推奨)
- Node-REDエディタのメニュー → パレットの管理
- ノードを追加タブを選択
node-red-node-email を検索
- ノードを追加ボタンをクリック
方法2: コマンドライン
cd ~/.node-red
npm install node-red-node-email
インストール後、Node-REDを再起動するとパレットの「Social」カテゴリにノードが追加されます。
💡 ヒント: Node-RED v2.0以降ではパレットマネージャーからのインストールが最も簡単です。Node-REDの再起動も自動的に処理されます。
📤 3. e-mail(送信)ノード
SMTPプロトコルを使用してメールを送信する出力ノードです。
ノード設定プロパティ
| プロパティ |
型 |
説明 |
| To |
string |
宛先メールアドレス(カンマ区切りで複数指定可) |
| Server |
string |
SMTPサーバーのホスト名(例: smtp.gmail.com) |
| Port |
number |
SMTPポート番号(465: SSL, 587: STARTTLS, 25: 非暗号化) |
| Use Secure Connection |
boolean |
SSL/TLS接続を使用(ポート465の場合はオン) |
| Userid |
string |
SMTP認証のユーザーID |
| Password |
string |
SMTP認証のパスワード |
| Name |
string |
エディタ上での表示名 |
入力メッセージプロパティ
| プロパティ |
型 |
説明 |
| msg.to |
string |
宛先アドレス(ノード設定の値を上書き) |
| msg.cc |
string |
CCアドレス |
| msg.bcc |
string |
BCCアドレス |
| msg.from |
string |
送信元アドレス(認証ユーザーと一致する必要がある場合が多い) |
| msg.topic |
string |
メールの件名(Subject) |
| msg.payload |
string / Buffer |
メール本文(HTML可)。Bufferの場合は添付ファイルとして送信 |
| msg.plaintext |
string |
payloadがHTMLの場合のプレーンテキスト代替版 |
| msg.replyTo |
string |
返信先アドレス |
| msg.inReplyTo |
string |
返信元メッセージID |
| msg.references |
string |
スレッドの参照メッセージID |
| msg.headers |
object |
カスタムメールヘッダー |
| msg.priority |
string |
メールの優先度 |
| msg.attachments |
array |
添付ファイル(nodemailer形式) |
| msg.envelope |
object |
SMTP envelope(拡張アドレス指定用) |
基本的な送信フロー例
テスト送信
→
件名・本文設定
→
e-mail
テキストメール送信
// Functionノードで本文を設定
msg.to = "recipient@example.com";
msg.topic = "Node-REDからのテスト通知";
msg.payload = "これはNode-REDから送信されたテストメールです。";
return msg;
HTMLメール送信
// HTMLメールを送信
msg.to = "recipient@example.com";
msg.topic = "センサーアラート通知";
msg.payload = "<h2>温度アラート</h2>" +
"<p>センサーの温度が閾値を超えました。</p>" +
"<ul>" +
" <li>現在値: <strong>" + msg.temperature + "°C</strong></li>" +
" <li>閾値: 50°C</li>" +
" <li>時刻: " + new Date().toLocaleString('ja-JP') + "</li>" +
"</ul>";
msg.plaintext = "温度アラート: 現在値 " + msg.temperature + "°C(閾値: 50°C)";
return msg;
添付ファイル付きメール送信
// 添付ファイル付きメール
msg.to = "recipient@example.com";
msg.topic = "レポート添付";
msg.payload = "日次レポートを添付します。";
msg.attachments = [
{
filename: "report.csv",
content: "日時,温度,湿度\n2025-01-01 10:00,25.3,60\n2025-01-01 11:00,26.1,58",
contentType: "text/csv"
}
];
return msg;
💡 ヒント: msg.payloadにBuffer(バイナリデータ)を設定すると、自動的に添付ファイルとして送信されます。その場合、msg.filenameでファイル名を指定できます。
📥 4. e-mail in(受信)ノード
IMAP4またはPOP3プロトコルを使用してメールを受信する入力ノードです。定期的にサーバーをポーリングし、新着メールをメッセージとして出力します。
ノード設定プロパティ
| プロパティ |
型 |
説明 |
| Protocol |
select |
受信プロトコル(IMAP4またはPOP3) |
| Server |
string |
受信サーバーのホスト名(例: imap.gmail.com) |
| Port |
number |
ポート番号(IMAP: 993, POP3: 995) |
| Use Secure Connection |
boolean |
SSL/TLS接続を使用 |
| Userid |
string |
メールアカウントのユーザーID |
| Password |
string |
メールアカウントのパスワード |
| Folder |
string |
監視するフォルダ(IMAP4の場合。デフォルト: INBOX) |
| Disposition |
select |
受信後のメール処理(None / Mark Read / Delete) |
| Name |
string |
エディタ上での表示名 |
出力メッセージプロパティ
| プロパティ |
型 |
説明 |
| msg.payload |
string |
メール本文(プレーンテキスト) |
| msg.html |
string |
HTML形式の本文(存在する場合) |
| msg.topic |
string |
メールの件名 |
| msg.from |
string |
送信者アドレス |
| msg.date |
string |
メールの日時 |
| msg.header |
object |
完全なヘッダーオブジェクト(to, cc等を含む) |
| msg.attachments |
array |
添付ファイルの配列 |
添付ファイルオブジェクトの構造
// msg.attachments[0] の例
{
"contentType": "application/pdf",
"fileName": "document.pdf",
"contentDisposition": "attachment",
"transferEncoding": "base64",
"length": 102400,
"generatedFileName": "document.pdf",
"content": <Buffer> // バイナリデータ
}
受信フロー例
e-mail in
→
debug
e-mail in
→
件名フィルタ
→
処理
→
debug
受信メールの解析
// Functionノードで受信メールを解析
var subject = msg.topic;
var from = msg.from;
var body = msg.payload;
var date = msg.date;
node.warn("件名: " + subject);
node.warn("送信者: " + from);
node.warn("日時: " + date);
// 添付ファイルがある場合
if (msg.attachments && msg.attachments.length > 0) {
msg.attachments.forEach(function(att) {
node.warn("添付: " + att.fileName + " (" + att.contentType + ")");
});
}
return msg;
🔐 5. 認証設定
主要メールサービスの設定
📧 Gmail
送信: smtp.gmail.com ポート: 465(SSL)
受信: imap.gmail.com ポート: 993(SSL)
認証: アプリパスワードが必要(2段階認証を有効化した上で生成)
📧 Outlook / Office 365
送信: smtp.office365.com ポート: 587(STARTTLS)
受信: outlook.office365.com ポート: 993(SSL)
認証: OAuth2.0が必要な場合あり
📧 Yahoo! Mail
送信: smtp.mail.yahoo.co.jp ポート: 465(SSL)
受信: imap.mail.yahoo.co.jp ポート: 993(SSL)
⚠️ Gmailのアプリパスワード設定手順:
- Googleアカウント設定 → セキュリティ
- 2段階認証プロセスを有効化
- セキュリティ → アプリパスワードを選択
- アプリ名を入力して作成をクリック
- 生成された16文字のパスワードをNode-REDのPassword欄に入力
注意: 通常のGmailパスワードは使用できません。必ずアプリパスワードを使用してください。
IMAP vs POP3 の比較
| 項目 |
IMAP4 |
POP3 |
| メール保管 |
サーバーに残る |
ダウンロード後に削除可能 |
| フォルダ管理 |
対応(INBOX以外も指定可) |
非対応(INBOXのみ) |
| 複数デバイス |
同期される |
同期されない |
| 推奨用途 |
一般的な監視用途 |
ダウンロード後に処理する場合 |
| デフォルトポート |
993(SSL) |
995(SSL) |
💡 推奨: 特別な理由がない限りIMAP4を使用してください。サーバー上のメール状態管理が容易で、フォルダ指定も可能です。
🛠️ 6. 実用的な使用パターン
パターン1: IoTセンサーアラート通知
センサーの値が閾値を超えた場合にメールで通知します。
センサー値
→
閾値チェック
→
アラート作成
→
e-mail
// Functionノード: アラートメール作成
msg.to = "admin@example.com";
msg.topic = "[ALERT] 温度異常検知 - " + new Date().toLocaleString('ja-JP');
msg.payload = "<h2 style='color:red'>温度アラート</h2>" +
"<p>検知時刻: " + new Date().toLocaleString('ja-JP') + "</p>" +
"<p>センサーID: sensor-01</p>" +
"<p>現在温度: <strong>" + msg.payload + "°C</strong></p>" +
"<p>閾値: 50°C</p>" +
"<hr>" +
"<p style='color:gray'>このメールはNode-REDから自動送信されています。</p>";
return msg;
パターン2: 定期レポート送信
定期的にデータを収集し、レポートとしてメール送信します。
毎日9:00
→
データ収集
→
レポート生成
→
e-mail
// Functionノード: 日次レポートデータの整形
var now = new Date();
var dateStr = now.toLocaleDateString('ja-JP');
msg.to = "team@example.com";
msg.topic = "日次レポート - " + dateStr;
// CSV添付ファイルを作成
var csvData = "時刻,温度,湿度,気圧\n";
// flow.get("dailyData") からデータを取得する例
var data = flow.get("dailyData") || [];
data.forEach(function(row) {
csvData += row.time + "," + row.temp + "," + row.humidity + "," + row.pressure + "\n";
});
msg.payload = "本日(" + dateStr + ")の計測レポートを添付します。";
msg.attachments = [{
filename: "report_" + dateStr.replace(/\//g, '-') + ".csv",
content: csvData,
contentType: "text/csv"
}];
return msg;
パターン3: メール受信によるコマンド実行
特定の件名のメールを受信してアクションを実行します。
e-mail in
→
件名判定
→
コマンド実行
→
結果返信
// Switchノードの設定:
// msg.topic が "STATUS" を含む → 出力1
// msg.topic が "RESTART" を含む → 出力2
// それ以外 → 出力3
// Functionノード: ステータス確認コマンド
var status = {
uptime: process.uptime(),
memory: process.memoryUsage(),
timestamp: new Date().toLocaleString('ja-JP')
};
msg.to = msg.from; // 送信者に返信
msg.topic = "Re: " + msg.topic;
msg.payload = "システムステータス:\n" +
"稼働時間: " + Math.floor(status.uptime / 3600) + "時間\n" +
"メモリ使用量: " + Math.floor(status.memory.heapUsed / 1024 / 1024) + "MB\n" +
"確認時刻: " + status.timestamp;
return msg;
パターン4: 連続送信制限(レートリミット)
短時間に大量のアラートが発生しても、メール送信を一定間隔に制限します。
アラート
→
重複チェック
→
e-mail
// Functionノード: 5分間に1回のみ送信
var lastSent = context.get("lastSent") || 0;
var now = Date.now();
var interval = 5 * 60 * 1000; // 5分
if (now - lastSent > interval) {
context.set("lastSent", now);
msg.to = "admin@example.com";
msg.topic = "[ALERT] 異常検知";
msg.payload = "異常が検知されました。\n時刻: " + new Date().toLocaleString('ja-JP');
return msg;
} else {
// 制限中は送信しない
return null;
}
📝 7. 演習問題
演習1: テストメール送信初級
課題:
Injectノードのボタンクリックで、テストメールを送信するフローを作成してください。
要件:
- Changeノードで件名と本文を設定する
- 件名: 「Node-RED テストメール」
- 本文: 「このメールはNode-REDから送信されたテストです。送信時刻: [現在時刻]」
- 宛先はe-mailノードの設定画面で指定する
✅ 成功の条件:
- Injectノードのボタンをクリックすると、e-mailノードが正常に動作してエラーが表示されない
- 指定した宛先メールアドレスに「Node-RED テストメール」という件名のメールが届く
- メール本文に送信時刻が含まれ、正しい内容で届いている(実際の送信テストはSMTPサーバー設定が必要なため省略可)
- デバッグノードを接続した場合、Changeノード出力の
msg.topicが「Node-RED テストメール」、msg.payloadに時刻文字列が含まれていることを確認できる
💡 ヒント
- Changeノードで
msg.topicに件名を設定
- Changeノードで
msg.payloadに本文を設定
- e-mailノードのTo欄に宛先を設定
- Server, Port, Userid, Passwordを正しく設定
✅ 解答例フロー
[
{
"id": "email_ex1_inject",
"type": "inject",
"name": "テスト送信",
"props": [],
"repeat": "",
"wires": [["email_ex1_change"]]
},
{
"id": "email_ex1_change",
"type": "change",
"name": "件名・本文設定",
"rules": [
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "Node-RED テストメール",
"tot": "str"
},
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "$join(['このメールはNode-REDから送信されたテストです。送信時刻: ', $now()])",
"tot": "jsonata"
}
],
"wires": [["email_ex1_send"]]
},
{
"id": "email_ex1_send",
"type": "e-mail",
"name": "テストメール送信",
"server": "smtp.gmail.com",
"port": "465",
"secure": true,
"tls": true,
"dname": "",
"to": "your-email@example.com",
"wires": []
}
]
演習2: 閾値アラート通知中級
課題:
温度センサーの値が設定した閾値を超えた場合にHTMLメールで通知するフローを作成してください。
要件:
- Injectノードでランダムな温度値(20〜60)を生成
- Switchノードで50°C以上を検知
- FunctionノードでHTMLメール本文を生成
- メール本文に温度値と検知時刻を含める
- 5分間に1回のみ送信するレートリミットを実装
✅ 成功の条件:
- 温度値が50以上の場合のみe-mailノードが実行され、50未満の場合はフローが止まる
- 「[ALERT] 温度異常: XX°C」という件名のアラートメールが指定アドレスに届く(実際の送信テストはSMTPサーバー設定が必要なため省略可)
- 5分以内に複数回50°C以上を検知しても、2回目以降のメール送信はスキップされる(レートリミットが機能している)
- Functionノードにデバッグノードを接続した場合、
msg.payloadにHTMLタグを含む本文文字列が出力される
💡 ヒント
- Injectノードの
msg.payloadをJSONata式で$floor($random() * 40 + 20)に設定
- Switchノードで
msg.payload >= 50を条件にする
- Functionノードで
context.get("lastSent")でレートリミット制御
- HTML本文では
<h2>や<strong>タグで視認性を高める
✅ 解答例フロー
[
{
"id": "email_ex2_inject",
"type": "inject",
"name": "ランダム温度",
"props": [{"p": "payload"}],
"payload": "$floor($random() * 40 + 20)",
"payloadType": "jsonata",
"repeat": "10",
"wires": [["email_ex2_switch"]]
},
{
"id": "email_ex2_switch",
"type": "switch",
"name": "50°C以上?",
"property": "payload",
"rules": [{"t": "gte", "v": "50", "vt": "num"}],
"wires": [["email_ex2_func"]]
},
{
"id": "email_ex2_func",
"type": "function",
"name": "アラートメール作成",
"func": "var lastSent = context.get('lastSent') || 0;\nvar now = Date.now();\nvar interval = 5 * 60 * 1000;\n\nif (now - lastSent > interval) {\n context.set('lastSent', now);\n var temp = msg.payload;\n msg.to = 'admin@example.com';\n msg.topic = '[ALERT] 温度異常: ' + temp + '°C';\n msg.payload = '
温度アラート
' +\n '
センサーの温度が閾値を超えました。
' +\n '
' +\n '- 現在温度: ' + temp + '°C
' +\n '- 閾値: 50°C
' +\n '- 検知時刻: ' + new Date().toLocaleString('ja-JP') + '
' +\n '
' +\n '
このメールはNode-REDから自動送信されています。
';\n return msg;\n}\nreturn null;",
"outputs": 1,
"wires": [["email_ex2_send"]]
},
{
"id": "email_ex2_send",
"type": "e-mail",
"name": "アラート送信",
"server": "smtp.gmail.com",
"port": "465",
"secure": true,
"tls": true,
"to": "admin@example.com",
"wires": []
}
]
演習3: メール受信による機器制御上級
課題:
特定の件名のメールを受信して機器の操作コマンドとして処理し、結果を返信するフローを作成してください。
要件:
- e-mail inノードでメールを受信
- 件名に「STATUS」を含むメールを受信したらシステム情報を返信
- 件名に「REPORT」を含むメールを受信したら保存データをCSVで返信
- 上記以外のメールは無視する
- 返信先は受信メールの送信者アドレスにする
✅ 成功の条件:
- 件名に「STATUS」を含むメールを受信すると、差出人に稼働時間・メモリ使用量を含む返信メールが届く(実際のメール送受信テストはサーバー設定が必要なため省略可)
- 件名に「REPORT」を含むメールを受信すると、差出人に.csvファイルが添付された返信メールが届く
- 上記以外の件名のメールを受信しても何も起こらない(Switchノードのマッチなし)
- 返信先(
msg.to)が受信メールのmsg.fromと同じアドレスになっている
💡 ヒント
- Switchノードで
msg.topicに対して「contains」条件を使用
msg.fromをmsg.toにコピーして返信先を設定
- CSVデータは
msg.attachmentsに設定する
process.uptime()やprocess.memoryUsage()でシステム情報を取得
✅ 解答例フロー
[
{
"id": "email_ex3_in",
"type": "e-mail in",
"name": "コマンド受信",
"protocol": "IMAP",
"server": "imap.gmail.com",
"port": "993",
"secure": true,
"useSSL": true,
"disposition": "Read",
"wires": [["email_ex3_switch"]]
},
{
"id": "email_ex3_switch",
"type": "switch",
"name": "コマンド判定",
"property": "topic",
"rules": [
{"t": "cont", "v": "STATUS", "vt": "str"},
{"t": "cont", "v": "REPORT", "vt": "str"}
],
"checkall": "false",
"wires": [["email_ex3_status"], ["email_ex3_report"]]
},
{
"id": "email_ex3_status",
"type": "function",
"name": "ステータス返信",
"func": "var uptime = process.uptime();\nvar hours = Math.floor(uptime / 3600);\nvar mins = Math.floor((uptime % 3600) / 60);\nvar mem = process.memoryUsage();\n\nmsg.to = msg.from;\nmsg.topic = 'Re: ' + msg.topic;\nmsg.payload = 'システムステータスレポート\\n' +\n '========================\\n' +\n '稼働時間: ' + hours + '時間' + mins + '分\\n' +\n 'メモリ使用量: ' + Math.floor(mem.heapUsed / 1024 / 1024) + 'MB / ' + Math.floor(mem.heapTotal / 1024 / 1024) + 'MB\\n' +\n '確認時刻: ' + new Date().toLocaleString('ja-JP');\nreturn msg;",
"wires": [["email_ex3_send"]]
},
{
"id": "email_ex3_report",
"type": "function",
"name": "レポート返信",
"func": "var data = flow.get('sensorData') || [\n {time: '10:00', temp: 25.3, humidity: 60},\n {time: '11:00', temp: 26.1, humidity: 58},\n {time: '12:00', temp: 27.5, humidity: 55}\n];\n\nvar csv = '時刻,温度,湿度\\n';\ndata.forEach(function(row) {\n csv += row.time + ',' + row.temp + ',' + row.humidity + '\\n';\n});\n\nmsg.to = msg.from;\nmsg.topic = 'Re: ' + msg.topic;\nmsg.payload = '計測データレポートを添付します。';\nmsg.attachments = [{\n filename: 'report_' + new Date().toISOString().slice(0,10) + '.csv',\n content: csv,\n contentType: 'text/csv'\n}];\nreturn msg;",
"wires": [["email_ex3_send"]]
},
{
"id": "email_ex3_send",
"type": "e-mail",
"name": "返信送信",
"server": "smtp.gmail.com",
"port": "465",
"secure": true,
"tls": true,
"wires": []
}
]
🔧 8. トラブルシューティング
| 問題 |
原因 |
解決方法 |
| メールが送信されない |
SMTP認証エラー |
アプリパスワード(Gmail)を使用する。ユーザーIDとパスワードを再確認する |
| 「Connection refused」エラー |
サーバーアドレスまたはポート番号が間違い |
正しいサーバー名・ポート番号を設定する(Gmail送信: smtp.gmail.com:465) |
| 「Authentication failed」エラー |
パスワードが通常のパスワード |
Gmailの場合はアプリパスワードを生成して使用する |
| メール受信が動作しない |
IMAPが無効化されている |
メールサービスの設定でIMAP/POP3アクセスを有効化する |
| SSL/TLS接続エラー |
ポートとSSL設定の不一致 |
ポート465はSSL=ON、ポート587はSSL=OFF(STARTTLSが自動使用される) |
| 添付ファイルが届かない |
attachmentsの形式が不正 |
nodemailer形式(filename, content, contentType)で指定する |
| HTMLメールがテキストで表示される |
Content-Typeが設定されていない |
msg.payloadにHTMLを設定すると自動的にHTML形式で送信される |
| 受信ポーリングが頻繁すぎる |
デフォルト設定 |
e-mail inノードの設定でポーリング間隔を調整する |
| ノードがパレットに表示されない |
インストール失敗またはNode-RED未再起動 |
npm installのエラーログを確認し、Node-REDを再起動する |
| OAuth2エラー(Outlook) |
基本認証が無効化されている |
OAuth2.0認証トークンをmsg経由で渡す設定を行う |
📝 9. ベストプラクティス
✅ 推奨事項:
- アプリパスワードの使用: Gmail等では通常パスワードではなくアプリパスワードを使用する
- レートリミットの実装: アラート通知には必ず送信間隔制限を設けて大量送信を防ぐ
- エラーハンドリング: Catchノードを接続してメール送信失敗時のリトライや通知を実装する
- 件名の明確化: 自動送信メールには[NODE-RED]等の接頭辞を付けて識別しやすくする
- HTMLとプレーンテキストの両方: HTMLメール送信時は
msg.plaintextも設定してテキストのみ対応のクライアントに配慮する
- IMAPの使用: 受信にはPOP3よりIMAPを推奨(フォルダ管理、状態同期が可能)
⚠️ 注意事項:
- セキュリティ: パスワードはNode-REDの認証情報管理(credentials)で安全に保管される。フローのエクスポート時にパスワードは含まれない
- 送信制限: GmailのSMTPには1日あたりの送信数制限(500通/日)があるため、大量送信には向かない
- ポーリング負荷: e-mail inノードのポーリング間隔を短くしすぎるとサーバーに負荷がかかる。最低30秒以上を推奨
- 添付ファイルサイズ: 大きな添付ファイルはメールサーバーの制限(通常25MB)に注意する
- スパム判定: 自動送信メールはスパムフィルターに引っかかる場合がある。送信元アドレスとSPF/DKIM設定を確認する
🔗 10. 追加リソース
🏠