A user wants to have Address Book activate and open to the card of the “Attendee” in an iCal event when the event triggers.
I’m stuck.
In my script that runs when the event occurs, how to get iCal’s “current event”'s first attendee? (i.e. how to know which event triggered the script so I can reference its attendees)
in Address Book, given a name, I can easily “get” the Person, but Address Book doesn’t want to respond properly to “reveal” (says ‘can’t continue reveal’), “show”, “select”, “open” (files only), or any other verb I can think of.
Questions
When a script is triggered by an iCal event, what’s the reference to the event?
How to tell Address Book to show a particular card (same as clicking on the row in the “Name” column)
I have Script Debugger, but running up against a wall here.
For the first it’s not so easy, iCal’s Applescript dictonary does not have current event. If the event is not part of a repeating event then you can find events whose start date is close to the current date (this assumes that the alarm has been triggered immediately - ie that the computer was on when the alarm was due). If the event is part of a recurrence then the complication is compounded by the fact that you’ll need to work with the recurrence of all appropriate events to see if there is a repeat of the event in the timescale you are interested in.
I must say that this has been fun, although for the life of me I don’t know why the iCal team would think a script that doesn’t know what event called it would be able to do anything. LOL.
Here is my almost-final script, incorporating the heuristic “closest event start time” as looping through the events and keeping the one with the least time difference, and then using “set selection to” in the Address Book instead of my mistaken “select” verb. I still have to tweak the event start time to account for the Trigger Interval (see below).
Caveats:
I looked at the Trigger Date of the Open FIle Alarms of an Event - (a “Run AppleScript” action is apparently an “Open File Alarm”), and it is always blank. So in the next revision I will calculate the Trigger Date by subtracting the Trigger Interval of the Open File Alarm from the Start Date. Should be straightforward.
The Attendee’s name has to be identical to that person’s Name in the Address Book. I think this is the only realistic way to do it. That means the user has to use the popup menu in iCal to set the Attendee from the Address Book. Since the purpose of the script is to display the attendee’s Address Book card, this should not be a problem. I don’t know what happens if the user enters the Attendee’s name in iCal using the popup, and then changes the display order (last name first versus first name first) in the Address Book.
Of course, the user has to set the property “calendarName” to their chosen calendar before installing the script.
property calendarName : "Home"
tell application "iCal"
set thisCalendar to first calendar whose title is calendarName
set theEvents to (every event of thisCalendar)
set theStartDates to (start date of every event of thisCalendar)
set currDate to (current date)
set todaysDateString to date string of currDate
set closest to currDate - (date "Thursday, January 1, 1970 12:00:00 AM") -- start with prehistoric date to force failed comparison on first loop iteration
repeat with i from 1 to count theStartDates
set thisStartDate to item i of theStartDates
set thisEvent to item i of theEvents
set thisCloseness to currDate - thisStartDate
if thisCloseness is not less than 0 then -- not in the future
if thisCloseness is less than closest then
set closest to thisCloseness
set closestEvent to thisEvent
end if
end if
end repeat
set theName to (display name of first attendee of closestEvent)
end tell
tell application "Address Book"
try
set ABFound to (first person whose name is theName)
set selection to ABFound
activate
on error
display dialog "Name of Attendee for Alarm not found in the Address Book."
end try
end tell
Just added the code to adjust the Start Date of each event by subtracting the Trigger Interval if one exists (why don’t they just set the Trigger Interval value to 0 instead of “undefined” if the user hasn’t changed it??? Sheesh.) This way, two events on the same day whose trigger intervals actually make their alarm times in a different order than their start times will still sort correctly and give us the most recent alarm. Example: Event A at noon, with trigger interval of “10 minutes before”, and event B at 1:00 PM, with trigger interval of 2 hours, will sort so that event B is deemed to be the “most recent alarm”, and thus the one that called our script.
property calendarName : "Home"
tell application "iCal"
set thisCalendar to first calendar whose title is calendarName
set theEvents to (every event of thisCalendar)
set theStartDates to (start date of every event of thisCalendar)
set currDate to (current date)
set todaysDateString to date string of currDate
set closest to currDate - (date "Thursday, January 1, 1970 12:00:00 AM")
set thisTriggerInterval to 0
repeat with i from 1 to count theStartDates
set thisStartDate to item i of theStartDates
set thisEvent to item i of theEvents
try -- see if event has a trigger interval, and if so, save it
set thisTriggerInterval to trigger interval of first open file alarm of thisEvent
end try
set thisCloseness to currDate - thisStartDate - thisTriggerInterval
set thisTriggerInterval to 0
if thisCloseness is not less than 0 then -- not in the future
if thisCloseness is less than closest then
set closest to thisCloseness
set closestEvent to thisEvent
end if
end if
end repeat
set theName to (display name of first attendee of closestEvent)
end tell
tell application "Address Book"
try
set ABFound to (first person whose name is theName)
set selection to ABFound
activate
on error
display dialog "Name of Attendee for Alarm not found in the Address Book."
end try
end tell
There is still one problem - if the person’s name in the Address Book has a middle name or suffix or prefix, the )(**$&^ iCal enters it as just “Last Name First Name”, so it will not match when Address Book is asked to look it up. Why they did this is completely beyond my comprehension. Try it - start typing a name into the combo box in the Event sheet and the matches from Address Book will only show the last name and first name.
I think that is the most that can be done without parsing the parts of the name and adding even worse heuristics.