我正在使用以下代码在rails中发送电子邮件:
class InvoiceMailer < ActionMailer::Base
def invoice(invoice)
from CONFIG[:email]
recipients invoice.email
subject "Bevestiging Inschrijving #{invoice.course.name}"
content_type "multipart/alternative"
part "text/html" do |p|
p.body = render_message 'invoice_html', :invoice => invoice
end
part "text/plain" do |p|
p.body = render_message 'invoice_plain', :invoice => invoice
end
pdf = Prawn::Document.new(:page_size => 'A4')
PDFRenderer.render_invoice(pdf, invoice)
attachment :content_type => "application/pdf", :body => pdf.render, :filename => "factuur.pdf"
invoice.course.course_files.each do |file|
attachment :content_type => file.content_type, :body => File.read(file.full_path), :filename => file.filename
end
end
end
这对我来说似乎很好,电子邮件也会在Gmail网络界面中显示出来 . 但是,在Mail(Apple程序)中,我只得到1个附件(应该有2个附件)并且没有文本 . 我似乎无法弄清楚是什么导致了它 .
我从日志中复制了电子邮件:
Sent mail to xxx@gmail.com
From: yyy@gmail.com
To: xxx@gmail.com
Subject: Bevestiging Inschrijving Authentiek Spreken
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary=mimepart_4a5b035ea0d4_769515bbca0ce9b412a
--mimepart_4a5b035ea0d4_769515bbca0ce9b412a
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: Quoted-printable
Content-Disposition: inline
Dear sir
=
--mimepart_4a5b035ea0d4_769515bbca0ce9b412a
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: Quoted-printable
Content-Disposition: inline
Dear sir
* Foo=
--mimepart_4a5b035ea0d4_769515bbca0ce9b412a
Content-Type: application/pdf; name=factuur.pdf
Content-Transfer-Encoding: Base64
Content-Disposition: attachment; filename=factuur.pdf
JVBERi0xLjMK/////woxIDAgb2JqCjw8IC9DcmVhdG9yIChQcmF3bikKL1By
b2R1Y2VyIChQcmF3bikKPj4KZW5kb2JqCjIgMCBvYmoKPDwgL0NvdW50IDEK
... ... ...
MCBuIAp0cmFpbGVyCjw8IC9JbmZvIDEgMCBSCi9TaXplIDExCi9Sb290IDMg
MCBSCj4+CnN0YXJ0eHJlZgo4Nzc1CiUlRU9GCg==
--mimepart_4a5b035ea0d4_769515bbca0ce9b412a
Content-Type: application/pdf; name=Spelregels.pdf
Content-Transfer-Encoding: Base64
Content-Disposition: attachment; filename=Spelregels.pdf
JVBERi0xLjQNJeLjz9MNCjYgMCBvYmoNPDwvTGluZWFyaXplZCAxL0wgMjEx
NjYvTyA4L0UgMTY5NTIvTiAxL1QgMjEwMDAvSCBbIDg3NiAxOTJdPj4NZW5k
... ... ...
MDIwNzQ4IDAwMDAwIG4NCnRyYWlsZXINCjw8L1NpemUgNj4+DQpzdGFydHhy
ZWYNCjExNg0KJSVFT0YNCg==
--mimepart_4a5b035ea0d4_769515bbca0ce9b412a--
8 回答
我怀疑问题在于您将整个电子邮件定义为多部分/替代,建议每个部分只是同一消息的备用视图 .
我使用类似下面的内容发送带附件的混合html /普通电子邮件,它似乎工作正常 .
@jcoleman是正确的,但如果你不想使用他的宝石,那么这可能是一个更好的解决方案:
此代码首先创建以下MIME层次结构:
multipart/related
multipart/alternative
text/html
text/plain
image/png
在调用
mail
之后,我们创建一个新的multipart/related
部分并添加现有部分的子项(在我们去的时候删除它们) . 然后我们强制Content-Type
为multipart/mixed
并继续添加附件,以及生成的MIME层次结构:multipart/mixed
multipart/related
multipart/alternative
text/html
text/plain
image/png
application/pdf
向James致敬,因为它帮助我让我们的邮件工作正常 .
稍微改进一下:首先,我们使用块中的块参数来添加部分(当我没有时,我遇到了问题) .
此外,如果要使用布局,则必须直接使用#render . 这是两个原则在工作中的一个例子 . 如上所示,您需要确保最后保留html部分 .
此示例使用选项哈希创建包含附件和布局的通用多部分消息,您可以像这样使用:
(我们实际上并没有这样做:让每个邮件程序为您填写很多这些详细信息更好,但我认为这样可以更容易理解代码 . )
希望有所帮助 . 祝你好运 .
问候,丹
Rails 3以不同的方式处理邮件 - 虽然简单的情况更容易,但是为多部分电子邮件添加正确的MIME层次结构,其中包含备选内容类型和(内联)附件相当复杂(主要是因为所需的层次结构非常复杂 . )
Phil的答案似乎有效 - 但由于MIME层次结构仍然不正确,因此iPhone(以及可能还有其他设备)上的附件不可见 .
正确的MIME层次结构最终看起来像这样:
multipart/mixed
multipart/alternative
multipart/related
text/html
image/png
(例如,对于内联附件; pdf将是另一个很好的例子)text/plain
application/zip
(例如附件 - 不是内联的)我发布了一个有助于支持正确层次结构的gem:https://github.com/jcoleman/mail_alternatives_with_attachments
通常,在使用ActionMailer 3时,您将使用以下代码创建消息:
使用此gem创建包含备选方案和附件的电子邮件,您将使用以下代码:
Note: My technique below works in some instances. However, when combined with inline images, it will cause the attachment to not show on iPhone Mail, and perhaps on other clients. 有关完整的解决方案,请参阅下面的jcoleman答案 .
值得注意的是,Rails现在处理这个问题,至少从 3.1rc4 开始 . 从ActionMailer指南:
诀窍是在触发问题中提到的三个替代问题之后添加附件 before ,您调用
mail
-添加附件 .Rails 3 Solution, multipart alternative email (html and plain) with pdf attachment, no inline attachments
以前我的电子邮件只显示了pdf附件,当它们在ios中打开时,或者在osx上的mail.app中都没有明文或html . Gmail从来都不是问题 .
我使用与Corin相同的解决方案,但我不需要内联附件 . 这让我走得很远 - 除了一个问题 - mail.app / iOS邮件显示纯文本不是html . 这是(如果最终发生)因为替代部分的顺序,首先是html然后是文本(为什么这应该是决定性的打败我,但无论如何) .
所以我不得不再做一次改变,相当愚蠢,但它确实有效 . 添加.reverse!方法 .
所以我有
Rails 4 solution
在我们的项目中,我们向客户发送包含公司徽标(内联附件)和PDF(常规附件)的电子邮件 . 我们采用的解决方法类似于@ user1581404提供的解决方法 .
然而,在将项目升级到Rails 4后,我们必须找到一个新的解决方案,因为在调用
mail
命令后不再允许您添加附件 .我们的邮件程序有一个基本邮件程序,我们通过覆盖邮件方法修复此问题:
N.B. Rails 3.2 solution.
就像这些多部分电子邮件一样,这个答案有很多部分,所以我会相应地剖析:
@ Corin的“混合”方法中的plain / html格式的顺序很重要 . 我发现html后面的文字给了我所需的功能 . 因人而异
设置Content-Disposition为nil(删除它)修复了iPhone / iOS附件查看其他答案中表达的难点 . 此解决方案已经过测试,适用于Outlook for Mac,Mac OS / X Mail和iOS Mail . 我怀疑其他电子邮件客户端也可以正常工作 .
与以前版本的Rails不同,附件处理与广告一样有效 . 我最大的问题通常是由尝试旧的解决方法引起的,这些解决方案只能为我解决问题 .
希望这可以帮助别人避免我的陷阱和死胡同 .
工作代码: