如何将原始电子邮件中的 mimedata 附件块转换为文件? (红宝石)

Posted

技术标签:

【中文标题】如何将原始电子邮件中的 mimedata 附件块转换为文件? (红宝石)【英文标题】:How to turn a mimedata attachment block from raw email into a file? (in ruby) 【发布时间】:2018-07-02 10:06:11 【问题描述】:

我们审核我们发出的电子邮件,以便稍后我们可以访问原始电子邮件文本。对于带有附件的电子邮件,我可以看到这样的 mimepart 部分:

--mimepart_5a65f317c19d2_24515571f0306fc12617a
Content-Type: application/pdf; name=CMI-1Y-120628-38895.pdf
Content-Transfer-Encoding: Base64
Content-Disposition: attachment; filename=CMI-1Y-120628-38895.pdf

JVBERi0xLjQKJeLjz9MKMyAwIG9iaiA8PC9UeXBlL1hPYmplY3QvQ29sb3JT
cGFjZS9EZXZpY2VHcmF5L1N1YnR5cGUvSW1hZ2UvQml0c1BlckNvbXBvbmVu
dCA4L1dpZHRoIDMwMC9MZW5ndGggNTI3My9IZWlnaHQgMjYwL0ZpbHRlci9G
bGF0ZURlY29kZT4+c3RyZWFtCnic7Z15YA3XGsC/EEFQKrb2WVISUi2JrbFU
aWyxvKKx11LUUlu1SCyhPPqaerQo2nqW1kMVr9UnfUijqZ3aW2KLUGt5QcQS
JDLvzjkz986ZOffec+XefHMbvz/izsw5kzM/NzNnzvIdADdS76PVI1qUducZ

....about 800 lines of text like this...

MCBuIAowMDAwMDM4MjczIDAwMDAwIG4gCjAwMDAwMzgzMTggMDAwMDAgbiAK
dHJhaWxlcgo8PC9Sb290IDEyIDAgUi9JRCBbPGIyNjEwYmQyZmM3ZGQyZTI0
NzQxYzg2M2VkOWU4NTBkPjwxY2JiNDIzYWZmMWVjY2U2MGRhNmJjMmE4ZjZl
MTBjNT5dL0luZm8gMTMgMCBSL1NpemUgMTQ+PgpzdGFydHhyZWYKMzg0NTUK
JSVFT0YK

--mimepart_5a65f317c19d2_24515571f0306fc12617a

我想做的是让查看此电子邮件记录的管理员可以选择“重建”附件。所以,当他们点击“查看附件”按钮时,我会使用数据来构建一个文件(使用上面标题中的文件名),然后将其返回给他们。

问题是,如何把它变成一个文件?有问题的附件始终是 PDF 文件,因此如果有一个仅适用于 pdf 的解决方案,那很好,但更通用的解决方案将是首选。

我正在使用 Ruby on Rails,因此 ActiveMailer 中可能已经有一个函数可以执行此操作...

编辑:如果有人想尝试使用一些真实数据,我制作了一个 PDF,其中只有一些大字母文本,并将其附加到电子邮件中。下面的链接指向一个包含来自该电子邮件的所有原始数据的文本文件,其中包含text/plaintext/htmlapplication/pdf 部分。您的挑战是将application/pdf mimepart 转换为 pdf 文件,并告诉我它在说什么(更重要的是,发布一个答案,说明您做了什么)。谢谢!

https://www.dropbox.com/s/u3kt5sdl6b44fms/raw_email.txt?dl=0

【问题讨论】:

【参考方案1】:

事实证明这比我想象的要容易。

算法:

从该 mimepart 获取文本块(即没有 mimepart 边界) base64 解码 将结果写入 filename.pdf

太明显了,我什至没有尝试过!

特别是在 Ruby 中:我相信您可以比这更简洁、更安全。

text = File.read("/home/max/raw_email.txt")
boundary_line = text.grep(/boundary\=mimepart/).first.chomp
mimepart_divider = "--#boundary_line.split("boundary=").last"
mimeparts = text.split(mimepart_divider)
mimepart = mimeparts.grep(/application\/pdf/).first
filename = mimepart.grep(/filename\=/).first.chomp.split("filename=").last
mimedata = mimepart.split("\n\n").compact_blank.last
decoded = Base64.decode64(mimedata)
File.open("#ENV['HOME']/#filename","w")|f| f.puts decoded

【讨论】:

以上是关于如何将原始电子邮件中的 mimedata 附件块转换为文件? (红宝石)的主要内容,如果未能解决你的问题,请参考以下文章

如何将 msg 中的附件附加到 Mime 以在 Python 中作为电子邮件发送?

Lotus Notes电子邮件作为另一封电子邮件的附件

Biztalk:包含映射到 CSV 的电子邮件的 XML,作为附件发送

Zend Framework:如何阅读电子邮件附件(并保存到磁盘)?

如何从电子邮件中获取 csv 附件并保存

将 MimeMessage 对象消息转发为 EML 文件中附件的常规转发格式