読者です 読者をやめる 読者になる 読者になる

望月いちろうのREADME.md

書き溜めておいた技術記事や旅行記のバックアップです。

Postfixをインストールしてサーバーからメールを送ってみる

f:id:mochizuki_p:20170207200537g:plain

サーバーからメールを送信したいという需要があると思います。 それはWebサービスの認証用にHTMLメールをユーザーに送信したいという需要によるかもしれませんし、メールマガジンやサイトの更新をユーザーに伝えるためかもしれません。あるいはダイレクトメール(これはスパムかも)を送信したいからかもしれません。

どちらにしても未だにメールを送信するというタスクはWebサービスを運営する上で、重要性があるわけですね。

ところでNode.jsを利用したアプリケーション上でメールを送信するには、Nodemailerというプラグインを利用するのが一般的です。

github.com

ところが、インターネット上ではGmailをSMTPサーバーとしてメールを送信するデモは多数ありましたが、サーバー内部で動作しているSMTPクライアントを利用してメールを送信するという例は見つかりませんでした。

The Postfix Home Page

そこで今回はUbuntuやCentOSで利用出来るオープンソースSMTPクライアントであるPostfixを中継して、Node.jsからHTMLメールを送信するデモを実演してみようと思います。

まずは今回のデモを実行する環境から

タイプ
OS Linux Ubuntu 14.04

初める

SSHでログインしたら、まずはapt-getを更新します。

sudo apt-get update

そしてPostfixとメール送信に関係したツールを一括でダウンロードするmailutilsというパッケージをインストールします。

sudo apt-get install postfix mailutils -y

このような画面になります。Postfixの初期設定を始めるわけです。

f:id:mochizuki_p:20170207195507p:plain

用途別に最適化された初期設定を準備してあるから、選択しろ

f:id:mochizuki_p:20170207195521p:plain

というわけです。

それぞれの用途をまとめると

タイプ 用途
Internet Site ウェブサイト SMTPを直接利用してメールの送受信を行う
Internet With smarthost スマートホスト付きウェブサイト fetch mailのような機能を利用してメールを取得・スマートホストを利用してメールを送信する
Satellite system メール転送サーバー メールの転送だけを行う
Local only ローカルのみ ローカルのユーザーにだけメールを送信する

今回の用途ではInternet Siteを選択します。

つぎにメールシステムで利用するドメイン名を指定します。

f:id:mochizuki_p:20170207195529p:plain

ここではmail.utali.ioとします。

入力が終わったらOKを押して完了です。

PostfixのようなSMTPサーバーは外部からのメール転送が可能な仕組みになっています。しかし、これはスパムメールの温床になるリスクがあり、無効化すべきです。 ここで、ローカルで起動しているプロセスからのみPostfixが利用出来るように設定します。

Postfixの設定ファイルをVimで編集します。

sudo vi /etc/postfix/main.cf

この個所を・・・

mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all

以下のように変更します

mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = localhost

これを保存したらPostfixを再起動して、設定を反映させます。

sudo service postfix restart

Node.jsからメールを送信する

ここまでの設定がうまくいけばローカルで起動している任意のアプリケーション上から、やはりローカルで起動してあるSMTPサーバーであるPostfixを経由してメールを送信することが可能です。

まず、Node.jsを利用してメールを送信することにしましょう。

最初にNode.jsとnpmがインストールされていることを確認してください

次にnodemailerをインストールします。但し古いバージョンでないと、うまくいかなったので注意してください。

sudo npm install nodemailer@0.7

テスト用のスクリプトを書きます。

touch mail.js

mail.js

var mailer = require('nodemailer');

//SMTPの設定
var setting = {
    host: 'localhost',
};
//メタデータ:これを詳しく書かないと迷惑メール扱いされる
var meta =  { from: 'root <root@mail.utali.io>' };
var options = {
    from: 'root@mail.utali.io',
    to: 'root@example.com',
    subject: 'こんにちは',
    text: 'テスト'
};
//SMTPの接続
var smtp = mailer.createTransport('SMTP', setting, meta);
//メールの送信
smtp.sendMail(options, function(err, res){
    if(err){
        console.error(err);
    }else{
        console.log('Message sent: ' + res.message);
    }
    smtp.close();
});

次はHTMLメールを送ってみましょう 最初にHTMLファイルを用意します。想定する用途はログインに使用するメールアドレスの確認用で、特定の認証用URLにアクセスすることで、そのユーザーが正当であることを確認することにします。

mail.html

<html>
<head>
  <style>h2{color:red}</style>
</head>
<body>
  <h2>HTML MAILER</h2>
</body>
</html>

mail.js

var mailer = require('nodemailer');
var fs = require('fs');

//SMTPの設定
var setting = {
    host: 'localhost',
};
// HTMLファイルをロード
var HTML = fs.readFileSync("mail.html")
//メタデータ:これを書かないと迷惑メール扱いされる
var meta =  { from: 'root <root@mail.utali.io>' };
var options = {
    from: 'root@mail.utali.io',
    to: 'root@example.com',
    subject: 'こんにちは',
    html: HTML
};
//SMTPの接続
var smtp = mailer.createTransport('SMTP', setting, meta);
//メールの送信
smtp.sendMail(options, function(err, res){
    if(err){
        console.error(err);
    }else{
        console.log('Message sent: ' + res.message);
    }
    smtp.close();
});

実際に送信

node mail.js

結果

HTMLメールを送信できた

f:id:mochizuki_p:20170207200336p:plain