Rails 4/5发送动态ActionMailer :: Base.mail电子邮件附件标记为Noname [英] Rails 4/5 Sending Dynamic ActionMailer::Base.mail email With Attachment labeled Noname

查看:178
本文介绍了Rails 4/5发送动态ActionMailer :: Base.mail电子邮件附件标记为Noname的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看过类似的帖子,主要是通过创建视图和控制器来发送附件,例如:



电子邮件中的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>您的数据就绪< / 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如果电子邮件
结束

我可以在日志中看到它发送的内容,但假设它作为Noname发送,因为它找不到视图。任何方式让它成功工作?



以下是示例输出:


发送邮件到sample@sample.com(383.9ms)日期:
星期三,十月13日08:47:30 -0400从:样品到:
收件人消息ID:
< 57ff326270f15_421f1173954919e2@ulinux.mail>主题:样本文件
Mime版本:1.0 Content-Type:multipart / mixed; charset = UTF-8
Content-Transfer-Encoding:7bit



- 内容类型:application / vnd.openxmlformats-officedocument.spreadsheetml.sheet;
filename = 20161012T08101476259208_Data.xlsx
Content-Transfer-Encoding:base64 Content-Disposition:attachment;
filename = 20161012T08101476259208_Data.xlsx Content-ID:
< 57ff326270f15_421f1173954919e2@ulinux.mail>



UEDBBQAAAAIAO .. ... ... ADUFQAAAAA =


更新 - 我注意到如果我使用email.content_type ='text / plain'成功通过。对于我来说,这是有用的,虽然后来可以使用HTML来形容我的电子邮件,但我很欣赏。



我认为这是有效的,因为它阻止了Rails从它的通常的清理/自动解释过程。我一定想看到一个多部分/混合或html兼容的版本在这里工作。



更新2 这仅仅是人为地修复了问题宝石,它将电子邮件呈现在开发中的新选项卡上。 rails_email_preview 在生产中,这个简单可以理解的打印细节和大概是base64编码的文件,所以问题保持开放。

解决方案

我有遇到这个问题,经过一番调查,似乎在Rails 4中,调用邮件方法后,您无法调用附件方法,否则邮件对象的content_type将被赢取没有边界信息,所以附件部分无法在收到的电子邮件中正确解析。



我想挖掘actionmailer的源代码,你应该能够找到一个解决方案,通过覆盖默认的邮件方法或设置正确的边界信息手动。



但是为了快速解决这个问题,我想到了一个不太优雅的工作:使用元编程:定义一个继承ActionMailer :: Base的委托类。

  class AnyMailer< ActionMailer :: Base 
#一个用于评估动态邮件操作的委托邮件类
end



  def send_email(connection,files)
AnyMailer.class_eval do
def any_mailer(连接,文件)
files.each do | file |
report_file_name =:foo
file_location =:bar
附件[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>您的数据就绪< / p>)
end
end

AnyMailer.any_mailer(连接,文件).deliver_now
注意,您不需要将content_type指定为multipart / mixed,ActionMailer将会妥善处理。我试图明确地指定它,而是搞砸电子邮件内容。


I've taken a look at similar posts that mostly deal with sending an attachment by creating a view and controller, such as:

PDF attachment in email is called 'Noname'

but I've got a process that generates files in the background dynamically and need to attach it to a recipient list using ActionMailer::Base.mail. Below is the code:

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

I can see in the logs that it's sending with the content but assume it's sending as Noname because it can't find the view. Any way to get this to work successfully?

Below is the sample output:

Sent mail to sample@sample.com (383.9ms) Date: Thu, 13 Oct 2016 08:47:30 -0400 From: Sample To: Recipient Message-ID: <57ff326270f15_421f1173954919e2@ulinux.mail> Subject: Sample File Mime-Version: 1.0 Content-Type: multipart/mixed; charset=UTF-8 Content-Transfer-Encoding: 7bit

-- Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; filename=20161012T08101476259208_Data.xlsx Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename=20161012T08101476259208_Data.xlsx Content-ID: <57ff326270f15_421f1173954919e2@ulinux.mail>

UEsDBBQAAAAIAO.. ... ...ADUFQAAAAA=

Update - I noticed if I use email.content_type = 'text/plain' - the attachment comes through successfully. For me, this works, though I'd appreciate later being able to style my emails with HTML

I presume this works because it prevents Rails from its usual gleaning/autointerpreting process. I'd certainly like to see a multipart/mixed or html compatible version work here though.

Update 2 This only fixed the issue artificially in the rails_email_preview gem, which renders the emails to a new tab in development. In production, this simply and understandably prints the details and the presumably base64-encoded file, so question remains open.

解决方案

I have meet this problem too, after some investigation, it seems in Rails 4, you can't call attachments method after calling mail method, otherwise the content_type of the mail message object won't have boundary information so that the attachments part can't be parsed correctly in the received email.

I think digging into the actionmailer source code and you should be able to find a solution, either by override the default mail method or set the correct boundary info manually.

But for quick resolving this problem, I thought out a not elegant work around by using meta programming: define a delegation class which inherits ActionMailer::Base.

class AnyMailer < ActionMailer::Base
  # a delegation mailer class used to eval dynamic mail action
end

Then eval this class with defining an arbitrary method to perform the email sending.

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

Attention, you don't need to specify the content_type as 'multipart/mixed', ActionMailer will handle it correctly. I tried to specify it explicitly but get messed up email content instead.

这篇关于Rails 4/5发送动态ActionMailer :: Base.mail电子邮件附件标记为Noname的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆