calendar-invite: add VALARM reminder, fix terminology, remove dead code

- Add 1-day reminder (VALARM) to all sent invites
- Fix datetime.utcnow() deprecation → datetime.now(timezone.utc)
- Rename "message ID" → "envelope ID" in SKILL.md for consistency
- Remove unused _himalaya() and _himalaya_with_account() helpers
This commit is contained in:
Yanxin Lu
2026-03-18 14:44:08 -07:00
parent 765825a8d1
commit b8ba4adec5
2 changed files with 14 additions and 25 deletions

View File

@@ -27,7 +27,7 @@ Calendar invites are outbound emails. Follow the workspace email rules:
## 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 sending invites, `mail@luyx.org` (owner's SimpleLogin alias) is **always added as an attendee automatically**. All invites include a **1-day reminder** (VALARM) by default. 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.
@@ -113,7 +113,7 @@ $SKILL_DIR/scripts/calendar-invite.sh send \
## Replying to Invites
```bash
# Accept by himalaya message ID
# Accept by himalaya envelope ID
$SKILL_DIR/scripts/calendar-invite.sh reply \
--envelope-id 42 \
--action accept
@@ -135,7 +135,7 @@ $SKILL_DIR/scripts/calendar-invite.sh reply \
| Flag | Required | Description |
|-----------------|----------|-----------------------------------------------------|
| `--action` | Yes | `accept`, `decline`, or `tentative` |
| `--envelope-id` | * | Himalaya message ID containing the .ics attachment |
| `--envelope-id` | * | Himalaya envelope 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 |

View File

@@ -14,14 +14,14 @@ import argparse
import subprocess
import sys
import uuid
from datetime import datetime
from datetime import datetime, timedelta, timezone
from pathlib import Path
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from icalendar import Calendar, Event, vCalAddress, vText
from icalendar import Alarm, Calendar, Event, vCalAddress, vText
# ---------------------------------------------------------------------------
# Config
@@ -38,24 +38,6 @@ PRODID = "-//OpenClaw//CalendarInvite//EN"
# Helpers
# ---------------------------------------------------------------------------
def _himalaya(*args):
"""Run a himalaya command and return stdout."""
result = subprocess.run(
["himalaya", *args],
capture_output=True, text=True, check=True,
)
return result.stdout
def _himalaya_with_account(account, *args):
"""Run a himalaya command with optional account flag."""
cmd = ["himalaya"]
if account:
cmd += ["--account", account]
cmd += list(args)
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
return result.stdout
def _sync_calendar():
"""Sync local calendar to CalDAV server via vdirsyncer."""
@@ -123,7 +105,7 @@ def cmd_send(args):
event = Event()
event.add("uid", uid)
event.add("dtstamp", datetime.utcnow())
event.add("dtstamp", datetime.now(timezone.utc))
event.add("dtstart", start, parameters={"TZID": args.timezone})
event.add("dtend", end, parameters={"TZID": args.timezone})
event.add("summary", args.summary)
@@ -151,6 +133,13 @@ def cmd_send(args):
"RSVP": "TRUE",
})
# 1-day reminder
alarm = Alarm()
alarm.add("action", "DISPLAY")
alarm.add("description", f"Reminder: {args.summary}")
alarm.add("trigger", timedelta(days=-1))
event.add_component(alarm)
cal.add_component(event)
ics_bytes = cal.to_ical()
@@ -286,7 +275,7 @@ def cmd_reply(args):
reply_event = Event()
reply_event.add("uid", uid)
reply_event.add("dtstamp", datetime.utcnow())
reply_event.add("dtstamp", datetime.now(timezone.utc))
# Copy timing from original
if original_event.get("dtstart"):