# 预约与取消命令 **本文档引用的文件** - [src/command/index.ts](file://src/command/index.ts) - [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts) - [src/command/handlers/history.ts](file://src/command/handlers/history.ts) - [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts) - [src/command/handlers/events.ts](file://src/command/handlers/events.ts) - [src/command/handlers/eventDetails.ts](file://src/command/handlers/eventDetails.ts) - [src/command/handlers/login.ts](file://src/command/handlers/login.ts) - [src/command/handlers/logout.ts](file://src/command/handlers/logout.ts) - [src/command/handlers/start.ts](file://src/command/handlers/start.ts) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts) - [src/scheduler/index.ts](file://src/scheduler/index.ts) - [wrangler.jsonc](file://wrangler.jsonc) - [package.json](file://package.json) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考虑](#性能考虑) 8. [故障排除指南](#故障排除指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本文件面向“预约与取消命令”的完整业务流程,深入解析以下命令: - 预约流程:/bookEvent(活动选择、时间槽确认、优惠券应用、用户确认和最终预订) - 历史查询:/history(预约记录获取、状态筛选、分页展示和详情查看) - 取消流程:/cancel(预约确认、取消原因选择、退款处理和状态更新) 同时解释回调查询处理、按钮交互和实时状态更新机制,并提供预约冲突检测、容量管理与通知推送的扩展实现建议。 ## 项目结构 该机器人基于 GrammY 框架构建,采用模块化命令处理器与 Cloudflare Workers 运行环境。核心目录与职责如下: - src/command/index.ts:注册命令与回调查询,配置对话式会话存储(KV) - src/command/handlers/*:各命令处理器(事件列表、活动详情、预约、历史、取消、登录、登出等) - src/client/cosmoe.ts:封装对 Cosmoe API 的调用(认证、事件、预约、取消等) - src/scheduler/index.ts:定时任务(新活动通知推送) - wrangler.jsonc:Cloudflare Workers 配置(KV 绑定、计划任务) - package.json:依赖与脚本 ```mermaid graph TB subgraph "Telegram 机器人" CMD["命令入口
src/command/index.ts"] HANDLERS["命令处理器
src/command/handlers/*"] SCHED["定时任务
src/scheduler/index.ts"] end subgraph "客户端" CLIENT["Cosmoe 客户端
src/client/cosmoe.ts"] end subgraph "Cloudflare Workers" KV["KV 存储
COSMOE_CREDENTIALS/COSMOE_STORAGE"] TRIG["计划任务触发器
*/1 * * * *"] end CMD --> HANDLERS HANDLERS --> CLIENT SCHED --> CLIENT HANDLERS --> KV SCHED --> KV TRIG --> SCHED ``` 图表来源 - [src/command/index.ts](file://src/command/index.ts#L20-L110) - [src/scheduler/index.ts](file://src/scheduler/index.ts#L12-L88) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503) - [wrangler.jsonc](file://wrangler.jsonc#L21-L30) 章节来源 - [src/command/index.ts](file://src/command/index.ts#L1-L110) - [wrangler.jsonc](file://wrangler.jsonc#L1-L31) ## 核心组件 - 命令注册与会话存储:通过 KV 适配器实现对话状态持久化,支持登录对话、回调查询处理与命令路由。 - Cosmoe 客户端:统一封装认证、事件查询、预约、取消、历史查询等 API 调用。 - 定时任务:周期性检查新活动并推送通知给已登录用户。 章节来源 - [src/command/index.ts](file://src/command/index.ts#L20-L110) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503) - [src/scheduler/index.ts](file://src/scheduler/index.ts#L12-L88) ## 架构总览 下图展示了从用户输入到 API 调用与 KV 存储的整体流程。 ```mermaid sequenceDiagram participant U as "用户" participant B as "Telegram Bot" participant C as "命令处理器" participant K as "KV 存储" participant API as "Cosmoe API" U->>B : 发送命令/回调 B->>C : 路由到对应处理器 C->>K : 读取/写入用户凭证与会话 C->>API : 调用事件/预约/取消接口 API-->>C : 返回结果 C-->>U : 发送消息/内联键盘 ``` 图表来源 - [src/command/index.ts](file://src/command/index.ts#L20-L110) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503) ## 详细组件分析 ### 预约流程:/bookEvent - 输入格式:/book_{event_id}_{slot_index} - 关键步骤: 1) 解析命令参数,提取活动 ID 与时间槽索引 2) 从 KV 获取用户凭证并校验登录状态 3) 调用 Cosmoe API 获取活动详情与时间槽 4) 校验时间槽剩余容量 5) 查询可用优惠券,若多于一个则弹出内联键盘供用户选择 6) 用户确认后发起预约请求,返回最终价格、预约编号等信息 ```mermaid sequenceDiagram participant U as "用户" participant B as "Bot" participant H as "bookEvent 处理器" participant K as "KV 存储" participant API as "Cosmoe API" U->>B : /book_{event_id}_{slot_index} B->>H : 路由到处理函数 H->>K : 读取用户凭证 H->>API : 获取活动详情与时间槽 API-->>H : 返回活动数据 H->>H : 校验剩余容量 H->>API : 查询可用优惠券 API-->>H : 返回优惠券列表 alt 多个优惠券 H-->>U : 弹出内联键盘选择优惠券 U->>B : 回调选择优惠券 B->>H : 处理回调 else 单个或无优惠券 H->>H : 自动选择/不使用优惠券 end H->>API : 提交预约请求 API-->>H : 返回预约结果 H-->>U : 成功/失败消息 ``` 图表来源 - [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L11-L118) - [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L160-L226) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L191-L270) 章节来源 - [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L11-L118) - [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L160-L226) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L191-L270) ### 历史查询:/history - 功能要点: - 获取用户登录态,调用历史接口 - 对预约按时间倒序排序,限制展示数量 - 为可取消且未来时间的预约生成取消链接 - 支持 Markdown 格式输出,避免超长消息截断 ```mermaid flowchart TD Start(["进入 /history"]) --> GetUser["获取 Telegram 用户ID"] GetUser --> CheckCreds{"KV 中存在凭证?"} CheckCreds --> |否| PromptLogin["提示先登录"] CheckCreds --> |是| InitClient["初始化 Cosmoe 客户端"] InitClient --> FetchBookings["获取我的预约历史"] FetchBookings --> HasData{"有数据?"} HasData --> |否| EmptyMsg["提示历史为空"] HasData --> |是| SortLimit["按时间倒序并限制数量"] SortLimit --> BuildMsg["构建 Markdown 消息"] BuildMsg --> CancelLink{"满足可取消条件?"} CancelLink --> |是| AddLink["添加取消链接"] CancelLink --> |否| SkipLink["跳过"] AddLink --> SendMsg["发送消息"] SkipLink --> SendMsg PromptLogin --> End(["结束"]) EmptyMsg --> End SendMsg --> End ``` 图表来源 - [src/command/handlers/history.ts](file://src/command/handlers/history.ts#L4-L107) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L226-L239) 章节来源 - [src/command/handlers/history.ts](file://src/command/handlers/history.ts#L4-L107) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L226-L239) ### 取消流程:/cancel - 输入格式:/cancel_{booking_id} - 关键步骤: 1) 解析命令参数,获取预约 ID 2) 校验登录态并获取用户历史 3) 在历史中定位目标预约,构造确认内联键盘 4) 用户点击确认后,调用取消接口并更新消息 ```mermaid sequenceDiagram participant U as "用户" participant B as "Bot" participant H as "cancel 处理器" participant API as "Cosmoe API" U->>B : /cancel_{booking_id} B->>H : 路由到处理函数 H->>API : 获取我的预约历史 API-->>H : 返回历史列表 H->>H : 定位目标预约 H-->>U : 弹出确认内联键盘 U->>B : 点击“确认”或“取消” B->>H : 处理回调 alt 确认取消 H->>API : 调用取消接口 API-->>H : 返回结果 H-->>U : 更新为成功/失败消息 else 取消操作 H-->>U : 提示操作已取消 end ``` 图表来源 - [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L11-L84) - [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L87-L132) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L405-L422) 章节来源 - [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L11-L84) - [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L87-L132) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L405-L422) ### 回调查询与按钮交互 - 回调类型: - 取消确认:confirm_cancel_{booking_id} 或 cancel_action - 优惠券选择:select_coupon_{event_id}_{slot_index}_{coupon_code|none} - 处理逻辑: - 解析回调数据,校验用户登录态 - 读取活动详情与时间槽,更新消息内容 - 执行预约或取消操作并反馈结果 章节来源 - [src/command/index.ts](file://src/command/index.ts#L92-L105) - [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L160-L226) - [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L87-L132) ### 实时状态更新机制 - 当前实现: - 历史查询中根据当前北京时间判断是否可取消,但未实现自动刷新 - 定时任务用于推送新活动通知,未包含预约状态变更通知 - 建议扩展: - 在历史查询中增加“刷新”按钮,调用相同接口并重新渲染 - 在定时任务中加入“预约状态变更通知”,向用户推送取消/完成状态变化 章节来源 - [src/command/handlers/history.ts](file://src/command/handlers/history.ts#L68-L92) - [src/scheduler/index.ts](file://src/scheduler/index.ts#L24-L84) ## 依赖关系分析 - 命令入口依赖各处理器模块,处理器依赖 Cosmoe 客户端与 KV 存储 - 定时任务依赖 Cosmoe 客户端与 KV 存储,通过计划任务触发器运行 - Cloudflare Workers 配置定义 KV 绑定与计划任务 ```mermaid graph LR IDX["命令入口
src/command/index.ts"] --> H_BOOK["预约处理器
src/command/handlers/bookEvent.ts"] IDX --> H_CANCEL["取消处理器
src/command/handlers/cancel.ts"] IDX --> H_HISTORY["历史处理器
src/command/handlers/history.ts"] H_BOOK --> CLIENT["Cosmoe 客户端
src/client/cosmoe.ts"] H_CANCEL --> CLIENT H_HISTORY --> CLIENT SCHED["定时任务
src/scheduler/index.ts"] --> CLIENT SCHED --> KV["KV 存储"] IDX --> KV WRANGLER["Workers 配置
wrangler.jsonc"] --> KV ``` 图表来源 - [src/command/index.ts](file://src/command/index.ts#L20-L110) - [src/scheduler/index.ts](file://src/scheduler/index.ts#L12-L88) - [wrangler.jsonc](file://wrangler.jsonc#L21-L30) 章节来源 - [src/command/index.ts](file://src/command/index.ts#L20-L110) - [src/scheduler/index.ts](file://src/scheduler/index.ts#L12-L88) - [wrangler.jsonc](file://wrangler.jsonc#L21-L30) ## 性能考虑 - KV 读写:会话与凭证均通过 KV 存储,注意控制读写频率与错误重试 - API 调用:事件与历史接口可能返回大量数据,需在前端做分页与截断 - Markdown 渲染:消息长度超过限制时应截断,避免 Telegram API 报错 - 定时任务:每分钟触发一次,需确保任务执行时间短、异常处理完备 章节来源 - [src/command/index.ts](file://src/command/index.ts#L20-L110) - [src/command/handlers/history.ts](file://src/command/handlers/history.ts#L94-L102) - [src/scheduler/index.ts](file://src/scheduler/index.ts#L12-L88) ## 故障排除指南 - 认证失败 - 症状:提示需要登录或凭证无效 - 排查:确认 /login 是否成功写入 KV;检查凭证有效期 - 预约失败 - 症状:提示预约失败或无空位 - 排查:检查时间槽剩余容量;确认优惠券是否可用 - 取消失败 - 症状:取消请求返回失败 - 排查:确认预约状态是否允许取消;检查网络与 API 返回 - 消息超长 - 症状:历史消息被截断 - 排查:减少展示条数或分页展示 章节来源 - [src/command/handlers/login.ts](file://src/command/handlers/login.ts#L49-L69) - [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L60-L63) - [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L120-L124) - [src/command/handlers/history.ts](file://src/command/handlers/history.ts#L94-L102) ## 结论 本系统以清晰的模块化设计实现了完整的预约与取消流程,结合 KV 会话存储与回调交互,提供了良好的用户体验。建议后续增强实时状态更新与通知推送能力,进一步提升用户参与度与满意度。 ## 附录 ### 命令与回调一览 - 命令 - /start:欢迎与帮助 - /login:交互式登录 - /logout:登出并清除凭证 - /events:查看最新活动 - /event_{id}:查看活动详情与预约入口 - /book_{event_id}_{slot_index}:发起预约 - /history:查看预约历史 - /cancel_{booking_id}:发起取消 - 回调 - confirm_cancel_{booking_id}:确认取消 - cancel_action:取消取消 - select_coupon_{event_id}_{slot_index}_{coupon_code|none}:选择优惠券 章节来源 - [src/command/index.ts](file://src/command/index.ts#L59-L109) - [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L160-L226) - [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L87-L132) ### 扩展实现建议 - 预约冲突检测 - 在提交预约前,查询用户当前未完成的预约,避免重复占用同一时间槽 - 容量管理 - 在活动详情页显示更直观的剩余/容量比例,必要时提供“占位”或“候补”机制 - 通知推送 - 新增“预约状态变更通知”:完成、取消、过期等状态变化时主动推送 - 新活动通知:现有定时任务已实现,可扩展为按用户偏好定制推送 章节来源 - [src/scheduler/index.ts](file://src/scheduler/index.ts#L24-L84) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L247-L270)