Sending to Exchange: How to Disable Disable Lossy Conversion of HTML to RTF?
Question: I have a python script which sends a multipart email with text, html, and ics
attachments. The idea is that a modern email client will render the HTML part
and offer to add the event to the user's calendar.

Code looks like:

    
    
    import smtplib
    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText
    from icalendar import Calendar, Event, UTC, vText, vCalAddress
    # ... set up calendar invite, render text and html templates ...
    msg = MIMEMultipart('alternative')
    msg_text = MIMEText(body_text, 'plain', 'utf-8')
    msg_html = MIMEText(body_html, 'html', 'utf-8')
    meeting = MIMEText(cal.as_string(), 'calendar;method=REQUEST', 'utf-8')
    meeting.set_param('method', 'REQUEST')
    meeting.set_param('name', 'meeting.ics')
    meeting.add_header('Content-class', 'urn:content-classes:calendarmessage')
    # ... set up various message attributes: to/from/subject ...
    msg.add_header('Content-class', 'urn:content-classes:calendarmessage')
    msg.attach(msg_text)
    msg.attach(msg_html)
    msg.attach(meeting)
    s = smtplib.SMTP(smtp_server)
    s.sendmail(sender, send_to, msg.as_string())
    

This works: I get the message, it is displayed as HTML, and I can easily add
the event to my calendar in Outlook and Mac Mail. However, the HTML is broken.
Here is the telltale in the HTML:

    
    
    <meta name="Generator" content="Microsoft Exchange Server">
    <!-- converted from rtf -->
    

Here is what I know so far:

  * If I drop the calendar attachment, the HTML makes it through without conversion.
  * I can only get the calendar invite to work if I attach it to the message last.

So, something about having the calendar invite attached causes Exchange to
mess up my HTML message. Is there maybe a header I can add to the message or
the HTML to ask Microsoft to pretty please not convert my HTML to RTF?


Answer: Outlook only works with RTF when it comes to appointments, tasks and contacts.
If a meeting invitation comes with an HTML body, it gets converted to RTF.

UPDATE: as of Outlook 2016, this is no longer the case: Outlook now natively
supports HTML for the appointments and tasks. HTML is stored in PR_HTML (or
RTF-wrapped HTML in PR_RTF_COMPRERSSED), and you can specify the format just
like with regular email messages. It is still not exposed on the Outlook
Object Model level unfortunately - there is no AppointmentItem.HTMLBody
property yet.

