pyramid_mailer `Message` and `Content-Transfer-Encoding`

247 views Asked by At

I'm sending emails with pyramid_mailer and found this weird issue that when I use Office365 as my SMTP server it adds random = characters into my message. I don't get that issue with any other mail server (I tested this with gmail and also with my own postfix server)

I send emails like below:

from pyramid_mailer.mailer import Mailer

from pyramid_mailer.message import Attachment, Message

mailer = Mailer()
mailer.smtp_mailer.hostname = "test.mail.at.office365"
mailer.smtp_mailer.username = "my_user"
mailer.smtp_mailer.password = "secret"
mailer.smtp_mailer.port = 587
mailer.smtp_mailer.tls = True

message = Message(
    subject="Test",
    sender="my_user@my_domain.com",
    recipients="test_user@test_domain.com",
    body="very long text, at least 75 characters long so Office 365 will break it and insert annoying '=' into message",
    html="very long text, at least 75 characters long so Office 365 will break it and insert annoying '=' into message",
)

mailer.send_immediately(message)

I searched on google and found this has something to do with line breaks and Transfer-Content-Encoding. And indeed, if I add \r\n every ~50 characters I won't see = added. But the problem is that I might want to send a hyperlink that will be longer than that...

Pyramid documentation (https://docs.pylonsproject.org/projects/pyramid_mailer/en/latest/) says I can use Attachment rather than plain string. And indeed as soon as I do that I can set this Transfer-Content-Encoding to something like base64 (as suggested here: https://jeremytunnell.com/2009/01/04/really-hairy-problem-with-seemingly-random-crlf-and-spaces-inserted-in-emails/) but my message then shows as attachment, not as regular message...

There seems to be no way to add this Transfer-Content-Encoding to Message object... I tried to use Message.extra_headers = {'Transfer-Content-Encoding': 'base64'} but this did not help.

I'm totally out of ideas, would appreciate any help...


-- Edit --

Thanks to answer below from @Mess:

from pyramid_mailer.message import Attachment
my_message = "very long text, at least 75 characters long so Office 365 will break it and insert annoying '=' into message"
body_html = Attachment(data=my_message, transfer_encoding="base64", disposition='inline')
body_text = Attachment(data=my_message, transfer_encoding="base64", disposition='inline')

Then pass body_html and body_text to Message constructor.

1

There are 1 answers

0
MeSS On BEST ANSWER

This is "Content-Disposition" header you need to set to control how the content is available to the recipient.

Set it to "attachment" to let download the file, use "inline" to be able to include the content, for example a logo, directly to your email, etc:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition

I hope it will point you to the right direction.

EDIT:

Using pyramid_mailer package it would be something like:

from pyramid_mailer.message import Attachment
attachment = Attachment(data=some_data, transfer_encoding="base64", disposition='inline')