Skip to Content
Menu

CalDAV Synchronization

by
Odoo 6
v 17.0 Third Party 315
Download for v 17.0 Deploy on Odoo.sh
Availability
Odoo Online
Odoo.sh
On Premise
Odoo Apps Dependencies Calendar (calendar)
Discuss (mail)
Lines of code 829
Technical Name caldav_sync
LicenseLGPL-3
Websitehttps://www.bemade.org
Versions 17.0
You bought this module and need support? Click here!
Availability
Odoo Online
Odoo.sh
On Premise
Odoo Apps Dependencies Calendar (calendar)
Discuss (mail)
Lines of code 829
Technical Name caldav_sync
LicenseLGPL-3
Websitehttps://www.bemade.org
Versions 17.0

CalDAV Synchronization

Main Screenshot

Author: Bemade Inc. (Marc Durepos)

Website: www.bemade.org

License: GNU Lesser General Public License (LGPL-3)

Overview

The CalDAV Synchronization module for Odoo allows users to synchronize their calendar events with CalDAV servers. This enables seamless integration of Odoo calendar with external applications like Apple Calendar or Thunderbird.

Warning

This module is in early development stages and should not be considered stable. Please test it on an unimportant calendar before using it with your important data. We are working hard to make improvements based on user feedback, so please reach out if you run into any issues or need a specific feature.

Features

  • Synchronize Odoo calendar events with CalDAV servers.
  • Create, update, and delete events in Odoo and reflect changes on the CalDAV server.
  • Poll CalDAV server for changes and update Odoo calendar accordingly.

Configuration

  1. Install the module in Odoo.
  2. Go to the User settings in Odoo.
  3. Enter the CalDAV calendar URL, username, and password on the user settings. In some cases, the calendar URL to use is not evident. For Apple iCloud calendars, for example, we recommend starting with the base server url at https://caldav.icloud.com/ and then selecting a specific calendar url from the error given in the server logs.

Note: Some calendar service providers such as Apple iCloud require app-specific passwords to be set so that the calendar API can bypass 2-factor authentication. Please look into setting up app-specific passwords for your cloud calendar provider if you're faced with authentication errors.

Usage

  1. Create a calendar event in Odoo and it will be synchronized with the CalDAV calendar.
  2. Update the event in Odoo and the changes will reflect on the CalDAV server.
  3. Delete the event in Odoo and it will be removed from the CalDAV server.
  4. Changes made to the calendar on the CalDAV server will be polled and updated in Odoo.

Technical Details

The module extends the calendar.event model to add CalDAV synchronization functionality. It uses the icalendar library to format events and the caldav library to interact with CalDAV servers. Polling for changes on the CalDAV server can be triggered manually by triggering the scheduled action in Odoo.

Support

If you have any issues with the module or feature requests, please reach out to us by creating an issue on our Gitlab at https://git.bemade.org/bemade/bemade-addons or by submitting a request on our website at https://www.bemade.org

Please log in to comment on this module

  • The author can leave a single reply to each comment.
  • This section is meant to ask simple questions or leave a rating. Every report of a problem experienced while using the module should be addressed to the author directly (refer to the following point).
  • If you want to start a discussion with the author, please use the developer contact information. They can usually be found in the description.
Please choose a rating from 1 to 5 for this module.
Great Developer!!!
by
Richard Evans
on 11/13/24, 9:35 AM

Thank you Marc for all of the support. I hope this helps balance out the review I did earlier. I truly thought I could go back and update my review as we worked on things.

For everyone else, The developer has reached out to me and worked with me one on one so we can get things built out correctly. His dedication to his product and user alone deserve 5 stars. Thank you for your time and I hope to see your offering grow and become perfected!


Thank You! 


Awesome! (And a bug report)
by
Thomas Hümmer
on 10/29/24, 3:58 AM

Thanks you very much! Indeed this is the missing puzzle piece in our odoo.

And it now already works much better than before!

However there is one bug:

If an event was moved once (in odoo or from external) the next move will throw this error:

odoo.addons.caldav_sync.models.calendar_event: Failed to sync event to CalDAV server: PutError at '409 Conflict b''', reason no reason


Thanks you !!
by
Nourdine Gernelle
on 10/15/24, 7:45 AM

Thank you so much for this feature that was missing in Odoo!

However, when creating a video meeting, the invitation and the link are sent by Nextcloud. Is it possible to let Odoo manage the meeting links as well as the invitations?

Thank you.

Re: Thanks you !!
by
Marc Durepos
on 10/15/24, 12:06 PM Author

Thanks for your kind note, Nourdine. If you create the meeting in the Odoo calendar you should be able to add the video call from there. I haven't tested with NextCloud so I don't know if it overwrites the iCal field for the video call URL. If not, you should even be able to head to your Odoo calendar and use the "clear meeting" button to remove the NextCloud URL and then add the Odoo Discuss call.


Excellent. but it has a few bugs.
by
Wombat
on 7/9/24, 2:16 AM

My first attempt was on 17 community - which did not work at all. I then tested on a 17 Enterprise and it seemed to work really well. But... 
- As others have mentioned, changing the appointment on the caldav server did not update Odoo. 
- Later I created another appointment in Odoo which replicated to the caldav server fine. Then I tried to change the time of the appointment in Odoo which replicated but this time it change the time of the appointment on the caldav and treated it as if were UTC time instead of my timezone. Naturally, the appointment is now offset. 
- When I tried to delete an appointment from Odoo, the appointment remained on the caldav server. 

I'm sure all these little issue can be quickly fixed pretty easily for these talented guys.
Sincerely, keep up the awesome work bemade.org!!! Hanging out for the updates.

Re: Excellent. but it has a few bugs.
by
Marc Durepos
on 10/8/24, 6:11 PM Author

Thanks for your comment. I've recently updated the module with some pretty major fixes and a boatload of test cases. Give it a whirl and let me know what works and what doesn't.


Sorta working, but needs some fixes....
by
Jonathan Hall
on 7/3/24, 7:13 PM

Adding a calendar item in to the Odoo calendar works and the entry appears on the remote Caldav calendar. But deleting it from Odoo, or even deleting it from the calendar, results in various errors:

2024-07-04 00:09:26,461 18113 ERROR com odoo.addons.base.models.ir_cron: Call from cron CalDAV Sync for server action #716 failed in Job #38 

Traceback (most recent call last):

  File "/odoo/odoo/tools/safe_eval.py", line 367, in safe_eval

    return unsafe_eval(c, globals_dict, locals_dict)

           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "ir.actions.server(716,)", line 1, in

  File "/odoo_addons/caldav_sync/models/calendar_event.py", line 203, in poll_caldav_server

    self.with_user(user).poll_user_caldav_server()

  File "/odoo_addons/caldav_sync/models/calendar_event.py", line 235, in poll_user_caldav_server

    ical_event = caldav_event.icalendar_instance

                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.11/dist-packages/caldav/objects.py", line 2403, in _get_icalendar_instance

    self.icalendar_instance = icalendar.Calendar.from_ical(

                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.11/dist-packages/icalendar/cal.py", line 414, in from_ical

    raise ValueError(cls._format_error(

ValueError: Found no components where exactly one is required: 



During handling of the above exception, another exception occurred:


Traceback (most recent call last):

  File "/odoo/odoo/addons/base/models/ir_cron.py", line 392, in _callback

    self.env['ir.actions.server'].browse(server_action_id).run()

  File "/odoo/odoo/addons/base/models/ir_actions.py", line 942, in run

    res = runner(run_self, eval_context=eval_context)

          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/odoo/addons/website/models/ir_actions_server.py", line 61, in _run_action_code_multi

    res = super(ServerAction, self)._run_action_code_multi(eval_context)

          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/odoo/odoo/addons/base/models/ir_actions.py", line 772, in _run_action_code_multi

    safe_eval(self.code.strip(), eval_context, mode="exec", nocopy=True, filename=str(self))  # nocopy allows to return 'action'

    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/odoo/odoo/tools/safe_eval.py", line 381, in safe_eval

    raise ValueError('%s: "%s" while evaluating\n%r' % (ustr(type(e)), ustr(e), expr))

ValueError: : "Found no components where exactly one is required: 

" while evaluating

'model.poll_caldav_server()'

In addition to:

2024-07-03 23:57:04,296 18185 WARNING crm root: Error ReportError at '412 Precondition Failed


b''', reason no reason from server when doing an object_by_uid(40cfad99-9993-4125-a1b0-b044879682a3).  search without compfilter set is not compatible with all server implementations, trying event_by_uid + todo_by_uid + journal_by_uid instead 

2024-07-03 23:57:04,538 18185 ERROR crm odoo.addons.caldav_sync.models.calendar_event: Failed to remove event from CalDAV server: ReportError at '412 Precondition Failed





Re: Sorta working, but needs some fixes....
by
Marc Durepos
on 10/8/24, 6:13 PM Author

Hi, thanks for your comment and your patience with this still very early-stages module. I've just uploaded a major update with significantly more automated tests. Please give it a try and let me know if you're still having any issues.


Very good idea, though a bit complicated to setup.
by
Peter Romão
on 6/21/24, 7:34 AM

Hello,

I am receiving the following error after having created an App Specific password in Apple ID.

caldav.lib.error.AuthorizationError: AuthorizationError at 'https://caldav.icloud.com/', reason Forbidden

What can I be doing wrong?

Thanks,

Re: Very good idea, though a bit complicated to setup.
by
Marc Durepos
on 6/21/24, 3:24 PM Author

Thanks for your comment, Peter. I have not personally tried with iCloud but from the URL you've posted it looks to me like the calendar-specific part of the URL is missing. When I share a calendar from Apple's Calendar app, I can right-click on the calendar and "Get Info" or "Copy URL to Clipboard". I'd suggest trying that URL instead. Please feel free to let me know how it goes and if you run into other issues at marc@bemade.org.


Issues
by
Jessica Naves
on 4/17/25, 4:03 AM

Every time I try to connect it to Odoo I get an error. I even tried to download the new code from GitHub and getting the same issue. 

Invalid Operation

Error while importing module 'caldav_sync'. while parsing /tmp/tmpyb5lzcg9/caldav_sync/views/res_users_views.xml:3 Error while validating view near: <header> <button string="Re-send Invitation Email" type="object" name="action_reset_password" invisible="state != 'active'"/> <button string="Send an Invitation Email" type="object" name="action_reset_password" context="{'create_user': 1}" invisible="state != 'new'"/> <field name="state" widget="statusbar"/> </header> Field "caldav_calendar_url" does not exist in model "res.users" View error context: {'file': '/tmp/tmpyb5lzcg9/caldav_sync/views/res_users_views.xml', 'line': 4, 'name': 'res.users.form.inherit', 'view': ir.ui.view(2959,), 'view.model': 'res.users', 'view.parent': ir.ui.view(164,), 'xmlid': 'view_users_form_inherit'}



Re: Issues
by
Marc Durepos
on 4/17/25, 5:46 AM Author

This looks like your module is simply out of sync between the JS code running in the browser and what’s on the server. Try this:


  1. Restart the Odoo server to load the latest Python code.
  2. Upgrade the module from apps within your Odoo.
  3. Refresh your browser and try again.

Good luck! Feel free to reach out at marc@bemade.org if this doesn’t work for you.



Request for Odoo version 18
by
Andreas Gegenleitner
on 2/1/25, 6:47 PM

Hello,

I would very much appreciate it if this app would be updated for Odoo version 18. 

Many thanks in advance! :)


Re: Request for Odoo version 18
by
Marc Durepos
on 4/17/25, 5:47 AM Author

Hello Andreas,

our 18.0 repo is not yet available on apps.odoo.com but you can get jt at git.bemade.org/bemade/bemade-addons


Community edition
by
Seconda Vita
on 1/4/25, 4:34 PM

In the ratings section, someone noted it won't work with the community edition.

Currently, I exactly have this issue as the sync doesn't work.

I get "CalDav Sync started" and "CalDav Sync ended" in the log files (Odoo 17, on-premise), but no sync occurs in either ways.

After looking through the sources, my impression is that it neither enters the poo nor the push event section.

Can someone confirm or deny this and if this is true, why that is the case?


I want to give more stars
by
Richard Evans
on 10/30/24, 2:39 PM

I would very much like to give this more stars ad it is a much needed feature in Odoo but this module continuously added the same events over and over from my caldav server to Odoo that it grind the entire DB to a halt. It was almost unusable.

I very much want to help improve this module so please let me know what you need and I will provide whatever is needed to get this working. 

A two way sync with my CalDAV server would be great, as of right now it is a manual process.

Re: I want to give more stars
by
Marc Durepos
on 10/30/24, 7:07 PM Author

Hi Richard,

Thanks for the report. That’s a new one for me. If you have a calendar server to which you can set up a test user and give me access, I could try to debug from a dev server.

Please write me directly at marc@bemade.org and I’ll see what I can do. The more people who use this module the more bugs we’ll be able to catch and fix!


Will this module be available for v18 soon?
by
Jürgen J. Schimmöller
on 10/30/24, 2:36 PM



Thanks a lot !!
by
Nourdine Gernelle
on 10/15/24, 7:44 AM

Thank you so much for this feature that was missing in Odoo!

However, when creating a video meeting, the invitation and the link are sent by Nextcloud. Is it possible to let Odoo manage the meeting links as well as the invitations?

Thank you.


Fixed an issue with recurring together with Nextcloud/emClient
by
BertS
on 9/19/24, 3:01 AM

Hi,

When syncing recurring events from my Nextcloud-instance (where event is created from emClient, I experienced following error:

`ValueError: RRULE UNTIL values must be specified in UTC when DTSTART is timezone-aware`


Startdate was given with timezone, and UNTIL was like `FREQ=WEEKLY;UNTIL=20250429T173000;BYDAY=MO;WKST=SU`


Odoo's internal datetime handling for recurring events strubbled with this.

I've fixed it in my instance, in calendar_event.py:


1. add method:

```

    def _rrule_until_contains_tzinfo(self, rrule_str):

        match = re.search(r'UNTIL=([0-9T]+)', rrule_str)

        if match:

            until_str = match.group(1)


            contains_timezone = '+' in until_str or bool(re.search(r'[A-Z]{3}', until_str))


            if not contains_timezone:

                return True

            else:

                return False

        else:

            return False

```


2. before passing dtstart to _rrule_parse, check for this and eventually remove tzinfo from dtstart after converting it to UTC (don't forget `from zoneinfo import ZoneInfo`) :

```

        dtstart = component.decoded("dtstart")

        if self._rrule_until_contains_tzinfo(rrule_str):

            dtstart = dtstart.astimezone(ZoneInfo("UTC")).replace(tzinfo=None)

        rrule_params = self.env["calendar.recurrence"]._rrule_parse(

            rrule_str, dtstart

        )

```


some more details
by
Jonathan Hall
on 7/4/24, 6:02 AM

2024-07-04 10:59:55,475 18321 WARNING crm odoo.api.create: The model odoo.addons.caldav_sync.models.calendar_event is not overriding the create method in batch 

2024-07-04 10:59:57,207 18321 WARNING crm odoo.fields: Field res.users.caldav_password: unknown parameter 'password', if this is an actual parameter you may want to override the method _valid_field_parameter on the relevant model in order to allow it 

2024-07-04 10:59:57,234 18321 WARNING crm py.warnings: /odoo/odoo/fields.py:542: UserWarning: Since Odoo 17, property calendar.event.description.states is no longer supported.



by
Jonathan Hall
on 7/3/24, 7:12 PM

Looks to have a few bugs... Adding a calendar item in to the Odoo calendar works and the entry appears on the remote Caldav calendar. But deleting it from Odoo, or even deleting it from the calendar, results in various errors:

2024-07-04 00:09:26,461 18113 ERROR com odoo.addons.base.models.ir_cron: Call from cron CalDAV Sync for server action #716 failed in Job #38 

Traceback (most recent call last):

  File "/odoo/odoo/tools/safe_eval.py", line 367, in safe_eval

    return unsafe_eval(c, globals_dict, locals_dict)

           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "ir.actions.server(716,)", line 1, in

  File "/odoo_addons/caldav_sync/models/calendar_event.py", line 203, in poll_caldav_server

    self.with_user(user).poll_user_caldav_server()

  File "/odoo_addons/caldav_sync/models/calendar_event.py", line 235, in poll_user_caldav_server

    ical_event = caldav_event.icalendar_instance

                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.11/dist-packages/caldav/objects.py", line 2403, in _get_icalendar_instance

    self.icalendar_instance = icalendar.Calendar.from_ical(

                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.11/dist-packages/icalendar/cal.py", line 414, in from_ical

    raise ValueError(cls._format_error(

ValueError: Found no components where exactly one is required: 



During handling of the above exception, another exception occurred:


Traceback (most recent call last):

  File "/odoo/odoo/addons/base/models/ir_cron.py", line 392, in _callback

    self.env['ir.actions.server'].browse(server_action_id).run()

  File "/odoo/odoo/addons/base/models/ir_actions.py", line 942, in run

    res = runner(run_self, eval_context=eval_context)

          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/odoo/addons/website/models/ir_actions_server.py", line 61, in _run_action_code_multi

    res = super(ServerAction, self)._run_action_code_multi(eval_context)

          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/odoo/odoo/addons/base/models/ir_actions.py", line 772, in _run_action_code_multi

    safe_eval(self.code.strip(), eval_context, mode="exec", nocopy=True, filename=str(self))  # nocopy allows to return 'action'

    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/odoo/odoo/tools/safe_eval.py", line 381, in safe_eval

    raise ValueError('%s: "%s" while evaluating\n%r' % (ustr(type(e)), ustr(e), expr))

ValueError: : "Found no components where exactly one is required: 

" while evaluating

'model.poll_caldav_server()'

In addition to:

2024-07-03 23:57:04,296 18185 WARNING crm root: Error ReportError at '412 Precondition Failed


b''', reason no reason from server when doing an object_by_uid(40cfad99-9993-4125-a1b0-b044879682a3).  search without compfilter set is not compatible with all server implementations, trying event_by_uid + todo_by_uid + journal_by_uid instead 

2024-07-03 23:57:04,538 18185 ERROR growthmeta_crm odoo.addons.caldav_sync.models.calendar_event: Failed to remove event from CalDAV server: ReportError at '412 Precondition Failed






Error connecting
by
Wombat
on 6/29/24, 8:53 PM

RPC_ERROR

Odoo Server Error

Traceback (most recent call last):

  File "/opt/odoosrc/17.0/odoo/odoo/tools/safe_eval.py", line 390, in safe_eval

    return unsafe_eval(c, globals_dict, locals_dict)

  File "ir.actions.server(293,)", line 1, in

  File "/opt/cyder/clients/cal/cal_addons/caldav_sync/models/calendar_event.py", line 203, in poll_caldav_server

    self.with_user(user).poll_user_caldav_server()

  File "/opt/cyder/clients/cal/cal_addons/caldav_sync/models/calendar_event.py", line 236, in poll_user_caldav_server

    self.sync_event_from_ical(ical_event)

  File "/opt/cyder/clients/cal/cal_addons/caldav_sync/models/calendar_event.py", line 380, in sync_event_from_ical

    recurrency_vals = self._get_recurrency_values_from_ical_event(component)

  File "/opt/cyder/clients/cal/cal_addons/caldav_sync/models/calendar_event.py", line 318, in _get_recurrency_values_from_ical_event

    vals.update(rrule_params.get("weekday"))

ValueError: dictionary update sequence element #0 has length 1; 2 is required


During handling of the above exception, another exception occurred:


Traceback (most recent call last):

  File "/opt/odoosrc/17.0/odoo/odoo/http.py", line 1764, in _serve_db

    return service_model.retrying(self._serve_ir_http, self.env)

  File "/opt/odoosrc/17.0/odoo/odoo/service/model.py", line 133, in retrying

    result = func()

  File "/opt/odoosrc/17.0/odoo/odoo/http.py", line 1791, in _serve_ir_http

    response = self.dispatcher.dispatch(rule.endpoint, args)

  File "/opt/odoosrc/17.0/odoo/odoo/http.py", line 1995, in dispatch

    result = self.request.registry['ir.http']._dispatch(endpoint)

  File "/opt/odoosrc/17.0/odoo/odoo/addons/base/models/ir_http.py", line 222, in _dispatch

    result = endpoint(**request.params)

  File "/opt/odoosrc/17.0/odoo/odoo/http.py", line 741, in route_wrapper

    result = endpoint(self, *args, **params_ok)

  File "/opt/odoosrc/17.0/odoo/addons/web/controllers/dataset.py", line 28, in call_button

    action = self._call_kw(model, method, args, kwargs)

  File "/opt/odoosrc/17.0/odoo/addons/web/controllers/dataset.py", line 20, in _call_kw

    return call_kw(request.env[model], method, args, kwargs)

  File "/opt/odoosrc/17.0/odoo/odoo/api.py", line 468, in call_kw

    result = _call_kw_multi(method, model, args, kwargs)

  File "/opt/odoosrc/17.0/odoo/odoo/api.py", line 453, in _call_kw_multi

    result = method(recs, *args, **kwargs)

  File "/opt/odoosrc/17.0/odoo/odoo/addons/base/models/ir_cron.py", line 107, in method_direct_trigger

    cron.with_user(cron.user_id).with_context({'lastcall': cron.lastcall}).ir_actions_server_id.run()

  File "/opt/odoosrc/17.0/odoo/odoo/addons/base/models/ir_actions.py", line 943, in run

    res = runner(run_self, eval_context=eval_context)

  File "/opt/odoosrc/17.0/odoo/odoo/addons/base/models/ir_actions.py", line 773, in _run_action_code_multi

    safe_eval(self.code.strip(), eval_context, mode="exec", nocopy=True, filename=str(self))  # nocopy allows to return 'action'

  File "/opt/odoosrc/17.0/odoo/odoo/tools/safe_eval.py", line 404, in safe_eval

    raise ValueError('%s: "%s" while evaluating\n%r' % (ustr(type(e)), ustr(e), expr))

ValueError: : "dictionary update sequence element #0 has length 1; 2 is required" while evaluating

'model.poll_caldav_server()'


The above server error caused the following client error:

RPC_ERROR: Odoo Server Error

    RPCError@https://cal.cyder.com.au/web/assets/0717d44/web.assets_web.min.js:2871:319

    makeErrorFromResponse@https://cal.cyder.com.au/web/assets/0717d44/web.assets_web.min.js:2874:163

    jsonrpc/promisehttps://cal.cyder.com.au/web/assets/0717d44/web.assets_web.min.js:2878:34


Installed now
by
Wombat
on 6/29/24, 8:41 PM

Got it to install: pip install --force-reinstall -v caldav==1.3.8



Install errors
by
Wombat
on 6/29/24, 7:05 PM

Hi tried to install but now get this message: Unable to install module "caldav_sync" because an external dependency is not met: Python library version conflict: caldav


I have "pip install caldav" in the environment which installed 1.3.9.