Sample Header Ad - 728x90

Need assistance debugging an Apple Script for duplicating iCloud Calendar items not older than 30 days to a specific Outlook calendar

0 votes
1 answer
37 views
I have been creating an Apple Script that duplicates calendar items from our shared Family iCloud calendar to a work-related Outlook calendar with the same name (different email address). The following script has been iteratively generated with ChatGPT but it has at least 1 syntax error that I can't fix, relating to the apparently non-existent occurrence property of a Calendar.app event in the following line:
-- NOTE: the following line yields a syntax error "Expected class name but found identifier."
set occurrencesList to every occurrence of thisEvent
Can somebody help me out with this script?
-- Path to a file where we store the event UIDs
set uidFilePath to "~/Documents/icloud_event_uids.txt"

-- Create or read the list of already processed event UIDs
set uidFile to open for access (POSIX path of uidFilePath) with write permission
try
    set processedUIDs to read uidFile as text
on error
    -- If file does not exist, create an empty list
    set processedUIDs to ""
end try

tell application "Calendar"
    -- Select the iCloud calendar
    set sourceCalendar to calendar "Family" -- Replace "iCloud" with the actual calendar name if needed
    set eventList to every event of sourceCalendar
    
    -- Access Outlook application
    tell application "Microsoft Outlook"
        -- Select the Outlook calendar (replace with the name of your desired calendar)
        set targetCalendar to calendar "Calendar" -- Replace "Calendar" with the name of your Outlook calendar
        
        -- Get the current date for comparison
        set currentDate to current date
        set thirtyDaysAgo to currentDate - (30 * days)
        
        -- Normalize currentDate and thirtyDaysAgo to UTC
        set currentDateUTC to convertToUTC(currentDate)
        set thirtyDaysAgoUTC to convertToUTC(thirtyDaysAgo)
        
        -- Check for events older than 30 days in Outlook and remove them
        set outlookEventList to every calendar event of targetCalendar
        repeat with outlookEvent in outlookEventList
            set eventEnd to end time of outlookEvent
            set eventEndUTC to convertToUTC(eventEnd)
            if eventEndUTC < thirtyDaysAgoUTC then
                -- Remove event if its end time is older than 30 days
                delete outlookEvent
                -- Remove the UID of the deleted event from the processed list
                set eventUID to subject of outlookEvent -- Use the subject or another unique property to track this
                set processedUIDs to removeUID(eventUID, processedUIDs)
            end if
        end repeat
        
        repeat with thisEvent in eventList
            -- Get the start time, end time, summary, and UID of the iCloud event
            set eventStart to start date of thisEvent
            set eventEnd to end date of thisEvent
            set eventSummary to summary of thisEvent
            set eventLocation to location of thisEvent
            set eventDescription to description of thisEvent
            set eventUID to id of thisEvent -- iCloud unique identifier (UID)
            
            -- Normalize event start and end times to UTC
            set eventStartUTC to convertToUTC(eventStart)
            set eventEndUTC to convertToUTC(eventEnd)
            
            -- Check if the event UID has already been processed
            if eventUID is not in processedUIDs then
                -- Process this event (e.g., duplicate it into Outlook)
                
                -- Check if it's a recurring event
                if recurrence of thisEvent is not missing value then
                    -- Handle recurring event by extracting all occurrences
                    set recurrenceRule to recurrence of thisEvent
					-- NOTE: the following line yields a syntax error "Expected class name but found identifier."
                    set occurrencesList to every occurrence of thisEvent
                    
                    repeat with occurrence in occurrencesList
                        -- Get start and end time for each occurrence
                        set occurrenceStart to start date of occurrence
                        set occurrenceEnd to end date of occurrence
                        
                        -- Normalize occurrence start and end times to UTC
                        set occurrenceStartUTC to convertToUTC(occurrenceStart)
                        set occurrenceEndUTC to convertToUTC(occurrenceEnd)
                        
                        -- Check if the occurrence already exists in Outlook
                        set eventExists to false
                        set outlookEventList to every calendar event of targetCalendar
                        repeat with outlookEvent in outlookEventList
                            set outlookEventStart to start time of outlookEvent
                            set outlookEventStartUTC to convertToUTC(outlookEventStart)
                            if (outlookEventStartUTC is occurrenceStartUTC) and (subject of outlookEvent is eventSummary) then
                                set eventExists to true
                                exit repeat
                            end if
                        end repeat
                        
                        -- If the occurrence does not exist, create it
                        if eventExists is false then
                            make new calendar event at targetCalendar with properties {subject:eventSummary, start time:occurrenceStart, end time:occurrenceEnd, location:eventLocation, content:eventDescription}
                        end if
                    end repeat
                else
                    -- If it's a single (non-recurring) event, process as usual
                    set eventExists to false
                    set outlookEventList to every calendar event of targetCalendar
                    repeat with outlookEvent in outlookEventList
                        set outlookEventStart to start time of outlookEvent
                        set outlookEventStartUTC to convertToUTC(outlookEventStart)
                        if (outlookEventStartUTC is eventStartUTC) and (subject of outlookEvent is eventSummary) then
                            set eventExists to true
                            exit repeat
                        end if
                    end repeat
                    
                    -- If the event does not exist, create it
                    if eventExists is false then
                        make new calendar event at targetCalendar with properties {subject:eventSummary, start time:eventStart, end time:eventEnd, location:eventLocation, content:eventDescription}
                    end if
                end if
                
                -- Append this event UID to the list of processed UIDs
                set processedUIDs to processedUIDs & eventUID & linefeed
                write processedUIDs to uidFile
            end if
        end repeat
    end tell
end tell

-- Close the file after processing
close access uidFile

-- Function to remove UID from the processed list
on removeUID(thisUID, uidList)
    set textItemDelimiters to linefeed
    set uidListItems to every text item of uidList
    set newUIDList to {}
    
    repeat with currentUID in uidListItems
        if currentUID is not thisUID then
            set end of newUIDList to currentUID
        end if
    end repeat
    
    return (newUIDList as text)
end removeUID

-- Function to convert date to UTC
on convertToUTC(inputDate)
    set timeZoneOffset to (time zone of (current date)) -- Get the current time zone offset
    set utcDate to inputDate - timeZoneOffset -- Convert to UTC by subtracting the offset
    return utcDate
end convertToUTC
Asked by ShutterFreak (326 rep)
Feb 11, 2025, 10:14 PM
Last activity: Jul 13, 2025, 09:07 PM