Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending a PDF attachment with a HTML+plain_text email in Python

I'm trying to send a PDF attachment with an email body that summarises the contents of the PDF file. The email body is in both HTML and plaintext.

I'm using the following code to build the email email message object:

#Part A
logging.debug("   Building standard email with HTML and Plain Text")
msg = MIMEMultipart("alternative")
msg.attach(MIMEText(email_obj.attachments["plain_text"], "plain", _charset="utf-8"))
msg.attach(MIMEText(email_obj.attachments["html_text"], "html", _charset="utf-8"))

#Part B
logging.debug("   Adding PDF report")
pdf_part = MIMEApplication(base64.decodestring(email_obj.attachments["pdf_report"]), "pdf")
pdf_part.add_header('Content-Disposition', 'attachment', filename="pdf_report.pdf")
logging.debug("   Attaching PDF report")
msg.attach(pdf_part)

My problem is that my email body disappears if I attach the PDF. If I comment out the code that attaches the PDF (Part B), the email body appears.

Unless I'm mistaken, it looks as though my PDF attachment is overwriting the email body.

like image 914
CadentOrange Avatar asked Dec 26 '22 11:12

CadentOrange


1 Answers

Such a message should have a more complex structure. The message itself contains two "top-level" MIME parts and has content-type "multipart/mixed". The first of these MIME part has type of "multipart/alternative" with two subparts, one for plain text and another for HTML. The second of the main parts is PDF attachment

pdfAttachment = MIMEApplication(pdf, _subtype = "pdf")
pdfAttachment.add_header('content-disposition', 'attachment', filename = ('utf-8', '', 'payment.pdf'))
text = MIMEMultipart('alternative')
text.attach(MIMEText("Some plain text", "plain", _charset="utf-8"))
text.attach(MIMEText("<html><head>Some HTML text</head><body><h1>Some HTML Text</h1> Another line of text</body></html>", "html", _charset="utf-8"))
message = MIMEMultipart('mixed')
message.attach(text)
message.attach(pdfAttachment)
message['Subject'] = 'Test multipart message'
f = open("message.msg", "wb")
f.write(bytes(message.as_string(), 'utf-8'))
f.close()

You may try to open a "source view" of a message in your favorite mail program (mail user agent) and see yourself (Ctrl-U in Thunderbird)

like image 54
user3159253 Avatar answered Feb 07 '23 09:02

user3159253