[SOLVED] Apple icloud CalDav connection

I cant seem to find anyone who has successfully got apple icloud caldav connectivity. The binding may not support the application password option?
Can anyone share how they have done this, and how I would identify my caldav URL without a mac and looking in plist files?

This article appears to be helpful.

If I had a mac that would be - however I have managed to work through this and will post my own answer shortly

It doesn’t require a Mac, but glad to hear you found a solution that works for you.

Sorry I read iCal as a mac app - I have found an easier way to determine the URL with cURL commands

OK to so to do this via cURL:

Log into your Apple account at appleid.apple.com. Confirm your login by entering the two-factor identification code sent to your primary device. Once logged in, look for the section in your Apple ID control panel labeled “Security” and click on “Generate Password”

When prompted, label the app-specific password whatever you want eg “OpenHab” and click “Create”.

Apple will provide you with a randomly generated alphanumeric string in the format xxx-xxxx-xxxx-xxxx. Highlight and copy the password and keep it somewhere safe.

Next open a console that can run cURL

run this (replacing $APPLEID with your own Apple ID :

curl -s -X PROPFIND -u "$APPLEID" -H "Depth: 0"  --data "<propfind xmlns='DAV:'><prop><current-user-principal/></prop></propfind>"  https://caldav.icloud.com/

When propmted for creentials, enter in the app-specific password

You should get a response and it shows you the URL of your account record, it looks something like https://caldav.icloud.com/347723822/principal/

Next run this (replacing your numeric ID)

curl -s -X PROPFIND -u "$APPLEID" -H "Depth: 0"  --data "<propfind xmlns='DAV:' xmlns:cd='urn:ietf:params:xml:ns:caldav'><prop><cd:calendar-home-set/></prop></propfind>" 
 https://caldav.icloud.com/347723822/principal/

This gives you the reference to the cluster the actual calendars lives on, it looks something like https://p22-caldav.icloud.com:443/347723822/calendars

You can list all the calendars from your icloud account by running (replacing with your output from above):

curl -s -X PROPFIND -u "$APPLEID" -H "Depth: 1"  --data "<propfind xmlns='DAV:'><prop><displayname/></prop></propfind>"  https://p42-caldav.icloud.com:443/347723822/calendars/ | grep displayname

then strip off the grep to show all info about each calendar:

curl -s -X PROPFIND -u "$APPLEID" -H "Depth: 1"  --data "<propfind xmlns='DAV:'><prop><displayname/></prop></propfind>"  https://p42-caldav.icloud.com:443/347723822/calendars/ 

You may need to up your history buffer depending on the number of calendars you have.

You are looking for the href value if the calendar you are after eg

<href>/1317873642/calendars/086e6106-1c0d-4301-a99d-5c5ebbcc5079/</href>

Once you have this, glue it together:

https://p42-caldav.icloud.com:443/347723822/calendars/086e6106-1c0d-4301-a99d-5c5ebbcc5079/

And that is your calDAV URL

Now in caldavio.cfg

caldavio:AJ:url=https://p42-caldav.icloud.com:443/347723822/calendars/086e6106-1c0d-4301-a99d-5c5ebbcc5079/
caldavio:AJ:username=myicloudusername
caldavio:AJ:password=myappspecifipass
caldavio:AJ:reloadInterval=60
caldavio:AJ:preloadTime=20000
caldavio:AJ:disableCertificateVerification=false
caldavio:timeZone=Australia/Adelaide

and in calDAVPersonal.cfg

caldavPersonal:usedCalendars=AJ

Then a few items

String OfficeCalName0   "Next Up [%s]"     <calendar>  { caldavPersonal="calendar:AJ type:EVENT eventNr:1 value:NAME" } 
DateTime OfficeCalTime0 "Starts [%1$tT, %1$td.%1$tm.%1$tY]"         <calendar>  { caldavPersonal="calendar:AJ type:EVENT eventNr:1 value:START" }

and on the sitemap

Text item=OfficeCalName0 
Text item=OfficeCalTime0

Done!

5 Likes

Excellent writeup! I’ve been wanting to do this for a while and you certainly made it a whole lot easier, thank you!

Mikael

Hello. I tried it like your writeup.
But I got following error:

Failed to parse request body as XML

Please help me.

Hans

have you substituted the calendar GUIDs for your own?

Hello.

I got the error after the first command line with my apple ID
curl -s -X PROPFIND -u “$APPLEID” -H “Depth: 0” --data “/prop>” https://caldav.icloud.com/

So you are substituting $APPLEID with your own Apple ID?

What is the error

Thanks
Andrew

Hello!

I tipped the “curl -s -X PROPFIND -u “$APPLEID” -H “Depth: 0” --data “/prop>” https://caldav.icloud.com/” and pressed ENTER.
I got back “Failed to parse request body as XML”

[12:55:50] openhabian@openHABianPi:~$ curl -s -X PROPFIND -u "xxxx.xxx@xxx.com" -H “Depth: 0” --data “/prop>” https://caldav.icloud.com/
Enter host password for user ‘xxxx.xxx@xxx.com’:
Failed to parse request body as XML[12:56:13] openhabian@openHABianPi:~$

I remember having Similan problems. I think I ended up using what I found here, and it worked fine.

So your command doesn’t look complete?

curl -s -X PROPFIND -u "$APPLEID" -H "Depth: 0"  --data "<propfind xmlns='DAV:'><prop><current-user-principal/></prop></propfind>"  https://caldav.icloud.com/

Hi Andrew,
thanks for your great tutorial. I also had the error:

Failed to parse request body as XML

But could figure out why it was not working

You forgot a < in the first command to while closing </prop>, so it should look like this:

curl -s -X PROPFIND -u "$APPLEID" -H "Depth: 0" --data "<propfind xmlns='DAV:'><prop><current-user-principal/></prop></propfind>" https://caldav.icloud.com/

Thanks again, I hope I could help!

Cheers

@walterwampe good find! thanks I have changed the original post

@Andrew_Pawelski Hi Andrew. I just tried the above CURL statements with different IDs. Unfortunatelly the statements don’t return anything. Can you confirm that your approach still works? Thank you very much!

yep my calendar is still working

@Andrew_Pawelski Hi Andrew. Thank you. My question was rather related to the above CURL statements.

curl -s -X PROPFIND -u "abcd@abcd.com" -H "Depth: 0"  --data "<propfind xmlns='DAV:'><prop><current-user-principal/></prop></propfind>"  https://caldav.icloud.com/

The above statement doesn’t return anything and also entering a wrong password results in a message (I replaced of course abcd@abcd.com with my own iCloud account).

if thats the complete curl command you are missing numbers off the end specific to your icloud account