Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
108
Help us understand the problem. What is going on with this article?
@pocari

MailCatcherでメール送信をテスト

More than 3 years have passed since last update.

MailCatcherでメール送信をテストする

概要

メール送信のテストって面倒ですよね。本文の確認だけならそれほど手間ではありませんが、
やはりメールなので実際に送信できたかどうかの確認は必要になります。

すると、SMTPサーバを用意して、テストなり自分なりのアドレスに実際にメールを送って確認、
面倒なのでいつかオペミスしてホントの他人のアドレスに一斉送信とか、悲しいあるあるです。

で、なんかいいものは無いかと探しているとMailCatcherというのがあるようでした。

良い感じのライブラリだったのでdockerファイル作ってそれで開発用簡易SMTPサーバ(実際に送るわけではないですが)にすると便利であろうと思って試してみました。

環境

僕の環境はmacなのでdocker-machineを使っています。
なので、以降docker hostのIPアドレスは192.168.99.100としています。
ここは適宜ご自分の環境に合わせてください。

  • ruby 2.3.0
  • MailCatcher 0.6.4
  • docker version 1.11.1, build 5604cbe
  • docker-machine version 0.7.0,

MailCatcher

特徴としては

  • SMTPサーバとして使えるが実際にメールを送信することはなく、送信したメールを保存してくれる。
  • 保存したメールはMailCatcherが別途用意しているweb画面でブラウザから確認できる。
  • また保存されているメールをapiで取得することが出来る

というようなライブラリです。

MailCatcherのDocker化

開発時にだけ必要なので出来るだけ軽いコンテナにしたかったためalpineベースのrubyコンテナを元に作りました。

Dockerfile
FROM ruby:2.3.0-alpine

RUN apk --no-cache --update add \
                            libstdc++ \
                            build-base \
                            openssl-dev \
                            sqlite \
                            sqlite-dev \
                            ruby-dev && \
    gem install mailcatcher && \
    apk del build-base ruby-dev && \
    rm -rf /tmp/* /var/tmp/* /var/cache/apk/*

EXPOSE 1025 1080

CMD ["mailcatcher", "-f", "--ip=0.0.0.0"]

このDockerfileの内容で作ったイメージをDocker hubにあげているので、buildしなくても、
下記コマンドでMailCatcherが立ち上がります。

docker run -d -p 1080:1080 -p 1025:1025 pocari/mailcatcher

ここでマッピングしている1080,1025はそれぞれ、web画面参照用のポート、SMTP用のポートです。

Web画面にアクセス

上記のコンテナ起動後、もうWeb画面も、SMTPサーバも使用可能になっているので、Web画面から確認してみます。

http://192.168.99.100:1080にブラウザからアクセスします。

スクリーンショット 2016-05-20 0.19.33.png

まだメールは無いので何も表示されてませんが、シンプルで綺麗な画面ですね。
公式ページによるとWebSocketを使っているみたいで、メール送信が発生するとページをリロードしなくてもリアルタイムで画面が更新されていきます。

メール送信

さて、これで環境はできたので実際にメールを送信してみましょう。

やはりrailsから送ることが多いと思うので、今回はActionMailerを使ってテストしてみます。
たださすがにrailsのアプリケーションから作ると面倒なので、ActionMailer単体で使用します。

今回はplainなメールとHTMLメールをそれぞれ一通ずつ送信してみます。

Gemfile

Gemfileを作成してインストールします。

# Gemfile作成
$ bundle init
$ echo 'gem "actionmailer"' >> Gemfile
# インストール
$ bundle install --path=vendor/bundle

テスト用スクリプト

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

今回の場合SMTPサーバの設定のホストがdocker hostで、ポートがdocker run時に設定した1025です。

またHTMLメールも送ってみたいので、テンプレートファイルの置き場も別途指定します。

それ以外は通常のActionMailerの使い方と同じだと思います。

test.rb
require 'action_mailer'

#SMTP設定
ActionMailer::Base.smtp_settings.merge!(
  address: '192.168.99.100',
  port: 1025
)

#テンプレートファイルの置き場所のルートフォルダを設定
ActionMailer::Base.prepend_view_path File.dirname(File.expand_path(__FILE__))

#メール送信クラス
class TestMailer < ActionMailer::Base
  default from: 'from@example.com'

  def test_mail(to, subject, body)
    mail(to: to, subject: subject, body: body)
  end

  def test_html_mail(to, subject, arg1, arg2)
    @arg1 = arg1
    @arg2 = arg2
    mail(to: to, subject: subject)
  end
end

#普通のメールを送信
TestMailer.test_mail(
  'to_address@example.com',
  'test subject',
  'Hello, World'
).deliver_now

#HTMLメールを送信
TestMailer.test_html_mail(
  'to_address@example.com',
  'test subject',
  'World',
  'Hoge',
).deliver_now

テンプレートファイルも用意しておきます。
今回はテンプレートファイルのルートをスクリプトファイルのディレクトリにしたので、
テンプレートファイルは./test_mailer/test_html_mail.html.erbに置きます。

./test_mailer/test_html_mail.html.erb
<!DOCTYPE html>
<html>
  <head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
  </head>
  <body>
    <h1>Hello, <%= @arg1 %></h1>
    <h2>This is HTML mail.</h2>
    <p>arg2 is <%= @arg2 %></p>
  </body>
</html>

実行!

さて、上記までで準備出来たので実行してみましょう。

$ bundle exec ruby test.rb

先ほどのweb画面にアクセスると下記のようになっていると思います。

スクリーンショット 2016-05-20 0.37.29.png

HTMLメールの方も見てみましょう。
スクリーンショット 2016-05-20 0.38.10.png

きちんと保存されていますね。

API

APIの方も確認してみましょう。

192.168.99.100:1080/messagesで保存済みメールのサマリが取得できます。
(ここではjsonの整形にjqを使ってます。)

$ curl -s 192.168.99.100:1080/messages | jq
[
  {
    "id": 1,
    "sender": "<from@example.com>",
    "recipients": [
      "<to_address@example.com>"
    ],
    "subject": "test subject",
    "size": "296",
    "created_at": "2016-05-19T15:31:32.000+00:00"
  },
  {
    "id": 2,
    "sender": "<from@example.com>",
    "recipients": [
      "<to_address@example.com>"
    ],
    "subject": "test subject",
    "size": "517",
    "created_at": "2016-05-19T15:31:32.000+00:00"
  }
]

個別メールの本文もapiで取得できます。メールの識別は上記のサマリ結果のidを使い
192.168.99.100:1080/messages/:id(.format)
の形式で確認できます。.formatの部分はplainやらhtmlやらです。

今回の場合id:1plainid:2htmlなので、そのようにして内容を確認してみます。

  • テキストメールの内容
$ curl -s 192.168.99.100:1080/messages/1.plain
Hello, World
  • HTMLメールの内容
$ curl -s 192.168.99.100:1080/messages/2.html
<!DOCTYPE html>
<html>
  <head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
  </head>
  <body>
    <h1>Hello, World</h1>
    <h2>This is HTML mail.</h2>
    <p>arg2 is Hoge</p>
  </body>
</html>

きちんと取れてますね。
その他:id.sourceの形式でヘッダも含めたメール内容全体が取得できます。

$ curl -s 192.168.99.100:1080/messages/2.source
Date: Fri, 20 May 2016 00:31:32 +0900
From: from@example.com
To: to_address@example.com
Message-ID: <573ddc543bc77_8ff73fcdbe03fa18274e5@paganini.local.mail>
Subject: test subject
Mime-Version: 1.0
Content-Type: text/html;
 charset=UTF-8
Content-Transfer-Encoding: 7bit

<!DOCTYPE html>
<html>
  <head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
  </head>
  <body>
    <h1>Hello, World</h1>
    <h2>This is HTML mail.</h2>
    <p>arg2 is Hoge</p>
  </body>
</html>

まとめ

これなら安心して開発環境でバンバンメール送信できますね。

108
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
pocari
sikmi
しくみ製作所株式会社は、世の中の「しくみ」を素敵にするためのソフトウェア開発集団です。オフィスのない弊社は、メンバー全員リモートワークです!

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
108
Help us understand the problem. What is going on with this article?