⚠️ Experimental - This project is under active development. Use with care in production.
Automated calendar synchronization that mirrors "busy" time slots across multiple calendars to prevent double-booking.
- Full-mesh synchronization across Google Calendars and CalDAV
- Privacy-focused: synced events show only "Busy" status
- Automatic token refresh for long-running background operation
- Interactive configuration wizard
- Event lifecycle management (create, update, delete)
- Infinite loop prevention with sync markers
- Configurable sync interval
- Timed events only: Only events with specific start/end times are synced. All-day and multi-day events are not currently supported.
- Daemon mode (
java -jar busybee.jar run) - Has not been tested - Email alerts - Experimental, may be removed in a future release
- JVM 21+
./gradlew fatJarjava -jar busybee.jar configureThe wizard will guide you through:
- Select "Google Calendar (OAuth)"
- Enter OAuth Client ID/Secret (see below)
- Browser opens for authorization
- Copy authorization code
- Done! Tokens saved automatically
java -jar busybee.jar sync # Run once
java -jar busybee.jar run # Run as daemon (untested)- Go to Google Cloud Console
- Create OAuth 2.0 Client ID (Desktop app)
- Note your Client ID and Client Secret
- In OAuth consent screen → Test users → Add your email
That's it! The configure wizard handles the rest automatically.
For Infomaniak, IceWarp, or other CalDAV providers:
java -jar busybee.jar configureSelect "Generic CalDAV" and provide URL, username, password.
sudo cp src/scripts/busybee.service /etc/systemd/system/
sudo cp src/scripts/busybee.timer /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now busybee.timer| Option | Description | Default |
|---|---|---|
intervalMinutes |
Sync interval | 15 |
prefix |
Sync event prefix | "BB" |
- Fetches events from all configured calendars
- Identifies "original" events (not synced)
- Creates "[BB-]
" placeholder events in all other calendars - On original event update: updates all synced blocks
- On original event delete: removes all synced blocks
- Tokens stored in local
tokens/directory (add to.gitignore) - Synced events contain no sensitive details
- Run behind firewall/VPN for production use