/install block-on-exchange
CalIn — ICS Calendar to Exchange Sync
Sync 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.
When to Use This Skill
- User asks to sync calendars, block time, or mirror busy slots
- User wants personal calendar events to block time on their work calendar
- User asks to check sync status or clear synced events
- Scheduled background sync via Heartbeat (recommended: every 5-30 minutes)
What It Does
- Fetches events (including recurring) from any HTTPS ICS feed
- Creates/updates/deletes corresponding "Blocked" events on Exchange via Microsoft Graph API
- Tracks synced events with a local mapping file — only touches what changed
- Privacy-preserving: only syncs time slots, never event titles, descriptions, or attendees
Setup
1. Install dependencies
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.
2. Configure credentials
Add to ~/.calintegration/.env (created by installer with chmod 600):
CALINT_ICS_URL=\x3Cyour-ics-feed-url>
CALINT_MS_CLIENT_ID=\x3Cazure-app-client-id>
CALINT_MS_TENANT_ID=\x3Cazure-app-tenant-id>
# Optional: sync to a specific Exchange calendar (defaults to primary)
# CALINT_MS_CALENDAR_ID=\x3Ccalendar-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):
- Go to https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade
- New registration > Name: "CalIn" > Redirect URI: Public client >
http://localhost:8400 - API permissions > Add > Microsoft Graph > Delegated > Calendars.ReadWrite
- Copy Application (client) ID and Directory (tenant) ID
3. Authenticate Microsoft
cd ~/.openclaw/skills/calin
venv/bin/python main.py setup
This opens a browser for one-time Microsoft login. Tokens are cached locally.
Commands
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 |
Automated Sync (macOS)
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
How It Works
- Fetches the ICS feed and expands all recurring events within a 14-day window
- Compares against the local event map (previous sync state)
- For each event:
- New: Creates a "Blocked" event on Exchange
- Changed (time moved): Updates the Exchange event
- Deleted from source: Deletes the Exchange event
- Saves updated event map and last sync timestamp
Change detection uses a hash of start time + end time + all-day flag. Only changed events trigger API calls.
Security and Privacy
- Credentials stored in
~/.calintegration/.envwith chmod 600 permissions - Tokens stored in
~/.calintegration/ms_token.jsonwith chmod 600 permissions - All files in
~/.calintegration/directory with chmod 700 - No event details synced — only time slots are transmitted. Event titles, descriptions, attendees, and locations are never sent to Exchange
- HTTPS only — ICS URLs must use HTTPS; Graph API calls use TLS with certificate verification
- No client secret — uses PKCE (Proof Key for Code Exchange) for Microsoft auth
- ICS URL validated — rejects non-HTTPS schemes to prevent SSRF
- API path IDs validated — prevents injection in Graph API endpoint construction
- All HTTP requests have 30-second timeouts to prevent hanging
External endpoints called
| 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 |
Data flow
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.
- 确保已安装 OpenClaw(本地或 Docker 部署)
- 在对话框中输入安装命令:
/install block-on-exchange - 安装完成后,直接呼叫该 Skill 的名称或使用
/block-on-exchange触发 - 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
ics to exchange-blocker 是什么?
Sync any ICS/iCal calendar to Microsoft Exchange as blocked time slots — supports recurring events, change detection, and privacy-preserving sync. 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 146 次。
如何安装 ics to exchange-blocker?
在 OpenClaw 或 Claude Code 对话框中运行命令「/install block-on-exchange」即可一键安装,无需额外配置。
ics to exchange-blocker 是免费的吗?
是的,ics to exchange-blocker 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。
ics to exchange-blocker 支持哪些平台?
ics to exchange-blocker 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(darwin)。
谁开发了 ics to exchange-blocker?
由 Blucaru(@blucaru)开发并维护,当前版本 v1.0.0。