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

mail gemで、Content-Type: multipart/mixedとしたいけどならないときの対処法

mail gem使って、multipartメールでかつファイルが添付されたメールを送信したら、 Content-Type: multipart/mixedではなくContent-Type: multipart/alternativeになってしまい、 Thunderbirdでは添付ファイルが認識されず、MacメーラーではHTML本文が表示されない自体となってしまった。 別におかしなことはしていなくて、 https://github.com/mikel/mail のREADME通り、

@mail = Mail.new do
  to      'nicolas@test.lindsaar.net.au'
  from    'Mikel Lindsaar <mikel@test.lindsaar.net.au>'
  subject 'First multipart email sent with Mail'

  text_part do
    body 'Here is the attachment you wanted'
  end

  html_part do
    content_type 'text/html; charset=UTF-8'
    body '<h1>Funky Title</h1><p>Here is the attachment you wanted</p>'
  end

  add_file '/path/to/myfile.pdf'
end 

のようにしてたのだけど、なぜかダメだった。 で、issues漁っていたら、 https://github.com/mikel/mail/issues/590 が見つかって、そこで紹介されている https://gist.github.com/steve500002/bfc4b027d93c0c04f126 のようにしたら、Content-Type: multipart/mixed で送信されるようになった。

mail=Mail.new do |mail|
  to      'reipient@example.com'
  from    'Fred Flintstone <fred@flintstones.com>'
  subject 'Multipart email with attachment'
end

# Remember to end the plain text with a few blank lines. iOS devices often display the content of the attachments so you want to force them to go below the text

# Create the text and html as separate mail parts
text_body = Mail::Part.new do
    body "This is the message\n\n"
    content_type 'text/plain; '
end
html_body  = Mail::Part.new do
    body "<h1>This is HTML</h1>"
    content_type 'text/html; charset=UTF-8'
end

# Create a mail part to hold the html and plain text
bodypart = Mail::Part.new
bodypart.text_part = text_body
bodypart.html_part = html_body

# Add the html and plain text to the email
mail.add_part bodypart

# Add the attachment(s)
attachment = "../path/to/doc.pdf"
mail.attachments["#{File.basename(attachment)}"] = File.read(attachment)

いったん、 bodypart = Mail::Part.new として、 その後、 mail.add_part bodypartするのがポイント。