[macOS General] MailCatcher: ダミーSMTPサーバをつかってメール送信

ローカルのMac環境からメール送信をするための方法を調べました。 Zend
Server 環境から Zend_Mail (PHP)を使ってメール送信するまで。

まず、Gmailやプロバイダなどの外部SMTPサーバをつかう設定がありました。

運用を考えると、設置予定のサーバのSMTPをつかうのが良いのでしょうか?

MailCatcher のインストール

以前にMOONGIFTさんで「メール送信を誤ると大変な失敗。慎重に開発すべし。」のような内容とともにダミーSMTPサーバの紹介がされていたことを思い出したので、試してみることにしました。
ダミーSMTPサーバ MailCatcher をインストールします。

$ gem install mailcatcher

mailcatcher でサーバが起動します。
停止するには http://localhost:1080/ でアクセスできるインターフェースのquitボタンを押します。

$ mailcatcher
Starting MailCatcher
==> smtp://127.0.0.1:1025
==> http://127.0.0.1:1080
*** MailCatcher runs as a daemon by default. Go to the web interface to quit.

サーバを起動すると以下の機能が使えるようになります。

  • http://localhost:1080/ から送信したメール内容をメールアプリのようなUIで確認できる。
  • smtp://localhost:1025/ をSMTPサーバとして利用できる。

Zend_Mail からSMTPを使ってみる

Rails と PHP の設定例が公式サイトにありました。
Zend Server で試してみます。
php.ini の sendmail_path を設定します。

$ sudo vim /usr/local/zend/etc/php.ini
/usr/local/zend/etc/php.ini
// sendmail_path を下記のように設定
sendmail_path = /usr/bin/env catchmail

Zend_Mailをつかった下記のようなActionを用意して試してみました。
port 1025 を指定します。

public function sendmailAction() {
    $mail = new Zend_Mail();
    $mail->addTo('foo@gmail.com', 'Some Recipient');
    $mail->setFrom('bar@gmail.com', 'Some Sender');
    $mail->setSubject('TestSubject');
    $mail->setBodyText('This is the text of the mail.');
    $config = array('port' => 1025);
    $smtp = new Zend_Mail_Transport_Smtp('127.0.0.1', $config);
    try {
        $mail->send($smtp);
        echo '送信しました';
    } catch (Zend_Exception $e) {
        echo "エラー: " . $e->getMessage();
    }
}

このような形でMailCatcherしていました。
From, To とも実在のアドレスですが、そこにはメールは届いていません。
(メールアドレスが壊れていても、送信されたように扱われました。)

MailCatcher 2013-05-22-15-36-07

MOONGIFTさんでは、画像表示と日本語件名の文字化けの不具合があったそうなので、後日確かめてみます。

画像、日本語表示まわりの確認

画像の表示と日本語件名の文字化けについて、可能な範囲で確かめてみました。
現在のバージョンで試した限りでは、画像の表示は可能で、適切にISO-2022-JPエンコーディングすれば文字化けもなさそうでした。
ただしメールまわりの仕様を含め理解し切れてないので、詳しい方がいたら教えて下さい。

Zend公式を見ながら、下記のようなスクリプトで試してみました。

public function sendmailAction() {
    function mbCnv($string) {
        return mb_convert_encoding($string, 'ISO-2022-JP', 'UTF-8');
    }
    $subject = '日本語のサブジェクト';
    $body = '日本語の本文。テスト。';
    $html = '<h1>HTMLメールの本文</h1><img src="http://hoge.com/images/logo.png">';
    $mail = new Zend_Mail('ISO-2022-JP');
    $mail->setBodyText(
        mbCnv($body),
        null,
        Zend_Mime::ENCODING_7BIT
    );
    $mail->setBodyHtml(
        mbCnv($html),
        null,
        Zend_Mime::ENCODING_7BIT
    );
    $mail->setHeaderEncoding(Zend_Mime::ENCODING_BASE64);
    $mail->addTo('foo@gmail.com');
    $mail->setFrom('bar@gmail.com');
    $mail->setSubject(mbCnv($subject));
    $atImage = 'http://hoge.com/images/logo.png';
    $at = new Zend_Mime_Part(file_get_contents($atImage));
    $at->type        = 'image/png';
    $at->disposition = Zend_Mime::DISPOSITION_INLINE;
    $at->encoding    = Zend_Mime::ENCODING_BASE64;
    $at->filename    = mbCnv('test.png');
    $mail->addAttachment($at);
    $config = array('port' => 1025);
    $smtp = new Zend_Mail_Transport_Smtp('127.0.0.1', $config);
    try {
        $mail->send($smtp);
        echo '送信しました';
    } catch (Zend_Exception $e) {
        echo "エラー: " . $e->getMessage();
    }
}

画像を適当なURLから取ってきて、HTMLメールも表示できました。
画像を添付してみましたが、Attachmentsとして添付されています。

MailCatcher 2013-05-22-22-54-56

subjectと本文を日本語で書いて見ましたが、表示はされているようです。

MailCatcher 2013-05-22-22-56-04

Sourceというタブでは、エンコーディングはディフォルトのままのようで切り替わりませんでした。

MailCatcher 2013-05-22-23-04-28

Downloadボタンで.emlファイルがダウンロードできます。
クイックルックで確認したところ、それっぽく表示されています。
(左下の?は、添付ファイルをあらわしているようです。)

MailCatcher 2013-05-22-23-11-16

Zend_Mail まわりですが、試しているうちに深い森へ足を踏み入れてしまいました。
このあたりはまた別の機会に。