我的python代码发送到microsoftoutlook的事件邀请不显示事件标题和描述。
if __name__ == "__main__":
sender = PersonInfo("MY NAME", "ID@gmail.com")
rec1= PersonInfo("MY NAME", "ID@outlook.com")
rec2= PersonInfo("NAME", "ID2gmail.com")
recipients = [rec1, rec2]
subject = "Hi"
body = "How is everything?"
dtstart = datetime(2020, 9, 3, 22, 15, 0)
dtend = datetime(2020, 9, 3, 22, 30, 0)
ics = build_cal_event("ImpEvent", "Greeting", sender, recipients, dtstart, dtend) #Creates ICS file
with open("event.ics", 'w') as f:
f.write(ics)
SendCalendarInvite(sender, recipients, subject, body, ics)
build_cal_event
如下(为简洁起见,省略了部分代码):
def build_cal_event(event_name, event_description, \
organizer, attendees,\
dtstart, dtend):
# cal = icalendar.Calendar()
str_list = []
str_list.append('''\
BEGIN:VCALENDAR
METHOD:REQUEST
..........
END:VEVENT
END:VCALENDAR
'''.format(datetime.now().strftime("%Y%m%dT%H%M%SZ")))
cal = ''.join(str_list)
return cal
它生成以下ICS文件(替换ID和名称以保持机密性):
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:myOrgName
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Eastern Standard Time
BEGIN:STANDARD
DTSTART:16010101T020000
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=11
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010101T020000
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=2SU;BYMONTH=3
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
ORGANIZER;CN=ID:mailto:ID@gmail.com
ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=ID:
mailto:ID@outlook.com
ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=ID:
mailto:ID@gmail.com
DESCRIPTION;LANGUAGE=en-US:impevent
UID:81d19fd7-833d-4d56-8d2d-1a343dee77b1
SUMMARY;LANGUAGE=en-US:ImpEvent
DTSTART;TZID=Eastern Standard Time:20200903T221500
DTEND;TZID=Eastern Standard Time:20200903T223000
CLASS:PUBLIC
PRIORITY:5
DTSTAMP:20200903T215335Z
TRANSP:OPAQUE
STATUS:CONFIRMED
SEQUENCE:0
LOCATION;LANGUAGE=en-US:
X-MICROSOFT-CDO-APPT-SEQUENCE:0
X-MICROSOFT-CDO-OWNERAPPTID:2118692743
X-MICROSOFT-CDO-BUSYSTATUS:TENTATIVE
X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
X-MICROSOFT-CDO-ALLDAYEVENT:FALSE
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-CDO-INSTTYPE:0
X-MICROSOFT-ONLINEMEETINGEXTERNALLINK:
X-MICROSOFT-ONLINEMEETINGCONFLINK:
X-MICROSOFT-DONOTFORWARDMEETING:FALSE
X-MICROSOFT-DISALLOW-COUNTER:FALSE
X-MICROSOFT-LOCATIONS:[]
BEGIN:VALARM
DESCRIPTION:REMINDER
TRIGGER;RELATED=START:-PT15M
ACTION:DISPLAY
END:VALARM
END:VEVENT
END:VCALENDAR
这个
SendCalendarInvite
功能如下:
def SendCalendarInvite(sender, recipients, subject, body, ics=None):
aws_region = "us-east-1"
client = boto3.client('ses',region_name=aws_region)
msg = MIMEMultipart('mixed')
msg["Subject"] = subject
msg["From"] = sender.email
msg["To"] = ', '.join(map(lambda x: x.email, recipients))
msg["Content-class"] = "urn:content-classes:calendarmessage"
ics_name = "{}.ics".format(subject.replace(" ", "_").upper())
part_email = MIMEText(body,"html")
part_cal = MIMEText(ics,'calendar;method=REQUEST')
msgAlternative = MIMEMultipart('alternative')
msg.attach(msgAlternative)
ics_name = "{}.ics".format(subject.replace(" ", "_").upper())
ical_atch = MIMEBase('text', 'calendar', **{'method' : 'REQUEST', 'name' : ics_name})
ical_atch.set_payload(ics)
ical_atch.set_type('text/calendar; charset=UTF-8; method=REQUEST; component = VEVENT')
encoders.encode_base64(ical_atch)
ical_atch.add_header('Content-Type', 'text/calendar')
ical_atch.add_header('charset', 'UTF-8')
ical_atch.add_header('component', 'VEVENT')
ical_atch.add_header('method', 'REQUEST')
ical_atch.add_header('Content-class', 'urn:content-classes:calendarmessage')
ical_atch.add_header('Content-Disposition', "attachment; filename={}".format(ics_name))
ical_atch.add_header('Content-ID', 'calendar_message')
ical_atch.add_header('Content Description', ics_name)
ical_atch.add_header("Filename", ics_name)
ical_atch.add_header("Path", ics_name)
eml_atch = MIMEText('', 'plain')
encoders.encode_base64(eml_atch)
eml_atch.add_header('Content-Transfer-Encoding', "")
msgAlternative.attach(part_email)
msgAlternative.attach(part_cal)
try:
result = client.send_raw_email(
Source=msg['From'],
Destinations=[recipient.email for recipient in recipients],
RawMessage={'Data': msg.as_string()}
)
except ClientError as e:
print(e.response['Error']['Message'])
else:
print("Email sent! Message ID:"),
print(result['MessageId'])
gmail收件人是这样看待邀请的:
看起来不错。
Outlook收到的邀请中缺少事件名称和事件说明。如何确保Outlook正确处理由我的代码发送的事件邀请并显示事件名称和说明?
mime电子邮件如下所示:
Content-Type: multipart/mixed; boundary="===============1597738219983052864=="
MIME-Version: 1.0
Subject: Hi
From: ID@gmail.com
To: ID@outlook.com, ID@gmail.com
Content-class: urn:content-classes:calendarmessage
--===============1597738219983052864==
Content-Type: multipart/alternative; boundary="===============6779992366809651548=="
MIME-Version: 1.0
--===============6779992366809651548==
Content-Type: text/html; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
How is everything?
--===============6779992366809651548==
MIME-Version: 1.0
Content-Type: text/calendar; method="REQUEST"; charset="us-ascii"
Content-Transfer-Encoding: 7bit
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:OrgName
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Eastern Standard Time
BEGIN:STANDARD
DTSTART:16010101T020000
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=11
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010101T020000
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=2SU;BYMONTH=3
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
ORGANIZER;CN=MYNAME:mailto:ID@gmail.com
ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=MYNAME:
mailto:MYNAME@outlook.com
ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=NAME:
mailto:ID@gmail.com
DESCRIPTION;LANGUAGE=en-US:impevent
UID:f250a41d-84c0-4f12-be83-38d2d51f5586
SUMMARY;LANGUAGE=en-US:ImpEvent
DTSTART;TZID=Eastern Standard Time:20200903T221500
DTEND;TZID=Eastern Standard Time:20200903T223000
CLASS:PUBLIC
PRIORITY:5
DTSTAMP:20200904T122939Z
TRANSP:OPAQUE
STATUS:CONFIRMED
SEQUENCE:0
LOCATION;LANGUAGE=en-US:
X-MICROSOFT-CDO-APPT-SEQUENCE:0
X-MICROSOFT-CDO-OWNERAPPTID:2118692743
X-MICROSOFT-CDO-BUSYSTATUS:TENTATIVE
X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
X-MICROSOFT-CDO-ALLDAYEVENT:FALSE
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-CDO-INSTTYPE:0
X-MICROSOFT-ONLINEMEETINGEXTERNALLINK:
X-MICROSOFT-ONLINEMEETINGCONFLINK:
X-MICROSOFT-DONOTFORWARDMEETING:FALSE
X-MICROSOFT-DISALLOW-COUNTER:FALSE
X-MICROSOFT-LOCATIONS:[]
BEGIN:VALARM
DESCRIPTION:REMINDER
TRIGGER;RELATED=START:-PT15M
ACTION:DISPLAY
END:VALARM
END:VEVENT
END:VCALENDAR
--===============6779992366809651548==--
--===============1597738219983052864==--
编辑2:
DESCRIPTION;LANGUAGE=en-US:impevent