如何创建多部分电子邮件? [滑轨]

时间:2014-02-27 16:47:15

标签: ruby-on-rails email icalendar email-attachments

我想要实现的目标如下:

发送包含delayed_job的电子邮件,其中包含:

  1. 纯文本
  2. html(将由不理解内联的常规客户显示)
  3. “内联”,由Outlook和Thunderbird(使用Lightning)识别。 Thunderbird Accept/Decline/Tentative Buttons
  4. “常规”附件(#2)
  5. 到目前为止什么有效/什么不对:

    我可以通过delayed_job发送包含所有部分的电子邮件,但是:

      Apple的Mail 2附件中的
    • 显示(而不是一个):

    Apple Mail

    (html显示正常)

      雷鸟(闪电)中的
    • 我收到邀请,就像我想要的那样。但警报没有出现。

    Lightning

    • 为了让ATTENDEES出现,我必须在渲染的iCal上做一些非常恶心的gsubs。 (参见代码段)
    我想:

    首先要记住的是:in order to send an email with attachments from delayed_job

      

    要解决此问题,请记住将此行添加到邮件程序:content_type“multipart / mixed”

    据我所知,correct MIME-Type hierarchy因此是:

    • 多部分/混合
      • 多部分/替代
        • 文本/纯
        • text / html的
        • text / calendar(with:method = REQUEST)
      • 应用/ ICS

    警告!代码传入。

    我目前以下列方式构建此电子邮件:

    编辑:我为Rails 4.2更新了邮件程序(attachments必须放在mail之前)

    在我的mailer.rb

    def invitation_email(...)  
      subject = "I suck at email..."
      attachments["invite.ics"] = { mime_type: "application/ics",
                                    content: ical_attachment }
      email = mail(from: me, to: you, subject: subject)
      add_ical_part_to(email)
      email
    end
    
    def add_ical_part_to(mail)
      outlook_body = ical_attachment
      mail.add_part(Mail::Part.new do
        content_type "text/calendar; method=REQUEST"
        body outlook_body
      end)
    end
    

    这就是我构建attach附件的方式:

    def ical_attachment
      params_participant = {
            "ROLE"   => "REQ-PARTICIPANT",
            "RSVP" => "FALSE",
            "PARTSTAT" => "ACCEPTED"
      }
    
      params_invite = {
            "CUTYPE" => 'INDIVIDUAL',
            "ROLE"   => "REQ-PARTICIPANT",
            "PARTSTAT" => "NEEDS-ACTION",
            "RSVP" => "TRUE"
      }
    
      cal = Icalendar::Calendar.new
    
      event = Icalendar::Event.new
      event.dtstart      @party.from.to_datetime, { "VALUE" => "DATE" }
      event.dtend        @party.to.to_datetime, { "VALUE" => "DATE" }
      event.summary      @party.title
      event.description  @party.description
      event.klass        "PRIVATE"
      event.organizer    "cn=#{@user.name} #{@user.surname}:mailto:#{@user.email}"
    
        # THIS DOES NOT WORK
      event.alarm.trigger =  "-PT5M" # 5 Minutes before...
    
      @party.participations.each do |participation|
            str = "cn=#{participation.user.name} #{participation.user.surname}:mailto:#{participation.user.email}"
            event.add_attendee(str, params_participant)
      end
    
      @party.invitations.each do |invitee|
            event.add_attendee("mailto:#{invitee.email}", params_invite)
      end
      cal.add_event(event)
      cal.publish
    
      # I KNOW THIS IS HORRIBLE AND I HATE IT, BUT OTHERWISE THE ATTENDEES DO NOT SHOW UP
      cal.to_ical.gsub("ORGANIZER:", "ORGANIZER;").gsub("ACCEPTED:", "ACCEPTED;").gsub("TRUE:", "TRUE;").gsub("PUBLISH", "REQUEST")
    end
    

    非常感谢任何帮助!

    正在生成的电子邮件:http://pastebin.com/patf05zd

    哦,我在:

2 个答案:

答案 0 :(得分:2)

如果有其他人碰巧碰到这个,我就是这样做的:

我现在使用icalendar而不是ri_cal gem。虽然我持怀疑态度,因为3年前最后一次对该回购的承诺,google group是一个非常有用的资源。

这是我如何生成ical附件(内联和正常),这似乎工作正常(虽然它显然需要一些重构:))

def to_ical
# this is horrible
klass = self

cal = RiCal.Calendar do
  event = event do
    organizer   "CN=#{klass.user.name} #{klass.user.surname}:mailto:#{klass.user.email}"
    summary     klass.party.title

    description klass.ical_description
    dtstart     klass.party.from.utc.to_datetime
    dtend       klass.party.to.utc.to_datetime
    location    "See url in description"
    security_class klass.security_class

    # this is horrible
    h = self

    klass.party.participations.each do |participation|
      h.add_attendee klass.prepare_participant(participation)
    end

    klass.party.invitations.each do |invitee|
      h.add_attendee klass.prepare_invitee(invitee.email)
    end

    unless klass.party.reminder == 0
      alarm do
        description "Alarm description"
        trigger klass.convert_trigger # -PT1H
        action "DISPLAY"
      end
    end
  end
end

# THE HORROR
cal.to_s.gsub("ATTENDEE:", "ATTENDEE")
        .gsub("ORGANIZER:", "ORGANIZER;")
        .gsub("CALSCALE:GREGORIAN", "CALSCALE:GREGORIAN\nMETHOD:REQUEST\n")

苹果邮件中的2个附件仍然显示,我认为不能修复。

答案 1 :(得分:1)

您的第二个B64编码附件在末尾包含大量垃圾(与会者字段)。 这可以解释Thunderbird问题。

请注意,有些客户会忽略您在申请时可能设置的任何警报:作为组织者,您不应该在每个与会者被提醒会议时提出要求。这将是一件相当粗鲁的事情。

关于Apple iCal问题,我担心的事情并不多:有些客户想要内部的ics,有些客户想要附件,所以你必须提供两者。它是否显示iCal上的接受/拒绝小组?