Node.js を使用してメール送信クライアントを作ってみました。
とはいえ「 nodemailer 」という npm パッケージを使用しただけなので、
実装自体は特別苦は無いはず。
これを使えば、ラズパイからセンサーデータをメール通知させることもできるので、そのためのテスト。
目次
nodemailer 導入
プロジェクトのフォルダで、npm install nodemailer --save
実行
これだけです。
単発でメールを送ってみる
nodemailer.comを参考に、
simplemailsend.js を作成します。
今回は、送信用の smtp サーバは gmail を使用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| var Mailer = require('nodemailer');
var Smtpsetting = { service: 'Gmail', secure: true, auth: { user: '[Gmailアドレス]', pass: '[Gmailアカウントのパスワード]', port: '465' } };
var Mailobject = { from: '[送信元アドレス]', to: '[送信先アドレス]', subject: 'This mail is test.', text: ` テストのメールです。 テストなので、返信不要です。 `, html: ` <html> <head> </head> <body> <h1>テストのメールです</h1> <p>テストなので、返信不要です。</p> </body> </html> ` };
var Smtp = Mailer.createTransport('SMTP', Smtpsetting);
let Send = () => Smtp.sendMail(Mailobject, function (err, res) {
if (err) { console.log('送信失敗\n=>' + err);
} else { console.log('送信成功\n=>' + res.message); } Smtp.close(); });
Send();
|
伏せてある Gmail アカウントの項目を埋めてあげ、
node .\simplemailsend.js
で実行します。
送信先に指定したアドレスにメールが送信できたはずです。
送信先を Gmail にしていたのですが、html 形式表示されました。
メールクライアントソフトなどを使用していると、text 形式表示も試せると思います。
定期的にメールを送ってみる
定期的にメールを送るには、
- タスクスケジューラに登録(windows)
- cron に登録(linax)
- コードの中で定期実行
する手段が考えられると思います。
今回は、コードの中で完結させたいので、3の方法をとってみます。
(ラズパイに乗せるときは、cron 登録で実行の予定)
loopmailsend.js として以下を保存します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| const Mailer = require("nodemailer");
const Smtpsetting = { service: "Gmail", secure: true, auth: { user: "[Gmailアドレス]", pass: "[Gmailアカウントのパスワード]", port: "465", }, };
let GetMailObject = (() => { let Mailobject = { from: "[送信元アドレス]", to: "[送信先アドレス]", subject: "This mail is test.", text: "", html: "", };
let count = 0;
return () => { let date = new Date(); let timestr = " " + (date.getMonth() + 1) + "/" + date.getDate() + " " + date.getHours() + ":" + date.getMinutes() + "[" + date.getSeconds() + "]";
count += 1;
Mailobject.text = ` ${count}件目のテストのメールです。 現在時刻は${timestr}です テストなので、返信不要です。 `; Mailobject.html = ` <html> <head> </head> <body>
<h1>${count}件目のテストのメールです</h1> <p>現在時刻は${timestr}です。</p> <p>テストなので、返信不要です。</p> </body> </html> `; return Mailobject; }; })();
let Smtp = Mailer.createTransport("SMTP", Smtpsetting);
let Send = () => Smtp.sendMail(GetMailObject(), function (err, res) { if (err) { console.log("送信失敗\n=>" + err); } else { console.log("送信成功\n=>" + res.message); } Smtp.close(); });
for (let i = 0; i < 10; i++) { Send(); }
|
node .\loopmailsend.js
で実行する。
これは失敗する
ループで 10 件送ったはずなのに、4 件だったり、10件だったり・・・。
さらにカウントアップしているはずなのに、全件の内容が同一になったりする。
理由は sendMail 関数が、非同期関数であるため。
もし順にカウントアップするなら、
それなりの方法が必要
ちゃんと定期的にメールを送ってみる[async await で修正]
loopmailsend-sync.js として以下を保存する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
| const Mailer = require("nodemailer");
const Smtpsetting = { service: "Gmail", secure: true, auth: { user: "[Gmailアドレス]", pass: "[Gmailアカウントのパスワード]", port: "465", }, };
let GetMailObject = (() => { let Mailobject = { from: "[送信元アドレス]", to: "[送信先アドレス]", subject: "This mail is test.", text: "", html: "", };
let count = 0;
return () => { let date = new Date(); let timestr = " " + (date.getMonth() + 1) + "/" + date.getDate() + " " + date.getHours() + ":" + date.getMinutes() + "[" + date.getSeconds() + "]";
count += 1;
Mailobject.text = ` ${count}件目のテストのメールです。 現在時刻は${timestr}です テストなので、返信不要です。 `; Mailobject.html = ` <html> <head> </head> <body> <h1>${count}件目のテストのメールです</h1> <p>現在時刻は${timestr}です。</p> <p>テストなので、返信不要です。</p> </body> </html> `; return Mailobject; }; })();
let Smtp = Mailer.createTransport("SMTP", Smtpsetting);
let Send = async () => { return new Promise((resolve, reject) => { Smtp.sendMail(GetMailObject(), function (err, res) { if (err) { console.log("送信失敗\n=>" + err); reject("送信失敗\n=>" + err); } else { console.log("送信成功\n=>" + res.message); resolve("送信成功\n=>" + res.message); } }); }); };
let Sleep = async (time) => { return new Promise((resolve) => setTimeout(() => { console.log(`timeout${time}ms`); resolve(); }, time) ); };
(async function SendLoop() { console.log("送信開始"); for (let i = 0; i < 10; i++) { await Sleep(3000); console.log("SendStart"); await Send(); console.log("SendEnd"); } Smtp.close(); })();
|
node .\loopmailsend-sync.js
で実行する。
10 件のメールが内容もカウントアップされながら送信されて来たはずです。
このコードでは 3 秒間隔のタイムアウトを挟んで、10 件メールの送信をしてみました。
手元の環境ではメール送信処理自体が、1 秒程度かかっていたので実際には4~5秒程度の間隔のメール送信になります。
感想とか
今回は node.js でメール送信を(ライブラリもあるし)割合簡単に実装できました。
ラズパイと組み合わせれば、センサー値をメールで通知ができるようになります。
追加で通知手段として twitter も組み合わせたり、外部からコマンドを発行して通知を返すとかも作ってゆきたいですね。
連休に、距離センサー買ったりサーボモーター動かしてみたりしたので、
早く形にして、記事にまとめたいですね。
ではでは。