1

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()
Saar Koren
  • 25
  • 1
  • 7

1 Answers1

2

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.

Booboo
  • 38,656
  • 3
  • 37
  • 60
  • Thank you, that got it working! Do you know why the alternative subtype does not work? From what I read, it is used to indicate that it is the same content but in different formats, so it makes sense that you would have two different formats. – Saar Koren Sep 29 '20 at 12:46
  • 2
    In fact `multipart/alternative` should be the correct solution here, not `multipart/mixed`. I can speculate that you are using something braindead on the receiving end (Outlook?) – tripleee Sep 29 '20 at 13:03
  • @tripleee Yes, I have update my answer with a better explanation. – Booboo Sep 29 '20 at 13:04
  • Okay, I read your updated explanation and that makes sense. I was using the Gmail client, I guess it prefers HTML over plain text. – Saar Koren Sep 29 '20 at 14:00