如何替换/覆盖EmailMultiAlternatives的默认标头

时间:2019-05-14 16:19:40

标签: python django email-attachments amazon-ses email-headers

环境:Ubuntu 18.10,Python 2.7.15,Django 1.11.16

我正在尝试发送包含嵌入式图像的电子邮件。我有以下代码:

msg = EmailMultiAlternatives(some_subject, some_body, 'from@some-domain.com', ['to@some@domain'])

img_data = open('path/to/image.png', 'rb').read()
img = MIMEImage(img_data)
msg.attach(img)

msg.send()

(我只包含了我认为相关的代码,但是我可以根据需要添加更多代码。)

以上操作正常,并且图像在我测试过的大多数电子邮件客户端(大约有7个,无论是移动,台式机还是Webmail客户端)上均正确显示,但以下两个例外:Mozilla Thunderbird 60和一些macOS本机电子邮件客户。

在Thunderbird上,图像不是内嵌显示,而是在消息末尾显示。在macOS客户端上,该图像以内联方式显示,但除此之外,它也显示在消息的末尾。

我撰写并从另一个电子邮件客户端发送了一条测试消息,其中包含一个内嵌图像,该图像已正确显示在Thunderbird和macOS上。我将此消息的标题与我的代码生成的消息的标题进行了比较。

我注意到错误的消息将'Content-Type'设置为'multipart/mixed',而正确显示的消息将相同的标头设置为'multipart/related'

我将错误消息保存在eml文件中,并手动更改了该标头的值,然后将消息加载到Thunderbird中。该消息已正确显示,并且图像位于正确的位置。

如果我可以将标题设置为适当的值,那么该问题将得到解决。

所以,我的问题是:是否有可能告诉EmailMultiAlternatives设置'Content-Type' : 'multipart/related'而不是默认值'multipart/mixed'

我试图这样添加标题,但是它不起作用:

msg = EmailMultiAlternatives(some_subject, some_body, 'from@some-domain.com', ['to@some@domain'], headers={'Content-Type' : 'multipart/related'})

我收到以下错误(我使用Amazon SES):

400 Bad Request
<ErrorResponse xmlns="http://ses.amazonaws.com/doc/2010-12-01/">
  <Error>
    <Type>Sender</Type>
    <Code>InvalidParameterValue</Code>
    <Message>Duplicate header 'Content-Type'.</Message>
  </Error>
  <RequestId>xxxxxxxxxx</RequestId>
</ErrorResponse>

如果我无法修改该标题,您是否建议其他选择?

1 个答案:

答案 0 :(得分:1)

如果查看源代码,您会发现EmailMultiAlternativesEmailMessage的子类,它本身具有类属性:

mixed_subtype = 'mixed'

因此,如果您创建自己的子类来覆盖它,则应该获得所需的内容:

class EmailMultiAlternativesRelated(EmailMultiAlternatives):
    mixed_subtype = 'related'

就是这样,现在您只使用这个新类,它将使用“ multipart / related”。

({_create_attachments()方法将此子类型传递给python的SafeMIMEMultipart,它会为每个附件创建实际的标头。)