I've developed a Python application to automate sending emails and meeting requests for internal office events. To keep these separate from my regular communications, we've set up an alternate email address that I can use to send the official announcements. I've modified my application to handle this for emails by using the SentOnBehalfOfName
for the alternate sender - however, I haven't been able to duplicate this for meeting requests. My attempt based on a series of web searches follows. When running this, though, I get the error:
Traceback (most recent call last):
File "mailer_test.py", line 49, in <module> test_sender)
File "mailer_test.py", line 38, in send_meeting_request
mtg.Send()
File "<COMObject CreateItem>", line 2, in Send
pywintypes.com_error: (-2147024809, 'The parameter is incorrect.', None, None)
This happens when I add in the option for an alternate sender - removing this results in the message sent successfully from my account. The test code which reproduces the error is below - I've removed my actual email address, but everything else is the same.
import win32com.client
OUTLOOK_APPOINTMENT_ITEM = 1
OUTLOOK_MEETING = 1
OUTLOOK_ORGANIZER = 0
OUTLOOK_OPTIONAL_ATTENDEE = 2
ONE_HOUR = 60
THIRTY_MINUTES = 30
OUTLOOK_FORMAT = '%m/%d/%Y %H:%M'
outlook_date = lambda dt: dt.strftime(OUTLOOK_FORMAT)
class OutlookClient(object):
def __init__(self):
self.outlook = win32com.client.Dispatch('Outlook.Application')
def send_meeting_request(self, subject, time, location, recipients, body,
sender=None):
mtg = self.outlook.CreateItem(OUTLOOK_APPOINTMENT_ITEM)
mtg.MeetingStatus = OUTLOOK_MEETING
mtg.Location = location
if sender:
# Want to set the sender to an address specified in the call
# This is the portion of the code that does not work
organizer = mtg.Recipients.Add(sender)
organizer.Type = OUTLOOK_ORGANIZER
for recipient in recipients:
invitee = mtg.Recipients.Add(recipient)
invitee.Type = OUTLOOK_OPTIONAL_ATTENDEE
mtg.Subject = subject
mtg.Start = outlook_date(time)
mtg.Duration = ONE_HOUR
mtg.ReminderMinutesBeforeStart = THIRTY_MINUTES
mtg.ResponseRequested = False
mtg.Body = body
mtg.Send()
if __name__ == "__main__":
import datetime
ol = OutlookClient()
meeting_time = datetime.datetime.now() + datetime.timedelta(hours=3)
test_recipients = ['me@example.com']
test_sender = 'alternate@example.com'
ol.send_meeting_request('Test Meeting', meeting_time, 'Nowhere',
test_recipients, 'This is a test meeting.',
test_sender)
Note: This is not the same problem as this question, since I'm not using C# and I'm also not trying to edit the meeting request after the fact.
Update:
As Marnix Klooster suggested, I've been looking through the UI to see how I can do this, and it doesn't appear to be easy (if even possible). The one way I have done it is to go into the other user's calendar and create a new appointment there and add invitees. That mailbox is added by going to the Advanced
tab from the More Settings...
button in the Server Settings dialog displayed when changing the Account Settings
. An alternate answer to this question would be how to use this mailbox as the default originator when accessing Outlook via COM.