Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Extracting Exchange vCalendars from Mail.app Apps
When I receive a vCalendar request from someone through Microsoft Exchange, Mail.app doesn't recognize the included vCalendar as an attachment and so it renders the content of the vCalendar instead of giving me an icon to click. I was able to remedy this shortcoming in Mail by setting up a new Mail rule which runs the AppleScript given below. For the Mail rule, you will need to "Edit Header List..." in order to add the header "Content-Class" which should be set to contains "calendarmessage" and then perfrorm action Run AppleScript with the script given below saved with the Script Editor as a compiled script.

This AppleScript will extract the vCalendar from the message and prompt you to save it to your disk. You should give the file the extension .ics. The first time you do this, the resulting file will likely appear as a text file. To tell the Finder that it is an iCal file, "Get Info" on the file and set "Open with" to "iCal". If you also press "Change All...", then in the future these files will belong to iCal by default.

This AppleScript will extract the vCalendar from the message and prompt you to save it to your disk. You should give the file the extension .ics. The first time you do this, the resulting file will likely appear as a text file. To tell the Finder that it is an iCal file, "Get Info" on the file and set "Open with" to "iCal". If you also press "Change All...", then in the future these files will belong to iCal by default.
property beginTag : "BEGIN:VCALENDAR"
property endTag : "END:VCALENDAR"

on perform_mail_action(info)
tell application "Mail"
set theMessages to |SelectedMessages| of info
repeat with thisMessage in theMessages
set thisContent to content of thisMessage

if (thisContent contains beginTag) ¬
and (thisContent contains endTag) then

-- extract vCalendar from message
set thisCal to ¬
text from character (offset of beginTag in thisContent) ¬
to character ((offset of endTag in thisContent) ¬
+ (length of endTag)) of thisContent

-- save vCalendar to file
set thisFileName to ¬
choose file name with prompt "Save calendar item from " ¬
& sender of thisMessage ¬
& " as:" default name subject of thisMessage & ".ics"
set thisFile to open for access thisFileName with write permission
write thisCal as string to thisFile
close access thisFile
end if
end repeat
end tell
end perform_mail_action
If you set this up on your computer, you will probably want to keep an eye on the Apple Mail updates as I would expect them to fix this eventually so you don't need this remedy. Also note that this script will only find one vCalendar per message, which is all I have ever received.
    •    
  • Currently 1.00 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (1 vote cast)
 
[14,908 views]  

Extracting Exchange vCalendars from Mail.app | 17 comments | Create New Account
Click here to return to the 'Extracting Exchange vCalendars from Mail.app' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Genius idea! But problem...
Authored by: willbank on Jan 28, '03 11:55:13AM

Following the instrucs to the letter this just crashes my Mail.app when it attempts to run the applescript...

Anyone any thoughts as to why this should be? (I am afraid that I am not clever enough to decipher the console log except it throws up

OS Version: 10.2.3 (Build 6G30)

Command: Mail
PID: 617

Exception: EXC_BAD_ACCESS (0x0001)
Codes: KERN_INVALID_ADDRESS (0x0001) at 0x40261aa0



[ Reply to This | # ]
Genius idea! But problem...
Authored by: lx on Jan 28, '03 12:37:11PM
I haven't seen a crash like this, so I cannot offer any direct help. As a suggestion for debugging, you should try creating a very simple AppleScript (just put display dialog "Boo!" between a perform_mail_action on/end pair) and attaching it to a mail rule.

[ Reply to This | # ]
Genius idea! But problem...
Authored by: willbank on Jan 30, '03 09:05:37AM

That all works fine but the minute it gets to the extract vCalendar stage it forces Mail to shutdown unexpectedly...

Is there any way that I can alter the contents of those lines (not being a scripter myself more analysis is a bit beyond me)?

Thanks for the help.



[ Reply to This | # ]
Genius idea! But problem...
Authored by: raydeeoh on Jun 18, '03 08:35:43PM

Part of the problem might be all the "\" characters in the above script. I don't know AppleScript, but you have to remove them in order for that script to compile. Took me a while to figure that out! Once I did it, it seems to work.



[ Reply to This | # ]
Genius idea! But problem...
Authored by: raydeeoh on Jun 18, '03 08:37:38PM

That's really weird - they are gone. They were there before -- perhaps an artifact of not being logged in and/or using the MacOSXHints search engine to hit that page. Very odd.



[ Reply to This | # ]
Some additions...
Authored by: svinki on Jan 28, '03 07:10:42PM

A collegue and I tackled this same problem last week...here are some additional tips:

1. In addition to scanning "Content-Class" for "calendarmessage", you'll also need to scan that header for "appointment". This covers different ways people can schedule meetings in Outlook.

2. Try saving the .ics file to Temporary Items, and then set the Applescript to tell Finder to open said file. This will feed the file to iCal, which will present a meeting invitation dialog. From there, you can accept (or decline) the meeting and choose which calendar will receive the event. With that change in place, you should also be able to get rid of the intervening Applescript dialog. The .ics file will eventually be deleted by the system.

3. Additional caveats: This will not "Update" meetings...you'll have to do that manually by deleting the previous version of the meeting from iCal and then importing the new, updated version.

I wish it were more robust, but it's a good stopgap until Apple gets this working the Right Way. =)



[ Reply to This | # ]
Some additions...
Authored by: svinki on Jan 28, '03 08:00:59PM

That should be "colleague". =b



[ Reply to This | # ]
Some additions...
Authored by: anandman on Mar 04, '03 10:38:15PM
Following your suggestions, I've come up with this script. For some reason, I can't overwrite the the temporary file so I had to insert the 'rm' command before trying to open it. This works well for me though.
property beginTag : "BEGIN:VCALENDAR"
property endTag : "END:VCALENDAR"

on perform_mail_action(info)
  tell application "Mail"
    set selectedMessages to |SelectedMessages| of info
    set theRule to |Rule| of info
    repeat with eachMessage in selectedMessages
      set theSubject to subject of eachMessage
      set theRuleName to name of theRule
      set theContent to content of eachMessage

      if (theContent contains beginTag) ¬
        and (theContent contains endTag) then
        -- extract vcalendar from message
        set theCal to ¬
          text from character (offset of beginTag in theContent) ¬
            to character ((offset of endTag in theContent) ¬
            + (length of endTag)) of theContent

        -- save vcalendar to file
        set theFileName to ¬
          (path to temporary items folder type string) ¬
            & "Mail2iCal.ics"
        set theFileNamePOSIX to POSIX path of theFileName
        try
          set theCommand to "rm -f '" & theFileNamePOSIX & "'"
          do shell script theCommand
        on error
          display dialog "ERROR: Can't delete file " & theFileNamePOSIX
        end try
        try
          set theFile to (open for access theFileName with write permission)
        on error
          display dialog "ERROR: Can't open file " & theFileName
          try
            close access theFileName -- use the file name rather than the ref
          end try
        end try
        try
          set eof of theFile to 0
          write theCal as string to theFile starting at eof
          close access theFile
        on error
          display dialog "ERROR: Can't write or close file " & theFileName
          try
            close access theFile
          end try
        end try

        -- open vCalendar file with iCal
        set theCommand to "open -a '/Applications/iCal.app' '" & theFileNamePOSIX & "'"
        do shell script theCommand
      end if
    end repeat
  end tell
end perform_mail_action
-anand

[ Reply to This | # ]
Some additions...
Authored by: anandman on Mar 04, '03 10:44:41PM
Oops. I forgot to change one thing. For some reason, Script Editor's check syntax changes and "as" to "type" and lets me compile it and save it the first time but when you try to check syntax or save it again it fails. Anyone know why?

Anyway, just change the following line:

  (path to temporary items folder type string)
to
  (path to temporary items folder as string)

-anand

[ Reply to This | # ]

Helping iCal understand vCalendars
Authored by: lx on Jan 29, '03 08:19:59AM
The hint I submitted suggests a way in which you can help Mail.app (1.2.3 v551) recognize and process a vCalendar request. It turns out that you will probably need to give iCal (1.0.2 v452) some help understanding the vCalendar standard which it does not seem to be well-versed in yet. iCal has two problems in replying to non-iCal vCalendar requests. First, it does not grok TZID's so any invite that doesn't specify times using built-in TZID's (like "US/Pacific") could end up at the wrong local time. Second, even when iCal gets a request using TZID's it understands, the RSVP dialog doesn't localize the time it indicates for the invitation (at least, that's what happens for me). I've attached some more AppleScript pieces that you can use with the script in the hint to help iCal get the time right.

To use this addition, add the lines:
--localize the calendar
if thisCal contains "BEGIN:VTIMEZONE" then ¬
set thisCal to my localized(thisCal)Add these lines just before the -- save vCalendar to file line. Also add the line:
property daylight : {startondate:date ¬
"Sunday, April 6, 2003 12:00:00 AM", ¬
endbeforedate:date "Sunday, October 26, 2003 12:00:00 AM"}
to the top of the script (if it is no longer 2003, you will need to update this line with the current daylight savings time interval).

Warning! The localization works for the vCalendar invites that I receive which all contain a single VTIMEZONE definition (with daylight and standard variations) for a single TZID. Your context may be different and the localization may not work. You will want to check that the "localized" time ends up in your iCal calendar correctly. As always, use at your own risk!
-- Handlers for Localization
on localized(theCal)
--choose daylight or standard variant
if (current date) >= startondate of daylight and ¬
(current date) < endbeforedate of daylight then
set theTZ to text from (offset of "BEGIN:DAYLIGHT" in theCal) to ¬
(offset of "END:DAYLIGHT" in theCal) of theCal
else
set theTZ to text from (offset of "BEGIN:STANDARD" in theCal) to ¬
(offset of "END:STANDARD" in theCal) of theCal
end if

--get time zone offset
set tzTag to "TZOFFSETTO:"
set tzStart to (offset of tzTag in theTZ) + (length of tzTag)
set theTimeShift to ((time to GMT) / 3600) ¬
- (text from tzStart to (tzStart + 2) of theTZ as number)

-- localize calendar
set newCal to ""
repeat with thisLine in paragraphs of theCal
set theOffset to the offset of "TZID=" in thisLine
if theOffset > 0 then
set theTime to decodeDT(text from character -15 to ¬
character -1 of thisLine)
set theTime to theTime + theTimeShift * hours
set thisLine to insert(thisLine, encodeDT(theTime), ¬
theOffset, length of thisLine)
end if
set newCal to newCal & thisLine & return
end repeat

return newCal
end localized

on insert(theString, theInsert, theStart, theEnd)
if (theStart - 1) >= 1 then
set theResult to text from character 1 ¬
to character (theStart - 1) of theString
else
set theResult to ""
end if

set theResult to theResult & theInsert

if theEnd <= length of theString then
set theResult to theResult ¬
& text from character theEnd to last character of theString
end if

return theResult
end insert

on decodeDT(theTimeString)
set theYear to text from character 1 to character 4 of theTimeString
set theMonth to text from character 5 to character 6 of theTimeString
set theDay to text from character 7 to character 8 of theTimeString
set theHours to text from character 10 to character 11 of theTimeString
set theMinutes to text from character 12 to character 13 of theTimeString
set theSeconds to text from character 14 to character 15 of theTimeString
return date (theMonth & "/" & theDay & "/" & theYear & ¬
", " & theHours & ":" & theMinutes & ":" & theSeconds)
end decodeDT

on encodeDT(theDate)
-- month number
set theMonth to 1
repeat until (month of theDate) is equal to item theMonth of ¬
{January, February, March, April, May, June, July, ¬
August, September, October, November, December}
set theMonth to theMonth + 1
end repeat

--time components
set theHours to (time of theDate) div 3600
set theMinutes to ((time of theDate) - theHours * 3600) div 60
set theSeconds to ((time of theDate) - theHours * 3600 - theMinutes * 60)

--vCal time encoding
return (year of theDate as text) ¬
& zeropadded(theMonth, 2) ¬
& zeropadded(day of theDate, 2) ¬
& "T" & zeropadded(theHours, 2) ¬
& zeropadded(theMinutes, 2) ¬
& zeropadded(theSeconds, 2)
end encodeDT

on zeropadded(theNumber, thePadding)
set theResult to theNumber as string
repeat while the length of theResult is ¬
less than thePadding
set theResult to "0" & theResult
end repeat
return theResult
end zeropadded
As before, my hope is that you will not need these hacks for very long.

[ Reply to This | # ]
Helping iCal understand vCalendars
Authored by: raydeeoh on Jun 18, '03 08:48:56PM

Where exactly do you insert this Time Zone script? Thanks!



[ Reply to This | # ]
Content-Class Header?
Authored by: skinnyjimmy on Jan 29, '03 08:50:44AM

This idea does sound fantastic (especially incorporating the 'temporary folder' idea) - however, the meeting requests I send from Outlook don't have the 'Content-Class' header in them. The raw-source view reveals only 'Message-Id', 'Mime-Version', 'X-Mailer' and 'Content-Type' headers (along with usual 'received', etc., headers). Nothing out of the ordinary and certainly no 'Content-Class'.

Any ideas if this is a server issue?



[ Reply to This | # ]
Content-Class Header?
Authored by: lx on Jan 29, '03 11:03:46AM
If there are no distinguishing headers (be sure to use View->Show All Headers) with which to identify messages containing vCalendars and there are no distinguishing strings of text in the message subject or message content (the part that is not in the attachment), then you can try being aggressive about finding them and running the AppleScript on all your messages, all messages from people in your AddressBook, all messages with attachments (try adding the header rule "Content-Type" "contains" "multipart"), or some other similarly broad mail rule.

The script does nothing with messages that do not contain BEGIN:VCALENDAR and END:VCALENDAR. Using a more general rule, however, might cause the script to extract invlaid vCalendars as well (such as ones quoted in replies), so some caution is in order for such an approach.

An additional note about applying this hint to your own context. While Mail.app interprets the invitations I receive as part of the message content, it may not do that with the invitations you are receiving for which it may be including the vCalendar as an attachment of unknown type. If this is the case, you will need to change the line set thisContent to content of thisMessage to set thisContent to source of thisMessage in order for the script to extract the vCalendar.

[ Reply to This | # ]
Complete Solution
Authored by: anwnn on Jan 30, '03 04:34:47PM

Very helpful hint, many thanks.

I'm hoping to eventually come up with a complete cross platform solution for iCal and Outlook interaction. I'm the sole person in my office that uses iCal, with all the Macs using Entourage, and the PCs using Outlook 2000/XP. I still haven't found a complete solution to both sending and recieving between all three platforms. Perhaps we could gather up all the tips for something like this into a single resource, as I'm sure I'm not the only fish swimming in this sea.

What good are the standards if they don't get implemented right, argh!

[ Reply to This | # ]

Extracting Exchange vCalendars from Mail.app
Authored by: nestorph on Oct 29, '03 09:10:46AM

I wish I had come across this script a few months ago. As it turns out, Panther fixes this problem and Outlook invitations appear as an attachment named meeting.ics. You can double-click on the attachment and it inserts the meeting into iCal. A problem still remains with how iCal constructs the reply e-mail message. The e-mail address is not that of the inviter, but instead a compilation of the inviter's name appended to @mac.com.



[ Reply to This | # ]
Extracting Exchange vCalendars from Mail.app
Authored by: benders on May 19, '04 02:31:37PM

Unfortunately iCal still doesn't understand timezones, at least not the ones from exchange. Our companies exchange server is in the eastern timezone and I'm in the pacific but iCal doesn't adjust the start time appropriately.



[ Reply to This | # ]
Extracting Exchange vCalendars from Mail.app
Authored by: grego33 on Jul 22, '07 07:15:15AM
I ran across this hint as I was having similar problems under OS X 10.4.10 and Mail.app 2.1. But I had the issue someone else had where Mail.app crashed whenever the script ran.

I think some things probably changed between OS X and Mail.app versions, so I made some updates to make it work and posted it in my blog:

http://www.dothemash.com/zerodiggs

[ Reply to This | # ]