0

I am trying to reply to an email via python and win32com. Below is my code :

    outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
    o = win32com.client.Dispatch("Outlook.Application")
    inbox = outlook.GetDefaultFolder(6)
    messages = inbox.Items


    for message in messages:
        if message.Subject == "aaa":
            print("Found message")             
            message.body="This is a reply"        
            message.Reply()

The reply is getting sent to the sender of "aaa" but the previous email on which I am trying to reply does not appear below the new email.The history of emails on which I am replying gets lost.

Poorva M
  • 43
  • 1
  • 6

1 Answers1

2

I do not have the means to test this, but from the code you shared, I think the problem is as follows:

you iterate over messages and each found MailItem is assigned the loop variable "message". Next you set the body of message as "This is a reply" - in other words: You overwrite the original message with the new string and then send the reply. .Reply() then simply creates a new MailItem object from message, just with Sender and Recipient Properties switched... and the new body you yourself assigned it.

https://learn.microsoft.com/en-gb/office/vba/api/outlook.mailitem.reply(method)

EDIT:

So I made this code:

import win32com.client as win32

outlook = win32.Dispatch("Outlook.Application").GetNamespace("MAPI")
acc = outlook.Folders("myemail@provider.com")
inbox = acc.folders("Inbox")   #change to localized versions
drafts = acc.folders("Drafts") #if necessary

def createReply(email:object):
        reply = email.Reply()
        newBody = "Dear friend,\n\nThis should be added on top.\nI hope this 
                   works\n\nkr\ntst\n"
        reply.HTMLBody = newBody + reply.HTMLBody
        reply.Move(drafts)

for mailItem in inbox.Items:
        if mailItem.Subject == "Test4Reply":
                print("Start")
                createReply(mailItem)

First, I sent an email to myself with the Subject line "Test4Reply" so I can grab that. I added some gibberish into the Email body, just to check if it gets retained. Then, I created a new MailItem Object reply from the email in my inbox using the .Reply() Method, which I then moved (with .Move()) into my Drafts folder. There I can inspect it and see that, indeed, the original email is preserved in the history, as well as the Subject line automatically gaining the "AW: " prefix.

So: To preserve the original email, you just need to make sure to not overwrite the original Body and only insert new text at the beginning of the MailItem.HTMLBody.

tst
  • 371
  • 1
  • 11
  • You are right. I tried creating new email object but do not see any means for reply to an email keeping previous conversations intact. Reply()/ReplyAll() do not take new email object I created as argument.Not sure if win32com can suffice my requirement. – Poorva M Dec 12 '19 at 12:19
  • I will be at my workstation in a bit, I can try it out and do some tests then. `Reply()` should not send the email yet though, right? According to the docs, it only creates a new MailItem object which you then have to send by calling `.Send` – tst Dec 12 '19 at 12:23
  • Already appreciating your help. I tried for message in messages: if message.Subject == "aaa": newMessage=message.Reply() newMessage.body="Body in reply" newMessage.Send() but it did the same as in original question :( – Poorva M Dec 12 '19 at 12:49
  • I managed to get it to work. I updated the answer with my code. – tst Dec 12 '19 at 13:00
  • You can concat the existing body with a new body, unfortunately that destroys all the formatting. I have not been able to get Python to read the `MailItem.Body` as HTML, it only seems to support plain text. So while the reply itself has the proper formatting, once you add to the string, it turns everything into plain text. – tst Dec 12 '19 at 14:23
  • 1
    Hey! Thanks it worked. It at least retained the previous mail. A little better formatting after I concatenated my MailItem.HTMLBody.Will still have to do the manipulation in the mail body to make it look like its actually an email chain.Appreciate your help..Cheers! – Poorva M Dec 12 '19 at 17:47
  • 1
    Oh... yeah I just figured it out. The HTMLBody is literally all you need. I added to my code in the above answer! Obviously the linebreaks in my `newBody`string dont show, because it now should be HTML formatted, not plain text. – tst Dec 13 '19 at 06:45