Secretary 是一个基于 FastAPI 的个人日程助手。它通过 Telegram Bot 接收指令或 Excel 文件,解析课程、考试和学习任务,并写入 CalDAV/Radicale 日历。
- 通过 Telegram webhook 接收 Bot 消息。
/ielts根据指令发送时间自动规划当天的 IELTS/四级日常任务。/delay推迟当天 IELTS 日程,并支持通过按钮改为 10 分钟、30 分钟或 1 小时。/course登录教务系统,拉取课表 Excel,并按选择的周次写入课程日历。- 上传考试安排 Excel 后,解析考试信息,写入考试日历,并重新调整 IELTS 日程。
- 写入 CalDAV 日历事件,支持提醒和课程周重复规则。
.
├── main.py # FastAPI 入口,处理 Telegram webhook
├── fetcher/
│ ├── telegram.py # Telegram Bot API 调用与文件下载
│ └── course.py # 教务系统登录与课表 Excel 下载
├── parser/
│ ├── telegram.py # Telegram 命令和按钮回调解析
│ ├── course.py # 课表 Excel 解析
│ └── exam.py # 考试 Excel 解析
├── schedule/
│ ├── radicale.py # CalDAV 事件封装
│ ├── alloc.py # 空闲时间分配与日程调整
│ └── new.py # 默认学习日程生成
├── deploy/
│ ├── caldav.service # systemd 服务示例
│ └── schedules.sql # 当日日程表结构和初始数据
└── requirements.txt # Python 依赖
- Python 3.12 或更高版本。
- PostgreSQL 数据库。
- 可访问的 CalDAV/Radicale 服务。
- Telegram Bot token。
- 如果使用
/course,运行环境需要能访问教务系统http://jw.bjbuft.edu.cn。
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt在项目根目录创建 .env,或在运行环境中提供以下变量:
CALDAV_USERNAME=your-caldav-username
CALDAV_PASSWORD=your-caldav-password
CALDAV_URL=https://your-caldav-server
SECRETARY_BOT=your-telegram-bot-token
PGHOST=localhost
PGDATABASE=secretary
PGUSER=secretary
PGPASSWORD=your-db-password
TZ=Asia/ShanghaiCalDAV 中需要提前准备这些日历:
class:课程日历exam:考试日历IELTS:学习任务日历Normal:普通日程日历
课程抓取账号目前在 fetcher/course.py 的 BUFTFetcher.login() 默认参数中配置。如需更换账号,修改该方法的默认参数,或改造成从环境变量读取。
/ielts 会从 PostgreSQL 的 schedules 表读取当天需要安排的日程。首次部署时,先创建数据库用户和数据库:
sudo -u postgres psql -c "CREATE USER secretary WITH PASSWORD 'your-db-password';"
sudo -u postgres psql -c "CREATE DATABASE secretary OWNER secretary;"然后执行仓库中的 SQL 文件,创建数据表并导入默认日程:
PGHOST=localhost PGDATABASE=secretary PGUSER=secretary PGPASSWORD=your-db-password psql -f deploy/schedules.sql确认数据已经写入:
PGHOST=localhost PGDATABASE=secretary PGUSER=secretary PGPASSWORD=your-db-password psql -c "SELECT calendar_name, schedule_description, duration_minutes, weekdays, arrange_type FROM schedules ORDER BY id;"服务运行时通过 PGHOST、PGDATABASE、PGUSER、PGPASSWORD 使用 PostgreSQL 默认连接参数。
weekdays 使用 0=周一 到 6=周日,arrange_type 支持:
early:尽早安排。auto:按原自动排程逻辑安排。late:尽晚安排。
source venv/bin/activate
set -a
source .env
set +a
uvicorn main:app --host 0.0.0.0 --port 8443也可以直接运行:
python main.py服务入口:
POST /webhook
服务需要能被 Telegram 访问。部署到公网后,设置 webhook:
curl "https://api.telegram.org/bot$SECRETARY_BOT/setWebhook?url=https://your-domain.example/webhook"常用 Bot 命令:
/start:返回可用操作入口。/ielts:安排当天 IELTS/四级学习任务。/delay:推迟当前 IELTS 日程。/course:选择课表起始周并导入课程。- 直接发送考试 Excel 文件:解析并导入考试日历。
仓库提供了 deploy/caldav.service 示例,默认配置:
- 工作目录:
/home/admin/secretary - 环境文件:
/home/admin/secretary/.env - 启动命令:
/home/admin/secretary/venv/bin/uvicorn main:app --host 0.0.0.0 --port 8003
根据实际部署路径调整后安装:
sudo cp deploy/caldav.service /etc/systemd/system/secretary.service
sudo systemctl daemon-reload
sudo systemctl enable secretary
sudo systemctl start secretary
sudo systemctl status secretary- Telegram 将消息推送到
POST /webhook。 main.py判断消息类型:- 普通命令交给
parser/telegram.py处理。 - 上传文件时通过 Telegram Bot API 下载 Excel。
- 普通命令交给
- 课程或考试 Excel 由对应 parser 转换为
REvent。 schedule/radicale.py将事件写入 CalDAV。schedule/alloc.py根据课程和考试占用时间重新分配学习任务。
/ielts 用于安排当天的日常任务。服务会从 PostgreSQL 读取今天周几对应的日程,再根据指令发送时间,自动读取当天已有课程、考试等占用时间,在不发生冲突的前提下规划新任务。
自动规划会尊重任务自身的需求。例如部分任务会尽早安排,部分任务会尽晚安排;普通任务会优先选择更合适的空闲时间段,尽量保留一天中更大块的休闲时间,避免把时间切割得过于零碎。
/ielts日程配置保存在 PostgreSQL 中,已生成的日程仍写入 CalDAV 日历。- Excel 文件格式需要与现有 parser 预期一致。
- 事件会写入固定日历名称,日历不存在时 CalDAV 客户端可能报错。