Ruby
mail
Gem
mime
multipart

mail gemで添付ファイルを付けてみたら

Rails環境とは言え、普通の配信ルート以外でメールを作成する必要があったので、mail gemを直接使ってみたのですが、1箇所ハマってしまいました。

メール作成時の書式について

今回の件とは直接関係ないですが、mail gemは、メールの各要素を指定するにあたって、各種の記法に対応しています。

# Readmeから引用

# 宣言的な書き方
mail = Mail.new do
  from    'mikel@test.lindsaar.net'
  to      'you@test.lindsaar.net'
  subject 'This is a test email'
  body    File.read('body.txt')
end

# 代入
mail['from'] = 'mikel@test.lindsaar.net'
mail[:to]    = 'you@test.lindsaar.net'
mail.subject = 'This is a test email'

説明の進めやすさの関係上、箇所によって書式が違うことがありますが、本質的な違いはありません。

添付ファイルを付けたら…!

もともとのコードとして、Hashに入ったメールの各要素を、ループを回してMailオブジェクトに入れていました。

mail = Mail.new
hash.each { |key, val| mail[key] = val }

そして、こうして作った後に、mail.attachments = { 'filename.ext' => content }のようにしたところ、事件が起きました。ファイルはついたものの、bodyが消滅してしまったのです。

Multipurpose Internet Mail Extensions

よく「MIMEタイプ」と言われますが、そのMIMEを略さずに書くと上のようになります。もともとメールが発祥だったのです。

そして、メールにファイルを添付するとか、HTMLとテキストの両方を入れるなどは、multipartという仕組みになっています。

今回の件の対策

メールがmultipartになったのであれば、正しくtext_partとして本文を投げ込めば通るかなと試してみたら、無事成功しました。

mail.text_part = Mail::Part.new { body hash[:body] }