Question

I'm trying to open an email add some text to it and forward it using python windows extensions.

This is what I have:

import win32com.client

outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI") 

inbox = outlook.GetDefaultFolder(6).Folders('SUBFOLDER')
messages = inbox.Items
message = messages.GetLast()
NewMsg = message.Forward()
NewMsg.To = "email@email.com" #I want to forward it to this address
NewMsg.Body = "New Text"+NewMsg.Body

When I copy something to the front of the email doing this: NewMsg.Body = "New Text"+NewMsg.Body, it breaks all the hyperlinks in the original message and removes the original formatting. Is there anyway I could keep the original formatting(bolded/colored words/hyperlinks) and add new text?

Was it helpful?

Solution

In the Outlook Object Model, the Body property of a [MailItem] represents "the clear-text body of the Outlook item".

There's a separate RTFBody property that represents "the body of the Microsoft Outlook item in Rich Text Format."

If you rewrite either one of these, it re-creates the other. The way this works doesn't seem to be documented very clearly in OOM, but the MAPI equivalent, PidTagBody/PR_RTF_COMPRESSED explains it:

When PR_BODY is stored for the first time, the message store also generates and stores the PR_RTF_COMPRESSED (PidTagRtfCompressed) property, the RTF version of the message text. If the IMAPIProp::SaveChanges method is subsequently called and PR_BODY has been modified, the message store calls the RTFSync function to ensure synchronization with the RTF version. If only white space has been changed, the properties are left unchanged.

So, if you make any changes besides whitespace to Body, RTFBody may be re-created from scratch. And there's nothing you can do about that.


There's a third property, HTMLBody, that will probably be a lot easier to edit in Python than RTFBody, whether by using stdlib solutions like ElementTree or third-party libraries like BeautifulSoup.

It isn't clearly documented anywhere what kinds of changes can break exact round-tripping, but it's not too hard to test (and most of the changes you'd want to make won't have any visible effect, even if they do change the details of the RTF, which may be good enough).

Or, maybe better, you can just force the converted-and-edited HTML to be the primary representation of the message instead of the RTF, by setting BodyFormat to olFormatHTML. That way, you'll know that what gets delivered is exactly the same HTML that you see in your code.


If you need to actually edit the RTFBody, you can. It's an array of bytes representing the possibly-compressed and definitely-encoded RTF. You have to call StrConv on it to convert it to a Unicode RTF string, and then you have to process that as RTF. You can do this in pure Python if you want (see the RTF spec), or using a third-party library, but there are also COM APIs for that that you can find by searching MSDN.

There is one last possibility to consider: You can always create and automate a message editor window. This is horribly hacky, but it does guarantee that you're doing exactly the same thing as if a user copied and pasted into the email manually…

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top