Getting "not supported calendar message.ics" attachment with outlook email invite from Python
Question: Trying to write a python script to send an outlook email invite. Used
instructions from here: <http://www.baryudin.com/blog/sending-outlook-
appointments-python.html> However, I keep getting a "not supported calendar
message.ics" attachemnt with my email. Code is below:

    
    
        import random
    
        import smtplib
    
        import email.MIMEText
        import email.MIMEBase
    
        from datetime import datetime
        from email.MIMEMultipart import MIMEMultipart
    
        import icalendar
    
        from pytz import timezone
    
        LOCAL_TZ = timezone("US/Eastern")
    
        def send_appointment(subject, description):
            start_dt = LOCAL_TZ.localize(datetime(2016, 6, 3, 17, 0, 0))
            end_dt = LOCAL_TZ.localize(datetime(2016, 6, 3, 18, 0, 0))
    
            cal = icalendar.Calendar()
            cal.add("prodid", "-//My oncall calendar application//test.com")
            cal.add("version", "2.0")
            cal.add("method", "REQUEST")
    
            event = icalendar.Event()
            event.add("attendee", MY_EMAIL)
            event.add("organizer", MY_EMAIL)
            event.add("status", "confirmed")
            event.add("summary", subject)
            event.add("description", description)
            event.add("location", "my desk")
            event.add("dtstart", start_dt)
            event.add("dtend", end_dt)
            event.add("dtstamp", start_dt)
            event["uid"] = random.random()
            event.add("priority", 5)
            event.add("sequence", 1)
            event.add("created", LOCAL_TZ.localize(datetime.now()))
    
            alarm = icalendar.Alarm()
            alarm.add("action", "DISPLAY")
            alarm.add("description", "Reminder")
            alarm.add("TRIGGER;RELATED=START", "-PT{0}H".format(1))
            event.add_component(alarm)
    
            cal.add_component(event)
    
            msg = MIMEMultipart("alternative")
            msg["Subject"] = subject
            msg["From"] = MY_EMAIL
            msg["To"] = MY_EMAIL
            msg["Content-class"] = "urn:content-classes:calendarmessage"
    
            msg.attach(email.MIMEText.MIMEText(description))
    
            filename = "invite.ics"
    
            part = email.MIMEBase.MIMEBase("text", "calendar", method="REQUEST",                     name=filename)
            part.set_payload(cal.to_ical())
            email.Encoders.encode_base64(part)
            part.add_header("Content-Description", filename)
            part.add_header("Content-class", "urn:content-classes:calendarmessage")
            part.add_header("Filename", filename)
            part.add_header("Path", filename)
            msg.attach(part)
    
            s = smtplib.SMTP("localhost")
            s.sendmail(MY_EMAIL, MY_EMAIL, msg.as_string())
            s.quit()
    
        def main():
            send_appointment("test", "desc")
    
        if __name__=="__main__":
            main()
    

NOTE: I defined MY_EMAIL but just not putting it here.

The .ics file generated is below.

    
    
        BEGIN:VCALENDAR
        VERSION:2.0
        PRODID:-//My oncall calendar application//test.com
        METHOD:REQUEST
        BEGIN:VEVENT
        SUMMARY:test
        DTSTART;TZID=US/Eastern;VALUE=DATE-TIME:20160603T170000
        DTEND;TZID=US/Eastern;VALUE=DATE-TIME:20160603T180000
        DTSTAMP;VALUE=DATE-TIME:20160603T210000Z
        UID:0.669475599056
        SEQUENCE:1
        ATTENDEE:myemail@somewhere.com
        CREATED;VALUE=DATE-TIME:20160603T204723Z
        DESCRIPTION:desc
        LOCATION:my desk
        ORGANIZER:myemail@somewhere.com
        PRIORITY:5
        STATUS:confirmed
        BEGIN:VALARM
        ACTION:DISPLAY
        DESCRIPTION:Reminder
        TRIGGER;RELATED=START:-PT1H
        END:VALARM
        END:VEVENT
        END:VCALENDAR
    

EDIT: Ok figured out the problem I think. It only understands utc timezone. So
if I changed the start and end datetimes to the following then the I get a
proper calendar invite.

    
    
        start_dt = datetime(2016, 6, 3, 17, 0, 0, tzinfo=pytz.utc)
        end_dt = datetime(2016, 6, 3, 18, 0, 0, tzinfo=pytz.utc)
    

Not entirely sure why it cannot understand other time zones. Looking at the
.ics file, the date time fields look like the following.

    
    
        DTSTART;VALUE=DATE-TIME:20160603T170000Z
        DTEND;VALUE=DATE-TIME:20160603T180000Z
    

as opposed to

    
    
        DTSTART;TZID=US/Eastern;VALUE=DATE-TIME:20160603T170000
        DTEND;TZID=US/Eastern;VALUE=DATE-TIME:20160603T180000
    

The question now is why it cannot handle other timezones but I guess that
should be another post.


Answer: Ok figured out the problem I think. It only understands utc timezone. So if I
changed the start and end datetimes to the following then the I get a proper
calendar invite.

    
    
        start_dt = datetime(2016, 6, 3, 17, 0, 0, tzinfo=pytz.utc)
        end_dt = datetime(2016, 6, 3, 18, 0, 0, tzinfo=pytz.utc)
    

Not entirely sure why it cannot understand other time zones. Looking at the
.ics file, the date time fields look like the following.

    
    
        DTSTART;VALUE=DATE-TIME:20160603T170000Z
        DTEND;VALUE=DATE-TIME:20160603T180000Z
    

as opposed to

    
    
        DTSTART;TZID=US/Eastern;VALUE=DATE-TIME:20160603T170000
        DTEND;TZID=US/Eastern;VALUE=DATE-TIME:20160603T180000
    

