Skip to content

Instantly share code, notes, and snippets.

@MyKEms
Created February 1, 2024 12:24
Show Gist options
  • Save MyKEms/3287c65f097a29b1756f3799842165bb to your computer and use it in GitHub Desktop.
Save MyKEms/3287c65f097a29b1756f3799842165bb to your computer and use it in GitHub Desktop.
AppleScript to copy all of the events from an Exchange calendar to an iCloud calendar via calendar.app.
tell application "Calendar"
-- Execute this script first manually via osascript Exchange_Sync.applescript to allow all security pop-ups. Make sure you use empty destination calendar because it will be wiped each run!
-- Don't forget to grant full calendar rights from System settings > Privacy & Security > Calendars > App > Options > Full calendar access
-- Schedule it via crontab -e and paste: "0 9,14 * * * osascript /Users/user.name/macOS_Cronjobs/Exchange_Sync.applescript > /Users/user.name/macOS_Cronjobs/cronjob.log"
-- Get the current date and time
set currentDate to current date
-- Set the start date range to 7 days ago
set startDateRange to currentDate - (7 * days)
-- Set the end date range to 30 days in the future
set endDateRange to currentDate + (30 * days)
-- Get the calendar named "Calendar" - ! MODIFY LINE BELOW - Source calendar !
set sourceCalendar to calendar "Calendar"
-- Get the calendar named "iCloudCalendar" - ! MODIFY LINE BELOW - Destination calendar (to be overwritten - delete all events and re-create!) !
set destinationCalendar to calendar "iCloudCalendar"
-- Delete events from the destination calendar
set destEvents to every event of destinationCalendar
repeat with anEvent in destEvents
delete anEvent
end repeat
-- Duplicate events from the source calendar to the destination
set sourceEvents to every event of sourceCalendar
repeat with anEvent in sourceEvents
set eventStartDate to start date of anEvent
set eventEndDate to end date of anEvent
set eventSummary to summary of anEvent
-- Logging the start and end dates
log "Processing event: " & eventSummary & " | Start Date: " & eventStartDate & " | End Date: " & eventEndDate
-- Check the event's start date is within the last 7 days and the next 30 days
if (eventStartDate ≥ startDateRange) and (eventStartDate ≤ endDateRange) then
if eventEndDate is missing value then
set eventEndDate to eventStartDate + (60 * minutes) -- Add 60 minutes if there is no end date
end if
try
-- Attempt to create the new event with the specified end date
set newEvent to make new event at end of destinationCalendar with properties {start date:eventStartDate, end date:eventEndDate, summary:eventSummary}
on error errMsg number errorNumber
-- Log any errors
log "Failed to copy event \"" & eventSummary & "\". Error: " & errMsg & " (Error number " & errorNumber & ")"
end try
end if
end repeat
end tell
@MyKEms
Copy link
Author

MyKEms commented Feb 1, 2024

This script was tested on MacBook Pro M2 with macOS Sonoma.

How to execute:

⚠️ WARNING: Make sure that the destination calendar is not in use at all! It will be wiped each run of this script! Depending on number of the events execution of this script may take from 5-20 minutes on M2 Pro processor.

  1. Execute manually:
    chmod +x Exchange_Sync.applescript
    osascript Exchange_Sync.applescript
    and allow all security pop-ups + Don't forget to grant full calendar rights from System settings > Privacy & Security > Calendars > App > Options > Full calendar access
  2. Schedule run under your username:
    crontab -e and paste+save: 0 9,14 * * * osascript /Users/user.name/macOS_Cronjobs/Exchange_Sync.applescript > /Users/user.name/macOS_Cronjobs/cronjob.log
    This script will be executed in the morning and the afternoon at 09:00 and 14:00.

Known issues:

  • Issue with repeating events
    • Unfortunately, Exchange works differently than regular Calendar.app and events that are recurring for 2+ weeks in the future won't be synced. There is an issue where the calendar expects eventStartDate and eventEndDate but Exchange does not provide such value for events that repeat on daily/weekly basis for months or even with no set end date.

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