I am trying to reply to an email using Python 3.4. The recipient of the email will be using Outlook (unfortunately) and it is important that Outlook recognizes the reply and displays the thread properly.
The code I currently have is:
def send_mail_multi(headers, text, msgHtml="", orig=None):
"""
"""
msg = MIMEMultipart('mixed')
# Create message container - the correct MIME type is multipart/alternative.
body = MIMEMultipart('alternative')
for k,v in headers.items():
if isinstance(v, list):
v = ', '.join(v)
msg.add_header(k, v)
# Attach parts into message container.
# According to RFC 2046, the last part of a multipart message, in this case
# the HTML message, is best and preferred.
body.attach(MIMEText(text, 'plain'))
if msgHtml != "": body.attach(MIMEText(msgHtml, 'html'))
msg.attach(body)
if orig is not None:
msg.attach(MIMEMessage(get_reply_message(orig)))
# Fix subject
msg["Subject"] = "RE: "+orig["Subject"].replace("Re: ", "").replace("RE: ", "")
msg['In-Reply-To'] = orig["Message-ID"]
msg['References'] = orig["Message-ID"]+orig["References"].strip()
msg['Thread-Topic'] = orig["Thread-Topic"]
msg['Thread-Index'] = orig["Thread-Index"]
send_it(msg['From'], msg['To'], msg)
get_reply_message
is removing any attachments as in this answer. send_it
function sets the Message-ID header and uses the proper SMTP configuration. Then it calls smtplib.sendmail(fr, to, msg.as_string())
msg.attach(MIMEMessage(...))
Any ideas on how to do this? Have I missed any headers?
Cheers,
Andreas
To send the mail you use smtpObj to connect to the SMTP server on the local machine. Then use the sendmail method along with the message, the from address, and the destination address as parameters (even though the from and to addresses are within the e-mail itself, these are not always used to route the mail).
Python offers a ` library to send emails- “SMTP lib”. “smtplib” creates a Simple Mail Transfer Protocol client session object which is used to send emails to any valid email id on the internet. The Port number used here is '587'. And if you want to send mail using a website other than Gmail.
Took me a while but the following seems working:
def send_mail_multi(headers, text, msgHtml="", orig=None):
"""
"""
msg = MIMEMultipart('mixed')
# Create message container - the correct MIME type is multipart/alternative.
body = MIMEMultipart('alternative')
for k,v in headers.items():
if isinstance(v, list):
v = ', '.join(v)
msg.add_header(k, v)
# Attach parts into message container.
# According to RFC 2046, the last part of a multipart message, in this case
# the HTML message, is best and preferred.
if orig is not None:
text, msgHtml2 = append_orig_text(text, msgHtml, orig, False)
# Fix subject
msg["Subject"] = "RE: "+orig["Subject"].replace("Re: ", "").replace("RE: ", "")
msg['In-Reply-To'] = orig["Message-ID"]
msg['References'] = orig["Message-ID"]#+orig["References"].strip()
msg['Thread-Topic'] = orig["Thread-Topic"]
msg['Thread-Index'] = orig["Thread-Index"]
body.attach(MIMEText(text, 'plain'))
if msgHtml != "":
body.attach(MIMEText(msgHtml2, 'html'))
msg.attach(body)
send_it(msg)
def append_orig_text(text, html, orig, google=False):
"""
Append each part of the orig message into 2 new variables
(html and text) and return them. Also, remove any
attachments. If google=True then the reply will be prefixed
with ">". The last is not tested with html messages...
"""
newhtml = ""
newtext = ""
for part in orig.walk():
if (part.get('Content-Disposition')
and part.get('Content-Disposition').startswith("attachment")):
part.set_type("text/plain")
part.set_payload("Attachment removed: %s (%s, %d bytes)"
%(part.get_filename(),
part.get_content_type(),
len(part.get_payload(decode=True))))
del part["Content-Disposition"]
del part["Content-Transfer-Encoding"]
if part.get_content_type().startswith("text/plain"):
newtext += "\n"
newtext += part.get_payload(decode=False)
if google:
newtext = newtext.replace("\n","\n> ")
elif part.get_content_type().startswith("text/html"):
newhtml += "\n"
newhtml += part.get_payload(decode=True).decode("utf-8")
if google:
newhtml = newhtml.replace("\n", "\n> ")
if newhtml == "":
newhtml = newtext.replace('\n', '<br/>')
return (text+'\n\n'+newtext, html+'<br/>'+newhtml)
The code needs a little bit tiding up but as is Outlook displays it correctly (with Next/Previous options). There was no need to create From, Send, To, Subject
headers by hand, appending the content worked.
Hope this saves someone else's time
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