6

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.

Community
  • 1
  • 1
Tim Whitcomb
  • 10,447
  • 3
  • 35
  • 47
  • 1
    Just to ask a dumb question: Is this functionality available through the UI? If not (and I've never found it), then it might just be impossible programmatically as well. – MarnixKlooster ReinstateMonica Feb 29 '12 at 07:22
  • Not a dumb question at all - I've been trying it through the UI without much luck. However, http://help.lockergnome.com/office/set-meeting-organizer--ftopict697177.html seems to think that it's possible by messing with PR_RECIPIENT_FLAGS. – Tim Whitcomb Feb 29 '12 at 15:48

1 Answers1

0

According to this page, you can send meeting requests on behalf of another person, but you need to have access to that person's calendar. The other person must appoint you as a delegate.

Roland Smith
  • 42,427
  • 3
  • 64
  • 94
  • That's correct. The first step given there is to "Open the other person's calendar." I can do that manually, but is there a way to automate that? – Tim Whitcomb Mar 12 '12 at 15:29
  • Using the exchange API: http://docs.activestate.com/activepython/2.4/pywin32/exchange.html? – Roland Smith Mar 12 '12 at 19:38