Take the 2-minute tour ×
Ask Different is a question and answer site for power users of Apple hardware and software. It's 100% free, no registration required.

I want to create a script that creates alarmed events in ical for birthdays of people that I have in my address book. Unfortunately, I am very bad working with applescript. Below is the outline of what I it to do, I would love some help as to what the actual script should be. I don't think the script would be that complex or long. Any help would be very much appreciated.

--run script when a change is made to a birth date in address book or when address book quits

--define list of people (will have an extra alarm, see below)

--search for birthdays entered in address book

--if no event is present in ical calendar named "birthdays" for birthdays found in address book (check name and date), create new all day event in birthday calendar with alarm on date and title "(Name of person)'s Birthday)

--if birthday is on list defined earlier, add extra alarm two weeks before the birthday

--display message showing what new events were created when the script ran

I'm not sure how this script could be triggered, but ideally it would run if a change is made to a birthday in address book (or a new one added).

Thanks.

share|improve this question
    
This isn't meant an as answer, obviously, but under what circumstances do birthdays in Address Book not show up in the Birthdays calendar in iCal? I've never seen that (lack of) behavior... –  Dan J Nov 25 '11 at 1:18
    
Learning Applescript is very useful. But personally I use Date 2 iCal for this. –  Alan Shutko Oct 23 '12 at 2:20

3 Answers 3

To set single alerts on all birthdays, you can avoid a script altogether:

  1. Open Calendar Preferences in Calendar.
  2. Under General, tick "Show Birthdays calendar".
  3. Under Alerts, set an alert for "Birthdays".

I haven't taken the time to actually write up an AppleScript for the double alarm parts, but this article seems to cover scripting calendar alarms quite nicely. I would imagine you would just need to create a file or list in the script that contains the names of the events (which you can deduce from the standard naming convention Calendar app uses).

Also I am using Mountain Lion with Calendar app. I can't recall if the steps above work on older versions of iCal.

share|improve this answer

Address Book already coordinates with iCal to create events based on the date in any contact’s birthday field. If all you only need alarms, then you just need a way to add alarms to these events.

The catch is that iCal’s user interface presents the calendar as if it were read-only. But to AppleScript, the calendar is not actually read-only. You can use AppleScript to add alarms to the events in the “Birthdays” calendar:

on run
    (* Warning:
        This program will delete all the "display alarms" from the events in the
        synthetic "Birthdays" calendar. Usually, there are no alarms on these
        events because iCal treats this calendar as if it were read-only.

        The calendar is not, however, actually read-only when accessed through
        AppleScript. This program deletes all existing "display alarms" for all
        birthdays and sets a new one for 13.5 days before the the event
        (i.e. noon 14 days before, since the event occurs at midnight).
    *)
    tell application "iCal"
        set bcName to "Birthdays"
        set bc to a reference to calendar bcName
        if not (exists bc) then
            display alert "No “" & bcName & "” calendar!"
            return
        end if
        repeat with e in events of contents of bc
            -- make the following conditional if you only want alarms for some birthdays
            tell e
                delete display alarms
                make new display alarm with properties {trigger interval:-13.5 * 24 * 60}
            end tell
        end repeat
    end tell
end run

Every time you run this program it will, effectively, make sure every birthday has an alarm on it. It looks like Address Book makes only minimal changes when it updates a birthday event for a changed name or birthday date; the alarms persist across updates from Address Book, but this may not be reliable since Address Books “owns” these events and could completely delete and recreate them any time it felt the need to do so.


I do not know of an official way to be notified of Address Book changes, but as the other answerer suggests, you might be able to hook up a Folder Action to the folder that holds the events for the “Birthdays” calendar. You can open that folder with this program:

tell application "iCal" to set bcuid to uid of calendar "Birthdays"
path to library folder from user domain
tell application "Finder" to open folder "Events" of folder (bcuid & ".calendar") of folder "Calendars" of result

Since this is an internal detail, it may not be reliable across different OS versions. All of the above was developed and tested on Mac OS X 10.6.8.

Alternatively, since the above program ensures every birthday has an alarm, you could just arrange to run it once a day or once at login (you can use an iCal event with a “Run Script” alarm, or save the program as an application and set it as a login item).


Creating your own events (in your own calendar) is certainly possible, but keeping them synchronized with the birthday data can be tricky (lookup by “name and date” is usually not sufficient because the user could change either of those, and your “make alarms” program may not be able to determine the original values by the time it knows a particular contact has been updated with a new name or birthday date). Address Book solves this problem by encoding the contact’s internal, unique identifier into the URL it saves into each birthday event’s url property; since the calendar is “read-only” it does not have to worry about a user changing or deleting its special URLs, so it can rely on them being accurate.

We delete all existing alarms on the assumption that all the alarms are “ours” since Address Book does not add alarms on its own, and iCal does not let users add alarms. Unfortunately, there is no extra property where we could add any kind of unique identifier to the alarm itself (although if the exact time of the alarm is not important, it might be possible to encode some information in the numeric value of the alarm’s minute offset). It seems easier to just delete the alarms and create exactly the one we want instead of checking any existing alarms to see if they match our current desired alarm setting.

share|improve this answer

I believe the difference is that the Birthday's calendar on ical does not create alarms before the event. Nor does it let you add them manually.

I think you could make this work though with a folder actions script. Enable the Birthdays calendar in ical. Then attach a script to the folder where these events are stored. When a new event is added (ie you've added a new birthday to your address book) the script will be triggered.

Here's the folder where I found my Birthdays events:

/Library/Calendars/FA907C55-E8CD-4291-8173-B3F86886E2BF.calendar/Events

You may have to dig through the lists of calendars until you find the correct folder, but it should be in there.

From there, the script would take the new item added to the folder, and then copy it to a separate calendar and add the alarm. To set it up, I'd create a new calendar where you want these new events to be dropped. Take the events from your birthdays calendar, and drag them onto the desktop or somewhere (they'll be deleted later). Then open each of them. It'll ask you which calendar you want to add them to, so just pick that new calendar you made. Delete the files, there you go, you can now add alarms to them.

Depending on how many birthdays you already have, you could write a script that would add an event to each of these individually, or (if you're like me and have so few bdays saved) do it manually. Once that's done, a folders action script would do the trick you're looking for.

on adding folder items to this_folder after receiving these_items
    repeat with i from 1 to number of items in these_items
        set this_item to item i of these_items
        tell application "finder"
            move this_item to --location specifier of folder for new bday calendar
        end tell
    end repeat
    tell application "ical"
        reload calendars
        --add script here to add new alarms
    end tell
end on adding folder items to

Sorry, I don't have the exact code for you to add the alarm. Try this out though and let me know how it works!

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.