It was a few months ago that I originally wrote the first incarnation of the MailExchange2iCal script. Since then I’ve been in contact with a few users trying to make it work for them and I’ve found a number of peculiarities in the types of email invites sent by Exchange/Outlook. The biggest problem was that the time zone data for the event was improperly formatted. This caused all sorts of problems for Mac users.
Let’s start at the beginning. Sometimes integration of a Mac in the corporate environment is a bit difficult and takes a bit of ingenuity. This is especially true when dealing with Exchange. The current versions of iCal and iCal Server are CalDAV and iCalendar compliant. Only Outlook 2007 is said to be CalDAV and iCalendar compliant. Previous versions of Outlook are not compliant and don’t play well with other calendar applications. Here’s the actual time zone (TZID) spec and the spec for how it should be formatted. You can see by looking at it that the TZID that Outlook produces is non-compliant.
A quick Google search shows an article or two that explain this very well.
I’ve found that there are at least 3 different types of invites that can be sent by Exchange/Outlook.
METHOD:REQUEST
– This is the usual email requesting that you attend a meeting.METHOD:PUBLISH
– This is essentially a publication notice for an event. It doesn’t ask you to reply.METHOD:CANCEL
– This is a cancellation notice for an event.
Additionally, I’ve found that the emails that contain these invites are formated in at least 3 different ways. Sometimes the calendar event is within the body of the message and is encoded with Content-Transfer-Encoding
in either 8bit
or quoted-printable
. Always the .ics
file is attached.
My script does the following:
- It parses the message to either extract the calendar data from the body of the message or from the
.ics
attachment. - It then figures out if the invite is of type
METHOD:REQUEST
,METHOD:PUBLISH
orMETHOD:CANCEL
. - If the invite is one of the first 2 types. The time zone is fixed and the event is imported into iCal. You might have to select into which calendar the event will be imported.
- If the invite is of type
METHOD:CANCEL
then the script will locate the corresponding event and set it’s status to cancelled.
- You will have to manually delete the event. It will appear in iCal to have a white strike-through font style.
- Repeating events all seem to have the same UID (Unique IDentifier).
I don’t know why. Every repeating event will be thusly marked as cancelled. You will then manually delete the specific event and manually run the script again while the cancellation message is selected. This will reset the remaining repeating events back to confirmed. Yes, I know this is a bit of a kludge but I don’t have a better method.
- It will parse the message to allow for invites from multiple Exchange servers.
My script, now re-named iCal-Invite-Fix.scpt
, will need to be customized for each Exchange server from which you receive invites. There are 3 properties at the beginning of the script. They are exchange_fragment
, ical_tzid
and myCalendar
. These first two properties are lists and the order of the items is crucial. The specific item (position in list) of each list must correspond to each other.
exchange_fragment
is a unique fragment of the TZID that your Exchange server sends.ical_tzid
is the time zone of the Exchange server in proper format.- This means no spaces, though spaces are replaced automatically with the underscore ‘_’.
- For instance, I’m in Southern California and the correct time zone should be written as
US/Pacific
orAmerica/Los_Angeles
. You can find this information by selecting the time zone drop down menu in the upper right corner of your iCal window and selectOther...
. If you look in iCal’s upper right corner for the time zone menu bar the last example will appear asAmerica/Los Angeles
. myCalendar
is the name of the calendar that normally receives the events. It is needed for the cancellation to function.
Save the script and either set it up to run from a mail rule or as I do call it from the System AppleScript menu. You will need to save the script in ~/Library/Scripts/Applications/Mail/ folder. Create this folder if it doesn’t exist.
To set the script up to run automatically you will need to create a new Mail rule as follows.
- Mail -> Preferences -> Rules -> Add Rule
- Description “iCal Invite Fix”
- If “any” of the following conditions are met:
- “Any Attachment Name” “ends with” “.ics”
- Perform the following actions:
- Run AppleScript “~/Library/Scripts/Applications/Mail/iCal-Invite-Fix.scpt”
- Click “OK” and then “Apply”
You can also run the script manually from the system-wide script menu. To install this menu. Open up the /Applications/AppleScript/AppleScript Utility.app
and check the Show Script menu in menu bar
box. If you put the script in the folder location indicated above it will now be visible when Mail.app is the current application.
Download the iCal-Invite-Fix script.
Please let me know if there are any problems or you need help setting this up. The script was not entirely my creation and credit also goes to others. I’m quite certain any errors are likely mine. 😉
Updated: Now produces CalDAV-compliant TZIDs, no quotes.
Updated again: Now will move the .ics files from /tmp to the Trash.
Update 12/03/2008: Fixed the METHOD:PUBLISH
invite to no longer ask to select which calendar to add event. It will automatically select the first local calendar, like it does with METHOD:REQUEST
.
Updated 12/28/2008: Added ability to use single script with multiple Exchange servers. The trade-off is a slightly more complex set up.
Comments
14 responses to “iCal – Exchange Time Zone Fix – Chapter 2”
Updated sed replacement to strip quotes that may appear in the DTSTART;TZID and DTEND;TZID. This is more CalDAV-compliant.
Hi mate,
I love the script, helped me resolve a long running gripe with all the exchange users in the office!
I just have one little bug which I thought you might shed some light on, and thats the way the “Attendees” get formatted. I always end up seeing two:
“3D (organiser)” which when clicked reveals the email address of the meeting inviter
“3D =ERROR” which when clicked shows ERROR
Also, for some reason the text in the “Notes” field also ends up cut short, with a “=” tacked on the end.
Any thoughts?
Guy-
It’s probably some formatting thing with the invite. The script only rewrites the time zone data. My bet is that there is something happening with the invite at the server and possibly the note is too long?? Just guessing. You might try having a look at one of your colleague’s invites on their Windows box and see if there are similarities.
Those
=3D
are usually from quote-printable formatting.Glad the script’s working for you.
Brilliant – thanks for writing this script. My life is now much better.
Andrew
Andrew – glad it’s making your life better. Any little bit I can do. 🙂
Fixed the script to move the saved .ics attachements to the Trash. It seems that AppleScript’s save attachment command doesn’t save replace the file that already exists.
Thanks Martin for finding this quirky bug.
Hi there,
I am receiving invites from various time zones as I am a consultant and travel a lot. Is there a way to make the Exchange Server timezone dynamic or to read it from the invite so that I don’t have to change it (which wouldn’t be practical as I often don’t know what timezone their server would be in)?
Many thanks!
C.
C-
Unfortunately you can only correct the Exchange Server’s timezone so that it will work correctly with iCal. But each Exchange Server that you must deal with should be in a fixed location. To solve your particular problem you will need multiple copies of the iCal-Invite-Fix script.
What you will need to do is have one copy of the script for each Exchange Server. Make the corrections for that Exchange Server in the script and then rename the script to reflect the location. Then a new Mail rule for each script that changes the following:
If
allthe following criteria are met:
Exchange Server
then
Something like that should work and you’d only have to set it up once for each Exchange Server. Unfortunately we can only work with the files we get. Trying to get your Exchange Server admin to do something it likely very difficult.
Hi Andy,
In what way should I format the Calendar name to get it to save it to my CalDAV calendar? I have a calendar called “Work” on the CalDAV share, but the script still saves to the local “Work” calendar instead.
Thanks again.
Guy, I don’t think you can import the invites into a CalDAV share. It doesn’t work for me here either. All of mine get imported into my local calendar as well. I look at this as a limitation of iCal.
I just synch this local calendar to my iPhone too. 😉
The script has been updated again. This time to allow for an unattended import of the
METHOD:PUBLISH
invite. I’m pretty sure the invites all get imported to the first local calendar you have. In my case it’s the Work calendar.The script has been updated to allow for multiple Exchange servers using a single script. Re-read the instructions. It comes at a slightly more complex set-up.
Hi Andy,
Hoped that your site & script might solve my problem – but no joy yet.
Basically, I have no issues with timezones – except when the exchange server calendar invite is recurring.
Example : a weekly recurring invite from Exchange 2007 in iCal gives me
– an event at the correct time
– an event 24 hours later (incorrect)
– every subsequent event is 7 days after the second incorrect event!
SO if you wanted to make a regular monday morning appt, I would get the first 1 ok, then 1 on Tuesday, and then one again on every subsequent Tuesday.
The invite itself when it hits my inbox has no .ics file, its encoded in base64 as a multi-part e-mail, and nothing I can do will fix it (including your excellent script).
Worse – hours of googling haven’t turned up a viable solution.
Help ! Any ideas very much appreciated…
Tim, can you redirect one of the invites to me so I can see what’s up? Send to andy@thefragens.dev
I won’t be able to get to it for a week or so though.