name: mail-to-calendar-12306 description: Parse forwarded Chinese railway (12306) ticket/payment emails, query official train schedule APIs for accurate arrival time, and create calendar events in writable calendars. Use when converting train-related emails into reliable itinerary events. license: MIT compatibility: Requires Python 3.9+ and network access to 12306 endpoints. metadata: author: OpenClaw version: "1.0"
Mail to Calendar (12306)
把“火车购票邮件”稳定转成“可用日历事件”的技能。
适用场景
- 收到转发的 12306 支付/购票通知邮件
- 邮件正文缺失到达时间或信息不完整
- 需要通过 12306 接口反查准确到站时间后写入日历
输入
- 邮件正文(或原始邮件)
- 可选:目标日历名称(默认选可写日历)
输出
- 一条日历事件(含:车次、起终点、发到时间、座位号)
- 可选:过程日志(用于审计)
标准流程
拉取邮件(IMAP)
- 仅抓取目标邮件(按主题关键词或最新转发)
- 提取正文文本(plain/html 统一清洗)
解析关键信息
- 车次(如
G7205) - 出发日期(如
2026-03-02) - 起终站(如
苏州→苏州园区) - 座位号(如
3车6D)
- 车次(如
查询 12306 检索接口
https://search.12306.cn/search/v1/h5/search?keyword=<车次>- 从返回中提取
train_no
查询列车经停接口
https://kyfw.12306.cn/otn/queryTrainInfo/query?leftTicketDTO.train_no=<train_no>&leftTicketDTO.train_date=<日期>&rand_code=- 在站点列表中定位目标到达站,读取
arrive_time
写入日历(只写可写日历)
- 标题建议:
火车:<车次> <起点>→<终点> - 地点建议:座位号(例如
3车6D号) - 描述可放:订单号、票价、检票口等
- 标题建议:
同步与校验
- 同步后复查:时间是否为“时段事件”(不是全天)
- 若出现重复或脏事件,清理后重同步
本次实战复盘(已脱敏)
- 成功从转发邮件解析到车次与行程日期
- 通过 12306 接口反查得到精确到达时间并写入日历
- 发现并修复两个常见坑:
- 只读日历写入会触发
409 Conflict - 某些
khal new用法可能误生成“全天样式”事件
- 只读日历写入会触发
- 最终结果:保留唯一正确时段事件,标题规范化为“火车…”,座位号放到地点字段
经验规则
- 永远先判断日历是否可写
- 车次到达时间优先以 12306 接口为准,不依赖邮件模板完整性
- 发现异常事件时,优先“删除脏事件 → 重建标准事件 → 再同步”
参考实现
scripts/train_arrival_12306.py:车次到达时间查询references/workflow.md:完整流程与错误处理策略