0

I am trying to send an email using Python smtplib.

My objective is to include the below info in email

  1. Attachment file #works fine

  2. Paste the contents of a table in message body #works fine

  3. Write a few lines about the table (as text) in message body # not works. instead stores as an attachment

So, I tried the below code

message = MIMEMultipart()
message['Subject'] = 'For your review - files'
message['From'] = 'user2@org.com'
message['To'] = 'user1@org.com'
# code to paste table contents in outlook message window - works fine
body_content = output # this has the pretty table - html table
message.attach(MIMEText(body_content, "html"))
# code to paste the written text in outlook message window - not works. instead of writing the text in outlook body,it stores as an attachment
written_text = """\
    Hi,
    How are you?"""
message.attach(MIMEText(written_text, "plain"))
# code to attach an csv file to a outlook email - works fine
with open(filename, "rb") as attachment:
    part = MIMEBase("application", "octet-stream")
    part.set_payload(attachment.read())
    encoders.encode_base64(part)
part.add_header(
"Content-Disposition",
f"attachment; filename= {filename}",
)
message.attach(part)
msg_body = message.as_string()
server = SMTP('internal.org.com', 2089)
server.sendmail(message['From'], message['To'], msg_body)
print("mail sent successfully")
server.quit()

The problem in my code is that it creates a text file (containing the message "Hi, How are you") and sends as an attachment?

But I want "Hi, How are you" as a text message in the main Outlook message window.

tripleee
  • 175,061
  • 34
  • 275
  • 318
The Great
  • 7,215
  • 7
  • 40
  • 128
  • Is this question useful for you? https://stackoverflow.com/questions/3362600/how-to-send-email-attachments – Gonzalo Odiard Apr 01 '22 at 18:41
  • @GonzaloOdiard - Thanks for theblink.As you can see in my code, I already have everything done as provided in other link. But the problem is, since I have two seperate parts to body followed by attachment section, it treats my 2nd body part as attachment as well. Is this something you can help me resolve please? – The Great Apr 02 '22 at 00:24
  • @TheGreat Your email needs to be MIMEMultipart. – Oli Apr 02 '22 at 13:24
  • @Oli - you can see at the top of my code that I have already used MIMEMultipart. If possible, can write as an answer – The Great Apr 02 '22 at 13:58

1 Answers1

1

The immediate problem is that many email clients assume that text body parts after the first are attachments. You can experiment with adding an explicit Content-Disposition: inline to the part(s) you want rendered as part of the main message, but is there a reason these need to be separate body parts in the first place? Combining the text fragments into a single body part would perhaps make more sense here.

More fundamentally, your email code was written for an older Python version. The email module in the standard library was overhauled in Python 3.6 to be more logical, versatile, and succinct; new code should target the (no longer very) new EmailMessage API. Probably throw away this code and start over with modern code from the Python email examples documentation.

from email.message import EmailMessage

message = EmailMessage()
message['Subject'] = 'For your review - files'
message['From'] = 'user2@org.com'
message['To'] = 'user1@org.com'

message.set_content(output, subtype="html")

written_text = """\
    Hi,
    How are you?"""
message.add_attachment(
    written_text, subtype="plain",
    disposition="inline")

with open(filename, "rb") as attachment:
    message.add_attachment(
        attachment.read(),
        maintype="application", subtype="octet-stream",
        filename=filename)

with SMTP('internal.org.com', 2089) as server:
    server.send_message(message)
    print("mail sent successfully")
    server.quit()

If the final attachment is really a CSV file, specifying it as application/octet-stream is a bit misleading; the proper MIME type would be text/csv (see also What MIME type should I use for CSV?)

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • but the problem is when I use send_message, it has prpblem sending it to multiple receipients. It doesn't send to them – The Great May 02 '22 at 13:06
  • Your example only shows one recipient. A common solution is `message["To"] = ", ".join(["recipient@example.net", "other@example.org"])` – tripleee May 02 '22 at 16:05