CalDAV client library for calendar and event management.
CalDAVEx provides a clean, idiomatic Elixir interface to CalDAV servers with robust XML parsing, iCalendar support, and comprehensive event filtering.
Quick Start
# Create a client
config = CalDAVEx.new_config(
"https://caldav.example.com",
CalDAVEx.basic_auth("username", "password")
)
client = CalDAVEx.new_client(config)
# Discover calendar endpoints
{:ok, discovery_info} = CalDAVEx.discover(client)
# List calendars
{:ok, calendars} = CalDAVEx.list_calendars(client, discovery_info)
# Get events from a calendar
calendar = List.first(calendars)
{:ok, events} = CalDAVEx.list_events(client, calendar.url,
from: ~U[2025-05-01 00:00:00Z],
to: ~U[2025-05-31 23:59:59Z]
)Authentication
CalDAVEx supports multiple authentication methods:
basic_auth/2- HTTP Basic authenticationbearer_auth/1- Bearer token authenticationno_auth/0- No authentication (for testing)
Error Handling
All functions return {:ok, result} or {:error, %CalDAVEx.Error{}} tuples.
Use error_to_string/1 to convert errors to human-readable messages.
Summary
Functions
Creates HTTP Basic authentication configuration.
Creates Bearer token authentication configuration.
Creates a new event in a calendar.
Deletes an event.
Discovers the principal URL and calendar home set URL for the authenticated user.
Converts a CalDAVEx.Error to a human-readable string.
Retrieves a single event by its URL.
Lists all calendars for the authenticated user.
Lists events from a calendar with optional time-range filtering.
Creates a new CalDAV client from configuration.
Creates a new CalDAV client configuration.
Returns no authentication configuration.
Updates an existing event.
Sets the HTTP request timeout in milliseconds.
Sets a custom User-Agent header for the client.
Functions
Creates HTTP Basic authentication configuration.
Parameters
username- The username for authenticationpassword- The password for authentication
Examples
auth = CalDAVEx.basic_auth("user@example.com", "secret")
config = CalDAVEx.new_config("https://caldav.example.com", auth)
Creates Bearer token authentication configuration.
Parameters
token- The bearer token for authentication
Examples
auth = CalDAVEx.bearer_auth("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...")
config = CalDAVEx.new_config("https://caldav.example.com", auth)
Creates a new event in a calendar.
Note: This function is currently not fully implemented.
Parameters
client- The CalDAV clientcalendar_url- The URL of the calendarfilename- The filename for the event (e.g., "event.ics")ics_data- The iCalendar data as a string
Deletes an event.
Note: This function is currently not fully implemented.
Parameters
client- The CalDAV clientevent_url- The URL of the eventetag- Optional ETag for optimistic locking
Discovers the principal URL and calendar home set URL for the authenticated user.
This performs two PROPFIND requests:
- Queries the base URL for
current-user-principal - Queries the principal URL for
calendar-home-set
Parameters
client- The CalDAV client
Returns
{:ok, %CalDAVEx.Types.DiscoveryInfo{}}on success{:error, %CalDAVEx.Error{}}on failure
Examples
{:ok, discovery_info} = CalDAVEx.discover(client)
IO.inspect(discovery_info.principal_url)
IO.inspect(discovery_info.calendar_home_set_url)
Converts a CalDAVEx.Error to a human-readable string.
Parameters
error- A%CalDAVEx.Error{}struct
Examples
case CalDAVEx.list_events(client, calendar_url) do
{:ok, events} -> events
{:error, error} -> IO.puts(CalDAVEx.error_to_string(error))
end
Retrieves a single event by its URL.
Parameters
client- The CalDAV clientevent_url- The full URL of the event
Returns
{:ok, %CalDAVEx.Types.Event{}}on success{:error, %CalDAVEx.Error{}}on failure
Examples
{:ok, event} = CalDAVEx.get_event(client, "https://caldav.example.com/cal/event.ics")
IO.inspect(event.calendar_data)
Lists all calendars for the authenticated user.
Parameters
client- The CalDAV clientdiscovery_info- Discovery information fromdiscover/1
Returns
{:ok, [%CalDAVEx.Types.Calendar{}]}on success{:error, %CalDAVEx.Error{}}on failure
Examples
{:ok, discovery_info} = CalDAVEx.discover(client)
{:ok, calendars} = CalDAVEx.list_calendars(client, discovery_info)
Enum.each(calendars, fn cal ->
IO.puts("Calendar: #{cal.display_name} - #{cal.url}")
end)
Lists events from a calendar with optional time-range filtering.
Parameters
client- The CalDAV clientcalendar_url- The URL of the calendaropts- Optional keyword list::from- Start of time range (DateTime):to- End of time range (DateTime)
Returns
{:ok, [%CalDAVEx.Types.Event{}]}on success{:error, %CalDAVEx.Error{}}on failure
Examples
# Get all events
{:ok, events} = CalDAVEx.list_events(client, calendar.url)
# Get events in a date range
{:ok, events} = CalDAVEx.list_events(client, calendar.url,
from: ~U[2025-05-01 00:00:00Z],
to: ~U[2025-05-31 23:59:59Z]
)
# Get future events
{:ok, events} = CalDAVEx.list_events(client, calendar.url,
from: DateTime.utc_now()
)
Creates a new CalDAV client from configuration.
Parameters
config- The client configuration fromnew_config/2
Examples
config = CalDAVEx.new_config(base_url, auth)
client = CalDAVEx.new_client(config)
Creates a new CalDAV client configuration.
Parameters
base_url- The base URL of the CalDAV serverauth- Authentication configuration frombasic_auth/2,bearer_auth/1, orno_auth/0
Examples
config = CalDAVEx.new_config(
"https://caldav.icloud.com",
CalDAVEx.basic_auth("user@icloud.com", "app-specific-password")
)
Returns no authentication configuration.
Use this for testing or when connecting to servers that don't require authentication.
Examples
config = CalDAVEx.new_config("http://localhost:8080", CalDAVEx.no_auth())
Updates an existing event.
Note: This function is currently not fully implemented.
Parameters
client- The CalDAV clientevent_url- The URL of the eventics_data- The updated iCalendar dataetag- Optional ETag for optimistic locking
Sets the HTTP request timeout in milliseconds.
Parameters
config- The client configurationms- Timeout in milliseconds
Examples
config
|> CalDAVEx.with_timeout(30_000)
Sets a custom User-Agent header for the client.
Parameters
config- The client configurationua- The User-Agent string
Examples
config
|> CalDAVEx.with_user_agent("MyApp/1.0")