Rails 4/5发送带有附件的动态ActionMailer::Base.mail邮件,标记为无名。

3

我看了一些类似的帖子,大多数都涉及通过创建视图和控制器发送附件,例如:

PDF附件在电子邮件中被称为“Noname”

但是我有一个在后台动态生成文件并需要使用ActionMailer::Base.mail将其附加到接收者列表的过程。以下是代码:

def send_email(connection)
    email = ActionMailer::Base.mail(to: connection['to'], from: connection['from'], subject: 'Sample File', body: "<p>Hello,</p><p>Your data is ready</p>", content_type: 'multipart/mixed')
    email.cc = connection['cc'] if connection['cc'].present?
    email.bcc = connection['bcc'] if connection['bcc'].present?
    @files.each do |file|
      report_file_name = "#{@start_time.strftime('%Y%M%dT%I%m%s')}_#{file[0]}.xlsx"
      file_location = "#{Rails.root}/tmp/#{report_file_name}"
      email.attachments[report_file_name] = File.open(file_location, 'rb'){|f| f.read}
    end
    email.deliver if email
  end

我可以在日志中看到它正在发送内容,但是假定它是作为“Noname”发送的,因为它找不到视图。有什么方法可以成功地使其工作?
以下是样本输出:
已发送邮件至sample@sample.com(383.9ms)日期:Thu,13 Oct 2016 08:47:30 -0400发件人:Sample收件人:Recipient消息ID:<57ff326270f15_421f1173954919e2@ulinux.mail>主题:示例文件Mime-Version:1.0内容类型:multipart/mixed; charset=UTF-8内容传输编码:7bit
-- 内容类型:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; filename=20161012T08101476259208_Data.xlsx内容传输编码:base64内容分配:attachment; filename=20161012T08101476259208_Data.xlsx内容ID:<57ff326270f15_421f1173954919e2@ulinux.mail>
UEsDBBQAAAAIAO.. ... ...ADUFQAAAAA=
更新-我注意到如果我使用电子邮件.content_type ='text/plain' -附件将成功通过。对我来说,这起作用了,尽管我希望以后能够使用HTML样式化我的电子邮件。
我认为这起作用是因为它防止Rails进行其通常的提取/自动解释过程。虽然我确实希望在此处看到一个multipart/mixed或html兼容版本。
更新2-这只是在rails_email_preview gem中人为地修复了问题,在开发中将电子邮件呈现到新标签中。在生产中,这仅仅是可以理解的打印细节和可能是base64编码的文件,所以问题仍然存在。

我现在也遇到了同样的问题?有关于如何修复它的任何消息吗? - Jimmy Huang
3个回答

0

你可能没有 mailer.text.erb 文件,只有 mailer.html.erb 文件。 添加它,你的邮件将会是多部分的。


0

这让我疯狂了。 如果您使用邮件视图,请确保拥有一个格式良好的 .html 模板和一个 .text 模板。

任何一个模板中的最小错误都会使整个电子邮件成为无名称附件。


0
我也遇到了这个问题,经过一些调查,似乎在Rails 4中,你不能在调用mail方法后调用attachments方法,否则邮件消息对象的content_type将没有边界信息,因此无法正确解析接收到的电子邮件中的附件部分。
我认为深入研究actionmailer源代码,你应该能够找到一个解决方案,可以通过覆盖默认的mail方法或手动设置正确的边界信息来实现。
但是为了快速解决这个问题,我想出了一个不太优雅的解决方法,使用元编程:定义一个继承ActionMailer::Base的委托类。
class AnyMailer < ActionMailer::Base
  # a delegation mailer class used to eval dynamic mail action
end

然后使用定义任意方法来执行电子邮件发送,对该类进行评估。

def send_email(connection, files)
  AnyMailer.class_eval do
    def any_mailer(connection, files)
      files.each do |file|
        report_file_name = :foo
        file_location = :bar
        attachments[report_file_name] = File.open(file_location, 'rb'){|f| f.read}
      end
      mail(to: connection['to'], from: connection['from'], subject: 'Sample File', body: "<p>Hello,</p><p>Your data is ready</p>")
    end
  end

  AnyMailer.any_mailer(connection, files).deliver_now
end

注意,您不需要将content_type指定为“multipart/mixed”,ActionMailer会正确处理它。我曾尝试过显式指定它,但结果是电子邮件内容混乱。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接