Skip to content

Instantly share code, notes, and snippets.

@pwc3
Last active February 1, 2024 12:34
Show Gist options
  • Save pwc3/5342337 to your computer and use it in GitHub Desktop.
Save pwc3/5342337 to your computer and use it in GitHub Desktop.
AppleScript to copy all of the events from an Exchange calendar to an iCloud calendar.
tell application "Calendar"
-- delete everything from the destination calendar
-- TODO: Change "Destination Calendar" to be the name of your destination calendar
repeat with anEvent in (get events of calendar "Destination Calendar")
delete anEvent
end repeat
-- copy all events from the source calendar to the destination
-- TODO: Change "Source Calendar" to be the name of your source calendar
-- TODO: Change "Destination Calendar" to be the name of your destination calendar
repeat with anEvent in (get events of calendar "Source Calendar")
copy anEvent to the end of events of calendar "Destination Calendar"
end repeat
end tell
@samdunne
Copy link

This crashes Calendar for me. Any ideas? I get a Connection Refused error

@derfinsterling
Copy link

Worked like a charm, thank you very much - But I do have an issue with the script copying all events, every time.
I'm new to scripting, could you give me any pointers on how I can limit it to copy only events after today?

Thanks!

@degreecy
Copy link

degreecy commented Jul 3, 2017

Is there a way to adapt the script to only copy a date range to avoid copying the whole calendar ?

@localjo
Copy link

localjo commented Oct 11, 2017

I'd be interested to know if there's a way to select a calendar by uid rather than name, since I've got several calendars named "Calendar" where I can't control the name. And for some reason, the copy line doesn't seem to actually copy the events to the destination calendar, even though I've confirmed with display dialog summary of anEvent as string that each event in the source calendar is being looped through.

@localjo
Copy link

localjo commented Oct 11, 2017

I've figured out I can select a calendar by uid (or any other property) doing something like this;

set sourceUid to "B20FD..."
set sourceCalendar to first calendar where its uid = sourceUid

@localjo
Copy link

localjo commented Oct 11, 2017

Regarding the copying; I'm noticing some strange behavior where some of the events seem to get copied and others don't I saw some quirks that made me think they might be getting copied and then immediately deleted again. This is what I'm doing now;

set destinationUid to "B20FD..."
set sources to {"A20FC..."}

-- Clear the destination calendar
tell application "Calendar"
	set destinationCalendar to first calendar where its uid = destinationUid
	repeat with anEvent in (get events of destinationCalendar)
		delete anEvent
	end repeat
	display dialog "Cleared " & name of destinationCalendar as string
	
	-- If this loop displays anything the clearing didn't work
	repeat with anEvent in (get events of destinationCalendar)
		display dialog "Failed to clear " & summary of anEvent as string
	end repeat
end tell

-- Copy sources to destination
tell application "Calendar"
	set destinationCalendar to first calendar where its uid = destinationUid
	repeat with sourceUid in sources
		set sourceCalendar to (first calendar where its uid = sourceUid)
		display dialog "Copying " & name of sourceCalendar as string
		repeat with anEvent in (get events of sourceCalendar)
			display dialog summary of anEvent as string
			copy anEvent to the end of events of destinationCalendar
		end repeat
	end repeat
	
	-- Why doesn't this have all events?
	display dialog "Copied to " & name of destinationCalendar as string
	repeat with anEvent in (get events of destinationCalendar)
		display dialog summary of anEvent as string
	end repeat
end tell

When I run this code, the last loop that logs the copied events sometimes logs all events, other times just logs some of them. But the loop before that logs the events being copied always logs all of the events.

@localjo
Copy link

localjo commented Oct 11, 2017

Alright, I'm not sure exactly what the problem was, or if I fixed it completely, but if I change the line;

copy anEvent to the end of events of destinationCalendar

To this;

duplicate anEvent to end of destinationCalendar with properties {description:"Copied Automatically"}

It looks like the problem goes away. I changed copy to duplicate which I think is just an alias. I copied directly to the destination calendar instead of the events of the destination calendar, which doesn't seem to have made a difference, but I like that better. And I added with properties which I think is what fixed the issue. I think updating the properties prevents something from thinking this might be an existing event and skipping it. That's just a guess, I haven't really confirmed, but I figured all of this may be useful to someone else.

@darb78
Copy link

darb78 commented Feb 18, 2020

Jumping on an old string here, but hoping someone is still watching. -- I have 2 different work calendars and a personal calendar that I need to keep in sync. It isn't sufficient for me to be able to view them, I need them to be mirror each other. This seems like a start to a good sync service, but I'm struggling (admittedly a novice here) to determine how I can set it up to not keep copying the same events over and over.

@tnacsak
Copy link

tnacsak commented Mar 10, 2020

Hi!
I played some hour with the topic at it has some infuriating problems.

  • First, AppleScript drops an error of missing handler for uids of calendars, and many properties of the events (url, allday event, location and so).
  • The other problem is recurrence - it was impossible to copy from an Exchange calendar to an icloud cal. It is a string, but the string from one event as a copy to the new event raises 1700 error code (Bad parameter data was detected or there was a failure while performing a coercion.)
  • Other issue is the fields with missing value, you see the code

I hope you can use the code below, but it is far to be perfect. I also planned to have a script which list the calendars and their uids to make the code target really the one you need, but the missing handler made it impossible.

set theStartDate to (current date) - (20 * days)
set hours of theStartDate to 0
set minutes of theStartDate to 0
set seconds of theStartDate to 0
set theEndDate to theStartDate + (14 * days) - 1

set sourceCalendarTitle to "YourSourceCalendarTitle"
set destinationCalendarTitle to "YourDestinationCalendarTitle"

tell application "Calendar"
	set destinationCalendar to (first calendar where its title = destinationCalendarTitle)
	set sourceCalendar to (first calendar where its title = sourceCalendarTitle)
	
	tell destinationCalendar
		set calendarEvents to (every event where its start date is greater than or equal to theStartDate and end date is less than or equal to theEndDate)
		set numberOfEvents to count calendarEvents
		repeat with i from 1 to numberOfEvents
			set anEvent to item i of calendarEvents
			delete anEvent
		end repeat
	end tell
	
	tell sourceCalendar
		set sourceEvents to (every event where its start date is greater than or equal to theStartDate and end date is less than or equal to theEndDate)
		repeat with i from 1 to count sourceEvents
			set anEvent to item i of sourceEvents
			set tmpDescription to description of anEvent
			if tmpDescription = missing value then
				set tmpDescription to ""
			end if
			
			if recurrence of anEvent = missing value then
				make new event at destinationCalendar with properties {summary:summary of anEvent, start date:start date of anEvent, end date:end date of anEvent, description:tmpDescription, allday event:allday event of anEvent}
			end if
		end repeat
	end tell
end tell

@masciugo
Copy link

it works with BigSur on mbp M1. thank you

@masciugo
Copy link

... the problem is that it misses recurring events whose first event does not happen inside the selected time window

@alexdd55
Copy link

alexdd55 commented Jul 5, 2021

sadly non of this works for me (Big Sur, MBP M1)

@MyKEms
Copy link

MyKEms commented Feb 1, 2024

Hi, I needed this feature, so I created an updated version for anyone interested (compatible with the current macOS version): https://gist.github.com/MyKEms/3287c65f097a29b1756f3799842165bb

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment