Skip to content

Conversation

@pavsap
Copy link

@pavsap pavsap commented Sep 5, 2025

Overview

This PR adds support for Apple iCloud calendars via the CalDAV protocol, enabling users to sync their iCloud calendars with CalendarSync.

Features

  • Apple CalDAV adapter with basic authentication (Apple ID + app-specific password)
  • Dynamic calendar discovery - users can specify friendly names like "primary" instead of UUIDs
  • Full event synchronization - create, read, update, delete calendar events
  • iCalendar parsing using github.com/emersion/go-ical
  • Seamless integration with existing adapter architecture

Configuration Example

source:
  adapter:
    type: apple
    calendar: "primary"  # or any calendar name like "Work", "Family"
    oAuth:
      clientId: "[email protected]"
      clientKey: "app-specific-password"

Implementation Details

  • Uses CalDAV protocol (RFC 4791) with Apple's iCloud CalDAV endpoints
  • Reuses existing OAuth config fields for simplicity (clientId=Apple ID, clientKey=app-specific-password)
  • Implements dynamic principal and calendar UUID resolution
  • Supports both friendly names and direct UUID specification
  • Full iCalendar format support for event properties

Setup Requirements

  • Apple ID account
  • App-specific password generated from Apple ID settings (not regular iCloud password)
  • Calendar access permissions

Testing

☑️ Authentication with Apple ID + app-specific password
☑️ Calendar discovery and name resolution
☑️ Event reading from iCloud calendars
☑️ Integration with existing CalendarSync architecture

Recent Updates

☑️ Fixed CalDAV event creation (resolved 400 Bad Request errors)
☑️ Added thread-safe calendar resolution caching for performance
☑️ Fixed Google->Apple sync functionality

- Implement CalDAV client for Apple iCloud calendars
- Support basic auth with Apple ID + app-specific passwords
- Dynamic calendar discovery and friendly name resolution
- Full CRUD operations for calendar events
- iCalendar parsing using go-ical library
- Seamless integration with existing adapter pattern
- Fix CalDAV PUT request paths using resolved principal/calendar IDs
- Add required If-None-Match header for new event creation
- Implement thread-safe calendar resolution caching with sync.Once
- Combine CreateEvent/UpdateEvent methods to reduce duplication
- Resolve Google->Apple sync 400 Bad Request errors
- Generate consistent SyncID from iCal UID for better event matching
- Add 412 Precondition Failed error handling in CreateEvent
- Gracefully fallback to update operation when event already exists

This resolves conflicts in bidirectional sync scenarios where the same
logical event exists in both calendars with different UIDs, preventing
CalDAV 412 errors while maintaining sync functionality.
@mmisiewicz
Copy link

I would love to make use of this. I tried the Zep adapter as mentioned in #227 but no luck there.

@pavsap
Copy link
Author

pavsap commented Oct 7, 2025

@mmisiewicz, just copy my branch and compile it from source with make build

Use the compiled ./bin/calendarsync as you normally would.

Cron runs the daily bidirectional sync between my Primary (Apple) calendar and Work (Google Workspace) calendar.

@mmisiewicz
Copy link

Can confirm it's working great for me and I'd love to see this merged!

@pavsap
Copy link
Author

pavsap commented Jan 8, 2026

@MichaelEischer why is this one not moving?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants