【发布时间】:2018-06-13 19:50:24
【问题描述】:
尝试通过 python 自动发送 Outlook 日历邀请。我可以发送电子邮件并附上邀请;但是,邀请是“不支持的日历 message.ics”。在过去的两周里,我一直在试图弄清楚如何做到这一点。我什至尝试过使用 win32com.client;但是该软件包无法让您像我使用posted about here 那样从单独的帐户发送电子邮件。
以下是我用来生成和发送“不支持的日历 message.ics”的代码:
# email related imports
import smptlib
import email
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email import Encoders
# calendar related imports
import icalendar
from icalendar import Calendar, Parameters, Todo
from icalendar.prop import vDatetime, vCalAddress, vText, vInt, vBoolean, vDDDTypes
import uuid
#other imports
import pytz
from datetime import datetime, date, time, timedelta
# set people parameters
sender = 'thing1@example.com'
recipients = 'thing2@example.com'
attendee = vCalAddress(recipients)
attendee.params['cn'] = vText('Thing 1')
attendee.params['RSVP'] = vText('TRUE')
organizer = vCalAddress(sender)
organizer.params['cn'] = vText('Thing 2')
the_sender = vCalAddress(sender)
the_sender.params['cn'] = vText('Thing 2')
# set timing parameters
location = 'Home'
tz = pytz.timezone("US/Pacific") # timezone to use for our dates -- change
as needed
appt_time = tz.localize(datetime(2018, 1, 31, 12, 0))
duration = 30
reminder_min = 15
# set info parameters
subject = 'My Cool Event'
description = 'this better work!'
summary = 'python calendar invite testing'
# create calendar object
cal = icalendar.Calendar()
cal.add('prodid', vText('-//Microsoft Corporation//Outlook 16.0 MIMEDIR//EN'))
cal.add('version', vInt(2.0))
cal.add('method', vText('REQUEST'))
cal.add('X-MS-OLK-FORCEINSPECTOROPEN', vBoolean(True)) # creates one instance of the event
# create the timezone
tz = icalendar.Timezone()
tz.add('tzid', vText('Pacific Standard Time'))
cal.add_component(tz)
# create the calendar event
event = icalendar.Event()
event.add('method', vText('REQUEST'))
event.add('tzid', vText('Pacific Standard Time'))
event.add('attendee', attendee, encode=0)
event.add('class', vText('PUBLIC'))
event.add('created', vDDDTypes(datetime.now()))
event.add('description', vText(description))
event.add('dtend', vDDDTypes((appt_time + timedelta(minutes = duration))))
event.add('dtstart', vDDDTypes(appt_time))
event.add('location', vText(location))
event.add('from', the_sender)
event.add('organizer', the_sender)
event.add('priority', vInt(5))
event.add('sequence', vInt(0))
event.add('summary', vText(summary))
event.add('transp', vText('opaque')) # Specifies whether or not this appointment is intended to be visible in availability searches
event.add('uid',vText(uuid.uuid4()))
event.add('X-MICROSOFT-CDO-BUSYSTATUS', vText('BUSY')) # sets the busy status of the appointment to busy
event.add('X-MICROSOFT-CDO-IMPORTANCE', vInt(1)) # sets the importance of the appointment (0,1,2)
event.add('X-MICROSOFT-DISALLOW-COUNTER', vBoolean(False))
event.add('X-MS-OLK-APPTSEQTIME', vDDDTypes(datetime.now()))
event.add('X-MS-OLK-AUTOFILLLOCATION', vBoolean(False)) # specifies whether the location is being automatically populated with recipients of type RESOURCE.
event.add('X-MS-OLK-CONFTYPE', vInt(0)) # specifies the type of conferencing that is enabled on the appointment
# set an alarm for a reminder notice
alarm = icalendar.Alarm()
alarm.add("action", "DISPLAY")
alarm.add('description', "Reminder")
alarm.add("TRIGGER;RELATED=START", "-PT{0}M".format(reminder_min))
event.add_component(alarm)
cal.add_component(event)
# write calendar event to file
open('PythonCalendarEvent_1.ics', 'w').writelines(cal.to_ical())
# generate message with (Multi-Purpose Internet Mail Extensions)
msg = MIMEMultipart('mixed')
msg["Subject"] = subject
msg["From"] = sender
msg['To'] = recipients
# attach calendar invite to email message
filename = "PythonCalendarEvent_1.ics"
cal_part = MIMEBase('text', 'calendar', **{'method' : 'REQUEST', 'name' : filename})
cal_part.set_payload(open(filename,"rb").read())
cal_part.set_type('text/calendar; charset=UTF-8; method=REQUEST; component = VEVENT')
email.Encoders.encode_base64(cal_part)
cal_part.add_header('Content-Type', 'text/calendar')
cal_part.add_header('charset', 'UTF-8')
cal_part.add_header('component', 'VEVENT')
cal_part.add_header('method', 'REQUEST')
cal_part.add_header('Content-class', 'urn:content-classes:appointment')
cal_part.add_header('Content-ID', 'calendar_message')
cal_part.add_header('Content Description', filename)
cal_part.add_header("Filename", filename)
cal_part.add_header("Path", filename)
msg.attach(cal_part)
# send the email at last
s = smtplib.SMTP(_insert_host_as_string_here_)
s.sendmail(sender, recipients, msg.as_string())
s.quit()
另一个有趣的注意事项:如果邀请被转发,则 ics 被识别。例如,我生成要发送给自己的电子邮件,然后我将其作为“不支持的日历 message.ics”接收。如果我随后将邀请转发给我的同事,他会将其视为常规日历邀请。我测试了这是否只是我的安装;但是,他复制了代码并遇到了同样的问题——第一条消息未被识别,但转发给我的邀请却被识别。
如果我需要进一步澄清,请告诉我。
【问题讨论】:
标签: python-2.7 email outlook icalendar