As consultants, you may need to use multiple calendars (2-n). Additionally, you need to keep up with all existing appointments in each of your calendars when you want to make new appointments. This means you have to check each calendar on its own. What we wanted to achieve is a single overview over all events in each of the calendars. Preferably in your primary calendar.
There are some commercial / freemium solutions for this (reclaim.ai, SyncThemCalendars), but their privacy policy is unclear. Calendar data is not only highly interesting personal data (who participates in which appointment and when?) but also highly interesting from an industrial espionage/targeted advertising perspective. The two third party providers get to see the content of the calendar events. In good appointments, there is a lot of secret and relevant company data in the appointment agenda.
To keep track of all the events, we created CalendarSync
, which allows the
syncing of events without breaking data protection laws and without exposing
data to a third party.
Download the newest release for your platform or install from the AUR.
Using asdf-vm
You can also install this program using asdf-vm
.
asdf plugin add calendarsync
# or
asdf plugin add calendarsync https://github.com/FeryET/asdf-calendarsync.git
## finally
asdf install calendarsync
Note: The asdf
plugin is not managed by inovex, but is provided by a CalendarSync user. inovex assumes no responsibility for proper provisioning.
Create a modified sync.yaml
file based on the content of the ./example.sync.yaml
file. Finally, start the app using CALENDARSYNC_ENCRYPTION_KEY=<YourSecretPassword> ./calendarsync --config sync.yaml
and follow the instructions in the output.
The app will create a file in the execution folder called auth-storage.yaml
. In this file the OAuth2 Credentials will be saved encrypted by your $CALENDARSYNC_ENCRYPTION_KEY
.
The CalendarSync config file consists of several building blocks:
sync
- Controls the timeframe to be syncedsource
- Controls the source calendar to be synced fromsink
- Controls the sink (target) calendar where the events from the source calendar are written totransformations
- Controls the transformers applied to the events before syncingfilters
- Controls filters, which allow events to be excluded from syncingauth
- Controls settings regarding the encrypted auth storage file
Should be self-explanatory. Configures the timeframe where to sync events. The
currently only implemented identifiers are MonthStart
and MonthEnd
.
sync:
start:
identifier: MonthStart # 1st of the current month
offset: -1 # MonthStart -1 month (beginning of last month)
end:
identifier: MonthEnd # last day of the current month
offset: +1 # MonthEnd +1 month (end of next month)
Example:
source:
adapter:
type: "outlook_http"
calendar: "[base64-formatstring here]"
oAuth:
clientId: "[UUID-format string here]"
tenantId: "[UUID-format string here]"
Configures the Source Adapter, for the adapter configuration, check the documentation here.
- Outlook
- ZEP
Example:
sink:
adapter:
type: google
calendar: "target-calendar@group.calendar.google.com"
oAuth:
clientId: "[google-oAuth-client-id]"
clientKey: "[google-oAuth-client-key]"
Configures the Sink Adapter, for the adapter configuration, check the documentation here.
- Outlook
Basically, only the time is synced. By means of transformers one can sync
individual further data. Some transformers allow for further configuration using
an additional config
block, such as the ReplaceTitle
transformer. Below is a
list of all transformers available:
transformations:
- name: KeepDescription
- name: KeepLocation
- name: KeepReminders
- name: KeepTitle
- name: PrefixTitle
config:
Prefix: "[Sync] "
- name: ReplaceTitle
config:
NewTitle: "[synchronized appointment]"
# Do not use KeepAttendees when the Outlook Adapter is used as a sink. There is no way to suppress mail invitations
- name: KeepAttendees
config:
UseEmailAsDisplayName: true
The transformers are applied in a specific order. The order is defined here:
internal/sync/transformer.go
In some cases events should not be synced. For example, declined events might create too much noise in the target calendar. These can be filtered by enabling the corresponding filter.
# Filters remove events from being synced due to different criteria
filters:
# Events where you declined the invitation aren't synced
- name: DeclinedEvents
# Events which cover the full day aren't synced
- name: AllDayEvents
# Events within the specified timeframe will be retained, while all others will be filtered out.
# hours are represented in the 24h time format
- name: TimeFrame
config:
HourStart: 8
HourEnd: 17
# Events where the title matches the ExcludeRegexp (RE2 Regex) aren't synced
- name: RegexTitle
config:
ExcludeRegexp: ".*test"
In this section you can configure settings regarding the encrypted local auth storage
auth:
storage_mode: yaml # Currently, only yaml is supported
config:
# Here you can use the standard unix abbreviation for home directory (~).
# This works also for Windows systems e.g. ~\calendar-sync\auth-storage.yaml
path: "./auth-storage.yaml"
You just synced a lot of events in your calendar and decide you want to use a separate calendar for this? Or you want to remove all the synced events from your calendar?
Use the --clean
flag to get rid of all the unwanted events. (We leave your
events which weren't synced with CalendarSync alone! :) )
GOOGLE is a trademark of GOOGLE INC. OUTLOOK is a trademark of Microsoft Corporation
RFC 5545 Internet Calendaring and Scheduling Core Object Specification (iCalendar) is used in the Google calendar API to denote recurrence patterns. CalDav RFC 4791 uses the dateformat specified in RFC 5545.
MIT