popo-calendar
PopoCalendar
Create and update calendar events via the POPO Open API.
Customization
Before executing, check for user customizations at:
~/.claude/skills/PAI/USER/SKILLCUSTOMIZATIONS/PopoCalendar/
Load PREFERENCES.md for appId/appSecret, default corp account, and common participants.
Workflow Routing
| Workflow | Trigger | File |
|---|---|---|
| CreateEvent | "book meeting", "create event", "schedule", any calendar request | Workflows/CreateEvent.md |
| UpdateEvent | "update meeting", "change time", "modify event", "reschedule" | Workflows/UpdateEvent.md |
| DeleteEvent | "cancel meeting", "delete event", "cancel schedule" | Workflows/DeleteEvent.md |
API Quick Reference
Endpoint: POST https://open.popo.netease.com/open-apis/calendar/v1/create
Auth Header: Open-Access-Token: {token}
Required Fields
| Field | Type | Note |
|---|---|---|
| businessId | String | Unique ID (max 200 chars), generate with UUID |
| title | String | Event title (max 50 chars) |
| tagId | int | 1=Product, 2=Training, 3=Meeting, 4=Interview, 5=Todo, 6=Task, 7=Onboarding, 100=None |
| alldayFlag | boolean | Full-day event? |
| startDateTime | String | yyyy-MM-dd HH:mm:ss (non-allday) or yyyy-MM-dd (allday) |
| endDateTime | String | Same format. Min span 15min, max 5 days |
| participantList | Participant[] | Max 500, no duplicates |
| remindFlag | boolean | Enable reminder? |
| cycleFlag | boolean | Recurring event? |
| meetingFlag | boolean | Enable video meeting? |
Participant Object
{
"uid": "name@corp.netease.com",
"role": 0, // 0=participant, 1=organizer, 2=presenter
"outsider": false,
"editAuth": false,
"teamAuth": false,
"inviteAuth": true,
"detailAuth": true
}
Remind Object
{ "count": 15, "unit": "MIN" }
// unit: MIN, HOUR, DAY, WEEK
Defaults (applied by tool)
- timezone:
Asia/Shanghai - tagId:
3(Meeting) - remindFlag:
true, remindList:[{count:15, unit:"MIN"}] - meetingFlag:
true - notifyFlag:
true - cycleFlag:
false - Organizer gets full permissions, participants get invite+detail auth
Tools (Python 3)
Token Management
Tools/GetToken.py — Auto-fetches and caches Open-Access-Token (24h validity, 30min pre-expiry refresh).
Token cached at ~/.cache/popo/token.json (chmod 600).
python3 ~/.claude/skills/PopoCalendar/Tools/GetToken.py # Print valid token
python3 ~/.claude/skills/PopoCalendar/Tools/GetToken.py --force # Force refresh
Create Event
Tools/CreateEvent.py — Auto-acquires token, builds payload, calls API.
# Simple mode
echo '{"title":"Weekly Sync","start":"2026-02-25 14:00:00","end":"2026-02-25 15:00:00","participants":["a@corp.netease.com"]}' | python3 ~/.claude/skills/PopoCalendar/Tools/CreateEvent.py
# Dry run (print payload without sending)
echo '{"title":"Test","start":"...","end":"...","participants":["a@corp"]}' | python3 ~/.claude/skills/PopoCalendar/Tools/CreateEvent.py --dry-run
Update Event
Tools/UpdateEvent.py — Updates existing event (PUT, full payload). Auto-fills unchanged fields from event history.
# By businessId
echo '{"businessId":"abc123","title":"New Title","start":"2026-02-26 14:00:00","end":"2026-02-26 15:00:00"}' | python3 ~/.claude/skills/PopoCalendar/Tools/UpdateEvent.py
# By title lookup (searches local event history)
echo '{"lookup":"团队会议","start":"2026-02-26 10:00:00","end":"2026-02-26 11:00:00"}' | python3 ~/.claude/skills/PopoCalendar/Tools/UpdateEvent.py
# Dry run
echo '{"businessId":"abc123","title":"...","start":"...","end":"..."}' | python3 ~/.claude/skills/PopoCalendar/Tools/UpdateEvent.py --dry-run
Event History
Created events are saved to ~/.cache/popo/event_history.json (last 200 events).
Used by UpdateEvent and DeleteEvent to resolve title lookups. Deleted events are auto-removed from history.
Delete Event
Tools/DeleteEvent.py — Cancels an event (DELETE). businessId cannot be reused after deletion.
echo '{"businessId":"abc123"}' | python3 ~/.claude/skills/PopoCalendar/Tools/DeleteEvent.py
echo '{"lookup":"团队会议"}' | python3 ~/.claude/skills/PopoCalendar/Tools/DeleteEvent.py