The Sad State of Mac Calendar Scripting
AppleScript support with popular Mac calendar apps is surprisingly limited. With Apple Mail, it’s easy to write a script that operates on the selected e-mail messages, and I’ve written many such scripts. I’d like to do this same with calendar events. For example, sometimes I want to make the same change to one of the fields of all the selected events (since there’s no bulk edit inspector). Other times I want to reschedule by shifting all the events by the same amount of time. Sometimes I have a group of past events (e.g. for cooking a Thanksgiving dinner or traveling to a familiar location) and I want to start planning the next iteration by duplicating and shifting them to the future. When traveling east-west, I would like to check that the time zone information is entered consistently.
But this just doesn’t seem to be possible to script. With Apple Calendar and BusyCal, the scripting dictionary does not even let you access the selected calendar events. Readdle Calendars, which recently switched to a subscription, is not scriptable at all. With Fantastical, the dictionary looks promising but mostly doesn’t work:
You can get the selected events, but key properties such as the containing calendar and the repetition and alarm info are missing. So I can’t just copy by making a new event based on the selected one.
I usually want the copied event to keep the same calendar, so how about just letting Fantastical copy an existing event and then edit it with the script? There’s a
duplicate
command, but it doesn’t work.OK, how about if I have the script pick the calendar and create a new event using the properties of the selected one? It turns out that creating new events via AppleScript doesn’t work, either.
How about if I duplicate the events using the menu command and then use AppleScript to edit them? The properties are shown as editable, and you can set their values, but this seems to just mutate a temporary object. The changes are never reflected in the user interface or saved to disk.
I contacted support, who said that, despite what the dictionary shows, none of this is supported. All you can do is read (some) of the properties of the selected events and create new events using the parse sentence
command. They suggested exporting to ICS, processing the file, and re-importing the ICS. The Export… command exports an entire calendar and so isn’t very useful for this purpose, unless you first copy the events to a temporary calendar. However, you can export individual events via drag and drop.
Some other partial solutions that I found:
You can click here to set a hidden Fantastical preference to make the event editor popover always open in expanded form. This saves a lot of clicks when editing a sequence of events.
You can Option-drag a selection of events to copy them to a particular day. I mostly don’t find this useful because the source and destination days don’t usually fit on screen at the same time (and it doesn’t let me open multiple windows).
Similarly, if you can manage to view and select a bunch of events in the week or day view, you can drag and drop to reschedule them all at once. This is in general rather awkward, but it can work if you’re doing something basic like shifting them all an hour later.
Although there is no command to Duplicate the selected events to a particular day, you can Copy them, then click on the desired start day, and Paste, and it will preserve the relative times between the events. (This also works in Apple Calendar.)
Previously:
Update (2024-10-28): A reader notes that, although Calendar does not provide AppleScript access to the selected events, if an event is in edit mode you can use GUI scripting to extract its information:
tell application "System Events" tell application process "Calendar" set parametersOfEvent to description of every button of pop over 1 of window 1 --eg...{"Oct 25, 2024 9 AM to 5 PM", "Alert when I need to leave Alert 15 minutes before start (default)", "Edit Attendees", "add", "Add Notes or URL"} set nameOfEvent to value of every text field of pop over 1 of window 1 set repeatsHow to value of every static text of pop over 1 of window 1 --eg..{"Busy", "Repeats every week on Monday, Tuesday, and Thursday"} --item 1 is the title, item 2 is how it repeats end tell end tell
And Shane Stanley’s CalendarLib EC is an AppleScript wrapper for accessing EventKit using AppleScriptObjC.
5 Comments RSS · Twitter · Mastodon
Do you have a script for Mail that blocks certain domains and if you do will Apple Mail accept it and how woul I install it? I know about your spam app but can't afford it.
You can do quite a bit of calendar scripting with Shortcuts. Shortcuts seems to be generally its own special little island within MacOS & iOS, shipping with its own libraries.
@geriatricguy I do not have such a script (since I use SpamSieve’s blocklist), but it should be possible to write a script that modifies Mail’s rules based on the selected message. You can run scripts using the system Script menu.
@Adam I did look into Shortcuts, but I don’t think it provides a way to access the selected events, and it can only find events by date.
You can access a lot of EventKit using AppleScriptObjC. I wrote a scripting library, CalendarLib EC, that covers the basics. You can get it here: https://s3.amazonaws.com/latenightsw.com/ShaneLibs/CalendarLib_EC_stuff.zip
@Shane Cool! It looks like the event’s id
in Fantastical is the same as the UID
with EventKit, so it should be possible to get the selection from the app and then operate on it using CalendarLib EC.