I am experimenting with sending emails using Python. I have run into a problem where I cannot send plain text and html in the body, only one or the other. If I attach both parts, only the HTML shows up, and if I comment out the HTML part, then the plain text shows up.
I'm not sure why the email can't contain both. The code looks like this:
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
username = 'email_address'
password = 'password'
def send_mail(text, subject, from_email, to_emails):
assert isinstance(to_emails, list)
msg = MIMEMultipart('alternative')
msg['From'] = from_email
msg['To'] = ', '.join(to_emails)
msg['Subject'] = subject
txt_part = MIMEText(text, 'plain')
msg.attach(txt_part)
html_part = MIMEText("<h1>This is working</h1>", 'html')
msg.attach(html_part)
msg_str = msg.as_string()
with smtplib.SMTP(host='smtp.gmail.com', port=587) as server:
server.ehlo()
server.starttls()
server.login(username, password)
server.sendmail(from_email, to_emails, msg_str)
server.quit()
I actually believe according to 7.2 The Multipart Content-Type what you coded is correct and the email client chooses whichever it believes is "best" according to its capabilities, which generally is the HTML version . Using 'mixed' causes both versions to be displayed serially (assuming the capability exists). I have observed in Microsoft Outlook that the text version becomes an attachment.
To see both serially:
Instead of:
msg = MIMEMultipart('alternative')
use:
msg = MIMEMultipart('mixed')
The server.ehlo()
command is superfluous.