I saw there are a few somewhat similar questions on stack overflow already, but I couldn't find a solution to my specific problem in them.
I am trying to use Python to send an HTML email with a .pdf attachment. It seems to work fine when I check my email on gmail.com, but when I check the message through apple's Mail program, I do not see the attachment. Any idea what is causing this?
My code is below. A lot of it is copied from various places on stack overflow, so I do not completely understand what each part is doing, but it seems to (mostly) work:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
from os.path import basename
import email
import email.mime.application
#plain text version
text = "This is the plain text version."
#html body
html = """<html><p>This is some HTML</p></html>"""
# Create message container - the correct MIME type is multipart/alternative.
msg = MIMEMultipart('alternative')
msg['Subject'] = "Deliverability Report"
msg['From'] = "[email protected]"
msg['To'] = "[email protected]"
# Record the MIME types of both parts - text/plain and text/html
part1 = MIMEText(text, 'plain')
part2 = MIMEText(html, 'html')
# create PDF attachment
filename='graph.pdf'
fp=open(filename,'rb')
att = email.mime.application.MIMEApplication(fp.read(),_subtype="pdf")
fp.close()
att.add_header('Content-Disposition','attachment',filename=filename)
# Attach parts into message container.
msg.attach(att)
msg.attach(part1)
msg.attach(part2)
# Send the message via local SMTP server.
s = smtplib.SMTP()
s.connect('smtp.webfaction.com')
s.login('NAME','PASSWORD')
s.sendmail(msg['From'], msg['To'], msg.as_string())
s.quit()
I'm not sure if it is relevant, but I am running this code on a WebFaction server.
Thanks for the help!
For html emails you have to set this in the header of the email content-type: text/html . However, if you want to send an attachment you have to change it to content-type: multipart/mixed . Which would make the html email...not html anymore.
To have text, html and attachments at the same time it is necessary to use both mixed and alternative parts.
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
text = "This is the plain text version."
html = "<html><p>This is some HTML</p></html>"
text_part = MIMEText(text, 'plain')
html_part = MIMEText(html, 'html')
msg_alternative = MIMEMultipart('alternative')
msg_alternative.attach(text_part)
msg_alternative.attach(html_part)
filename='graph.pdf'
fp=open(filename,'rb')
attachment = email.mime.application.MIMEApplication(fp.read(),_subtype="pdf")
fp.close()
attachment.add_header('Content-Disposition', 'attachment', filename=filename)
msg_mixed = MIMEMultipart('mixed')
msg_mixed.attach(msg_alternative)
msg_mixed.attach(attachment)
msg_mixed['From'] = '[email protected]'
msg_mixed['To'] = '[email protected]'
msg_mixed['Subject'] = 'Deliverability Report'
smtp_obj = smtplib.SMTP('SERVER', port=25)
smtp_obj.ehlo()
smtp_obj.login('NAME', 'PASSWORD')
smtp_obj.sendmail(msg_mixed['From'], msg_mixed['To'], msg_mixed.as_string())
smtp_obj.quit()
Message structure should be like this:
Mixed:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With