RailsでFoundation for Emails 2.0を使ってレスポンシブなHTMLメールを送る

　この記事は[トレタ Advent Calendar 2016](http://qiita.com/advent-calendar/2016/toreta)の24日目の記事になります。メリークリスマス！

　今時のメールは大体HTMLメールなのですが、これが結構な曲者です。HTMLメールはブラウザ以上に互換性が低く、色々な罠があります。

　RailsではActionMailerがHTMLメールをサポートしていますが、あまり深いところは助けてくれません。そこでいくつかのツールを合わせて解決して見ます。

## HTMLメールの罠
- CSSの挙動がブラウザと異なる場合がある
- メール用のResponsive CSSを用意する必要がある
- CSSは`class`ではなく、`style`でインライン展開する
- Asset pipelineを使うにはちょっと細工が必要
- [HTMLメールを作るにあたって知っておきたいこと](http://qiita.com/Altech/items/22e3b1e59f74af4e4067)にまとまっています


## メール用CSSフレームワーク

 ブラウザでは[bootstrap](http://qiita.com/tags/bootstrap)や[Foundation](http://qiita.com/tags/foundation)など、レスポンシブCSSフレームワークが流行しています。HTMLメール向けもブラウザ向けほど数は多くありませんが、同じようなフレームワークがリリースされています。

　HTMLメールはそれほど表現力は高くないので、ブラウザのCSSフレームワークに比べて能力の差は大きくありません。


## Foundation for Emails 2.0

　今回は[Foundation for Email](http://foundation.zurb.com/emails.html)を使って見ます。前はZurb Inkと呼ばれていました。

　Foundation for EmailはSCSSで構築されているので、[sass-rails](https://github.com/rails/sass-rails)を使いましょう。CSSよりSCSSの方がカスタマイズしやすいのでオススメです。

### Railsに導入する

　Foundation for EmailのGemはないので、`sass-rails`だけを`Gemfile`に追加します

```Gemfile
gem 'sass-rails', '~> 5.0'
```

　続いてFoundation for Emailをダウンロードします。
https://github.com/zurb/foundation-emails/releases から最新版をダウンロードして適当なフォルダに展開します。使うのは`SCSS`ディレクトリだけなので、これを`assets`の下に移動します。

```
mkdir $(RAILS_ROOT)/assets/stylesheets/mailer
mv $(解凍したディレクトリ)/scss $(RAILS_ROOT)/assets/stylesheets/mailer/foundation
```

次にMailerで使うSCSSファイルを作ります。

```$(RAILS_ROOT)/assets/stylesheets/mailer/common.scss
@import "_foundation-custom";
@import "foundation/foundation-emails";

// 以下に好きなSCSSを書いてね & 例
.footer {
  hr {
    width: 94%;
    margin: 40px auto 10px auto;
    height: 2px;
    background-color: #dddddd !important;
    border: 0 !important;
  }
  p, a {
    font-size: 12px;
    color: #cccccc !important;
  }
}
```

```$(RAILS_ROOT)/assets/stylesheets/mailer/_foundation-custom.scss

// _global.scssを参考にFoundationをカスタマイズ
$primary-color: #ff0000;
```

　最後にlayoutファイルを準備します。[公式にテンプレート](https://github.com/zurb/foundation-emails-template)を参考にしました

```app/views/layouts/mailer.html.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
    <%= stylesheet_link_tag "mailer/common", media: "all" %>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width">
    <title><%= yield :title %></title>
  </head>
  <body>
    <%= yield %>
    <!-- prevent Gmail on iOS font size manipulation -->
    <div style="display:none; white-space:nowrap; font:15px courier; line-height:0;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>
  </body>
</html>
```

　これで、あとはFoundation for Emailのマニュアルに沿ってHTMLを書いて行ってください。

　HTMLメールでは未だにレイアウトのために`<table>`タグを使います。気持ち悪いですがそういうものだと思うしかないみたいです。


## HTMLの最適化

　HTMLメールの問題は、HTMLの問題とCSSの問題があります。CSSの側の問題はCSSフレームワークで解決できますが、HTMLの書き方の問題が残っています。

　一番大きな問題はgmailがclassをサポートしないため、全てのタグにstyleで指定する必要があることでしょう。

　Railsではこの問題を解決するために [premailer-rails](https://github.com/fphilipe/premailer-rails)を使います。
このGemでは`style`への展開以外に不必要なアトリビュートの削除などを行ってくれます。


## 画像の扱い

　HTMLメールの扱いの面倒な事の一つに画像の扱いがあります。添付ファイルにして`<img src="cid:.."/>`で指定する方法と、BASE64でエンコードして`<img src="data:image/jpeg;base64.."/>`という風にHTMLに含めてしまう方法があります。
　後者の方が楽なのですがOutlookでは表示されないため、前者を使う方が再現性が高いようです。

　その場合は下記のようにして、Mailerの方で`attachments[]`に表示したい画像ファイルを追加し、`.html.erb`の方では`attachments[n].url`を使って指定します。

```foo_mailer.rb
class FooMailer < ActionMailer::Base
  def email
    attachments['banner.png'] = File.read(Rails.root.join('app/assets/images/banner.png'))
  end
end
```

```email.html.erb
<%= image_tag attachments['banner.png'].url, class: 'banner' %>
```

## メールの確認

　HTMLメールが正しく表示されているのか、各種クライアントで確認するのは大変です。そこでメールのレンダリングを一覧で確認できるWebサービスを使います。

　一番有名なのは[Litmus](https://litmus.com)だと思いますが、$99/mo〜(2016/12末現在)とちょっとお高めです。無料や低価格の同種のサービスはないようです。