Search code examples
pythonmultipart

Multipart E-Mail missing or corrupt attachment


I use the following code to send an e-mail with a pdf attachment. For most receivers this works without any issues but some clients show the pdf as corrupt or not at all. Thus I think there is probably something wrong and most clients are just forgiving enough to make it work anyway. Unfortunately, at this point I am out of ideas as I tried so many header combinations - all without success. The pdf is base64 encoded.

def sendMail(receiver, pdf):
    marker = "AUNIQUEMARKER"
    message = """Subject: The Subject
From: {sender}
To: {receiver}
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary={marker}
--{marker}
Content-Type: text/plain; charset="utf-8"

Text goes here.
--{marker}
Content-Type: application/pdf; name="{filename}"
Content-Transfer-Encoding:base64
Content-Disposition: attachment; filename={filename}

{pdfcontent}
--{marker}--
""".format(marker=marker, sender="some@sender.com", receiver=receiver, filename="Test.pdf", pdfcontent=pdf)
    port = 587
    smtp_server = "some.server.com"
    context = ssl.create_default_context()
    with smtplib.SMTP(smtp_server, port) as server:
        server.starttls(context=context)
        server.login("user", "password")
        server.sendmail("some@sender.com", [receiver, "cc@sender.com"], message.encode())

In case it is relevant, the pdf is created via LaTex as follows

pdfl = PDFLaTeX.from_texfile('latex/test.tex')
pdf, log, completed_process = pdfl.create_pdf(keep_pdf_file=False, keep_log_file=False)
pdfBase64 = base64.b64encode(pdf).decode()

Thanks for any help.

PS: Not showing the attachment at all might be fixed as I switched from Content-Type: multipart/alternative to multipart/mixed.


Solution

  • Well, apparently the base64 block should contain a newline every 76 characters. In my case that means I had to switch from base64.b64encode to base64.encodebytes as the latter does exactly this.