后端-飞书API-workday重复创建日程
问题现象
每次运行 workday --sync --overwrite,飞书日历上的日程数量持续增加,而非保持与本地一致。定时事件(19:00-21:00)尤其严重,单次同步可产生 7+ 重复。全量查询显示 24+ 条但本地只有 18 条。
核心问题
三个独立的 Bug 层层叠加:
1. Calendar ID 字面量错误(全天日程全部未创建)
build_event_cmd 中创建全天日程时使用字面量 "primary" 作为 calendar_id:
params = json.dumps({"calendar_id": "primary"}) # ← 错误
events.create API 需要真实的 calendar ID(如 feishu.cn_xxx@group.calendar.feishu.cn)。删除操作使用 get_primary_calendar_id() 获取真实 ID 正常执行,但创建操作用 "primary" 无效 → 每次 sync 清空旧日程但不创建新日程 → 手动重新创建后累积重复。
2. query_events_for_date 只过滤 start.date,遗漏定时日程
search_event 返回的定时事件使用 start.date_time(2026-07-18T19:00:00+08:00)而非 start.date。代码只检查 start.date:
start_d = meta.get("start", {}).get("date", "") # ← 定时日程此字段为空
3. search_event 响应结构解析偏移
events.search_event 的 event_id 不在 item 顶层,而在 item.meta_data.event_id 内。代码从 item.get("event_id") 取值得到 None:
eid = item.get("event_id", "") # ← 应为 meta.get("event_id")
解决方法
-
修复 Calendar ID:
build_event_cmd中统一调用get_primary_calendar_id()获取真实日历 ID:cal_id = get_primary_calendar_id() params = json.dumps({"calendar_id": cal_id}) -
修复定时日期提取:
query_events_for_date同时检查start.date和start.date_time:start_d = start.get("date") or (start.get("date_time", "")[:10]) or "" -
修复 event_id 提取路径:从
meta_data内获取:eid = meta.get("event_id", "") -
用
search_event替代+agenda:改用events.search_event --page-all确保全量查询,避免分页遗漏:[lark, "calendar", "events", "search_event", "--as", "user", "--params", params, "--data", body, "--page-all"], -
执行全量覆盖同步:修复后运行
python .codebuddy/skills/workday/scripts/workday.py --sync,清除全部 34 条旧数据,重新创建 18 条新日程。
下次防错措施
- 定时日程验证:验证脚本需同时覆盖
start.date和start.date_time两种格式 - API 响应结构检查:调用任何新飞书 API 前,先执行
raw_api --format json检查返回结构,确认字段路径 - 重复检测:运行
python .codebuddy/skills/workday/scripts/workday.py --sync后立即检查飞书日历总数是否等于本地扫描条数 - 测试覆盖:单元测试中增加
test_filters_other_date(定时+全天混合场景)和test_search_event_parse(meta_data 结构解析)