Install
openclaw skills install block-on-exchangeSync any ICS/iCal calendar to Microsoft Exchange as blocked time slots — supports recurring events, change detection, and privacy-preserving sync
openclaw skills install block-on-exchangeSync busy time from any ICS/iCal calendar to Microsoft Exchange as "Blocked" slots. Works with Google Calendar, iCloud, Outlook.com, Nextcloud, Fastmail, Proton Calendar, or any CalDAV server that publishes an ICS feed.
Requires Python 3.12+.
cd ~/.openclaw/skills/calin
bash install.sh
This creates a Python venv and installs icalendar, msal, recurring-ical-events, and requests.
Add to ~/.calintegration/.env (created by installer with chmod 600):
CALINT_ICS_URL=<your-ics-feed-url>
CALINT_MS_CLIENT_ID=<azure-app-client-id>
CALINT_MS_TENANT_ID=<azure-app-tenant-id>
# Optional: sync to a specific Exchange calendar (defaults to primary)
# CALINT_MS_CALENDAR_ID=<calendar-id>
Where to find your ICS URL:
| Provider | Location |
|---|---|
| Google Calendar | Settings > your calendar > Integrate > "Secret address in iCal format" |
| iCloud | Calendar app > right-click calendar > Share > Public Calendar > copy URL |
| Outlook.com | Settings > Calendar > Shared calendars > Publish > ICS link |
| Nextcloud | Calendar > three-dot menu > Copy subscription link |
| Fastmail | Settings > Calendars > Share/export > ICS URL |
Azure AD app (free, no client secret needed):
http://localhost:8400cd ~/.openclaw/skills/calin
venv/bin/python main.py setup
This opens a browser for one-time Microsoft login. Tokens are cached locally.
Run these from the skill directory:
| Command | What it does |
|---|---|
venv/bin/python main.py sync | Run one sync cycle |
venv/bin/python main.py status | Show last sync time and event count |
venv/bin/python main.py clear | Remove all synced events from Exchange |
venv/bin/python main.py setup | Re-run authentication setup |
The installer generates a launchd plist for automatic sync every 5 minutes:
cd ~/.openclaw/skills/calin
bash install.sh
cp com.calintegration.sync.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/com.calintegration.sync.plist
Change detection uses a hash of start time + end time + all-day flag. Only changed events trigger API calls.
~/.calintegration/.env with chmod 600 permissions~/.calintegration/ms_token.json with chmod 600 permissions~/.calintegration/ directory with chmod 700| Endpoint | Purpose | Auth |
|---|---|---|
| Your ICS URL (HTTPS) | Read calendar events | URL contains secret token |
login.microsoftonline.com | Microsoft OAuth token exchange | PKCE flow |
graph.microsoft.com/v1.0 | Create/update/delete Exchange events | Bearer token |
ICS Feed (read-only) --> [CalIn on your machine] --> Microsoft Graph API (write)
|
~/.calintegration/ (local state)
No data is sent to any third party. All processing happens locally.