8.3 KiB
name, description, metadata
| name | description | metadata | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| calendar-invite | Send, accept, and decline calendar invite emails (ICS/iCalendar) via himalaya. Syncs events to CalDAV (Migadu) via vdirsyncer. |
|
Calendar Invite
Send, accept, and decline calendar invitations via email using himalaya. Events are saved to local calendar and synced to CalDAV (Migadu) via vdirsyncer.
Prerequisites
himalayaconfigured and working (see thehimalayaskill)vdirsyncerconfigured and syncing to~/.openclaw/workspace/calendars/khalfor reading calendar (optional but recommended)- Runs via
uv run(dependencies managed inpyproject.toml)
Important: Email Sending Rules
Calendar invites are outbound emails. Follow the workspace email rules:
- youlu@luyanxin.com -> mail@luyx.org: send directly, no confirmation needed
- All other recipients: confirm with user before sending
Owner Auto-Attendee
When sending invites, mail@luyx.org (owner's SimpleLogin alias) is always added as an attendee automatically. This ensures the owner receives every invite and can Accept/Decline from their own email client. No need to include it in --to — it's added by the script.
When accepting or tentatively accepting a received invite, the original invite is automatically forwarded to mail@luyx.org so the event lands on the owner's calendar too.
Usage
All commands go through the wrapper script:
SKILL_DIR=~/.openclaw/workspace/skills/calendar-invite
# Send an invite
$SKILL_DIR/scripts/calendar-invite.sh send [options]
# Reply to an invite
$SKILL_DIR/scripts/calendar-invite.sh reply [options]
Sending Invites
$SKILL_DIR/scripts/calendar-invite.sh send \
--to "friend@example.com" \
--subject "Lunch on Friday" \
--summary "Lunch at Tartine" \
--start "2026-03-20T12:00:00" \
--end "2026-03-20T13:00:00" \
--location "Tartine Bakery, SF"
Send Options
| Flag | Required | Description |
|---|---|---|
--to |
Yes | Recipient(s), comma-separated |
--subject |
Yes | Email subject line |
--summary |
Yes | Event title (shown on calendar) |
--start |
Yes | Start time, ISO 8601 (2026-03-20T14:00:00) |
--end |
Yes | End time, ISO 8601 (2026-03-20T15:00:00) |
--from |
No | Sender email (default: youlu@luyanxin.com) |
--timezone |
No | IANA timezone (default: America/Los_Angeles) |
--location |
No | Event location |
--description |
No | Event description / notes |
--organizer |
No | Organizer display name (defaults to --from) |
--uid |
No | Custom event UID (auto-generated if omitted) |
--account |
No | Himalaya account name (if not default) |
--dry-run |
No | Print ICS + MML without sending |
Send Examples
# Simple invite (--from and --timezone default to youlu@luyanxin.com / LA)
$SKILL_DIR/scripts/calendar-invite.sh send \
--to "alice@example.com" \
--subject "Coffee Chat" \
--summary "Coffee Chat" \
--start "2026-03-25T10:00:00" \
--end "2026-03-25T10:30:00"
# Multiple attendees with details
$SKILL_DIR/scripts/calendar-invite.sh send \
--to "alice@example.com, bob@example.com" \
--subject "Team Sync" \
--summary "Weekly Team Sync" \
--start "2026-03-23T09:00:00" \
--end "2026-03-23T09:30:00" \
--location "Zoom - https://zoom.us/j/123456" \
--description "Weekly check-in. Agenda: updates, blockers, action items."
# Dry run
$SKILL_DIR/scripts/calendar-invite.sh send \
--to "test@example.com" \
--subject "Test" \
--summary "Test Event" \
--start "2026-04-01T15:00:00" \
--end "2026-04-01T16:00:00" \
--dry-run
Replying to Invites
# Accept by himalaya message ID
$SKILL_DIR/scripts/calendar-invite.sh reply \
--envelope-id 42 \
--action accept
# Decline with a comment
$SKILL_DIR/scripts/calendar-invite.sh reply \
--envelope-id 42 \
--action decline \
--comment "Sorry, I have a conflict."
# From an .ics file
$SKILL_DIR/scripts/calendar-invite.sh reply \
--ics-file ~/Downloads/meeting.ics \
--action tentative
Reply Options
| Flag | Required | Description |
|---|---|---|
--action |
Yes | accept, decline, or tentative |
--envelope-id |
* | Himalaya message ID containing the .ics attachment |
--ics-file |
* | Path to an .ics file (alternative to --envelope-id) |
--from |
No | Your email (default: youlu@luyanxin.com) |
--account |
No | Himalaya account name |
--folder |
No | Himalaya folder (default: INBOX) |
--comment |
No | Optional message to include in reply |
--dry-run |
No | Preview without sending |
* One of --envelope-id or --ics-file is required.
Typical Workflow
- List emails:
himalaya envelope list - Read the invite:
himalaya message read 57 - Reply:
$SKILL_DIR/scripts/calendar-invite.sh reply --envelope-id 57 --action accept
How It Works
Sending invites:
- Generates an RFC 5545 ICS file with
METHOD:REQUEST(viaicalendarlibrary) - Builds an MML email with a
text/calendarattachment - Sends via
himalaya template send - Saves the event to
~/.openclaw/workspace/calendars/home/ - Runs
vdirsyncer syncto push to Migadu CalDAV
Replying to invites:
- Extracts the
.icsattachment from the email (viahimalaya attachment download) - Parses the original event with the
icalendarlibrary - Generates a reply ICS with
METHOD:REPLYand the correctPARTSTAT - Sends the reply to the organizer via
himalaya template send - On accept/tentative: saves event to local calendar. On decline: removes it
- Runs
vdirsyncer syncto push changes to Migadu CalDAV
CalDAV sync:
- Events sync to Migadu and appear on all connected devices (DAVx5, etc.)
- Heartbeat runs
vdirsyncer syncperiodically as a fallback - If sync fails, it warns but doesn't block — next heartbeat catches up
Integration with Email Processor
The email processor (scripts/email_processor/) may classify incoming calendar invites as reminder or confirmation. When reviewing pending emails:
- Check if the email contains a calendar invite (look for
.icsattachment or "calendar" in subject) - If it does, use
replyinstead of the email processor's delete/archive/keep actions - The email processor handles the email lifecycle; this skill handles the calendar response
Checking the Calendar
# List upcoming events (next 7 days)
khal list today 7d
# List events for a specific date
khal list 2026-03-25
# Check for conflicts before sending an invite
khal list 2026-03-25 2026-03-26
Timezone Reference
Common IANA timezones:
America/Los_Angeles— Pacific (default)America/Denver— MountainAmerica/Chicago— CentralAmerica/New_York— EasternAsia/Shanghai— ChinaAsia/Tokyo— JapanEurope/London— UKUTC— Coordinated Universal Time
Troubleshooting
Invite shows as attachment instead of calendar event?
- Ensure
type=text/calendar method=REQUESTis set on the MML part - Some clients require the
METHOD:REQUESTline in the ICS body
Times are wrong?
- Double-check
--timezonematches the intended timezone - Use ISO 8601 format:
YYYY-MM-DDTHH:MM:SS(no timezone offset in the value)
Event not showing on phone/other devices?
- Run
vdirsyncer syncmanually to force sync - Check
~/.openclaw/workspace/logs/vdirsyncer.logfor errors - Verify the .ics file exists in
~/.openclaw/workspace/calendars/home/
Recipient doesn't see Accept/Decline?
- Gmail, Outlook, Apple Mail all support
text/calendarmethod=REQUEST - Some webmail clients may vary