预约命令.md 18 KB

预约命令

本文引用的文件

  • src/command/index.ts
  • src/command/handlers/bookEvent.ts
  • src/command/handlers/cancel.ts
  • src/command/handlers/events.ts
  • src/command/handlers/eventDetails.ts
  • src/command/handlers/history.ts
  • src/command/handlers/login.ts
  • src/command/handlers/logout.ts
  • src/command/handlers/start.ts
  • src/client/cosmoe.ts
  • package.json

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考虑
  8. 故障排查指南
  9. 结论
  10. 附录

简介

本文件面向“预约命令”的实现与使用,围绕以下命令展开:

  • 预约创建:/book_{eventid}{slot_id}
  • 预约取消:/cancel_{booking_id}
  • 活动浏览:/events、/event_{id}
  • 历史查询:/history
  • 登录/登出:/login、/logout、/start

文档将深入解释命令解析、用户认证、活动与时间槽选择、优惠券应用、取消确认流程、状态管理与并发控制策略,并提供错误处理与数据一致性保障方案,以及扩展开发指导。

项目结构

该机器人采用模块化命令分发与客户端封装:

  • 命令入口与路由:在命令入口中注册所有命令与回调查询,绑定环境变量(KV 存储)。
  • 命令处理器:每个命令对应一个处理器文件,负责解析输入、调用客户端 API、构建交互式键盘与消息。
  • 客户端封装:统一的 CosmoeClient 封装 API 请求、认证状态与数据模型。

    graph TB
    subgraph "命令层"
    CMD_INDEX["命令入口<br/>src/command/index.ts"]
    H_BOOK["预约处理器<br/>src/command/handlers/bookEvent.ts"]
    H_CANCEL["取消处理器<br/>src/command/handlers/cancel.ts"]
    H_EVENTS["活动列表处理器<br/>src/command/handlers/events.ts"]
    H_EVENTD["活动详情处理器<br/>src/command/handlers/eventDetails.ts"]
    H_HISTORY["历史处理器<br/>src/command/handlers/history.ts"]
    H_LOGIN["登录处理器<br/>src/command/handlers/login.ts"]
    H_LOGOUT["登出处理器<br/>src/command/handlers/logout.ts"]
    H_START["开始处理器<br/>src/command/handlers/start.ts"]
    end
    subgraph "客户端层"
    C_CLIENT["CosmoeClient<br/>src/client/cosmoe.ts"]
    end
    CMD_INDEX --> H_BOOK
    CMD_INDEX --> H_CANCEL
    CMD_INDEX --> H_EVENTS
    CMD_INDEX --> H_EVENTD
    CMD_INDEX --> H_HISTORY
    CMD_INDEX --> H_LOGIN
    CMD_INDEX --> H_LOGOUT
    CMD_INDEX --> H_START
    H_BOOK --> C_CLIENT
    H_CANCEL --> C_CLIENT
    H_EVENTS --> C_CLIENT
    H_EVENTD --> C_CLIENT
    H_HISTORY --> C_CLIENT
    H_LOGIN --> C_CLIENT
    H_LOGOUT --> C_CLIENT
    H_START --> C_CLIENT
    

图表来源

  • src/command/index.ts
  • src/command/handlers/bookEvent.ts
  • src/command/handlers/cancel.ts
  • src/command/handlers/events.ts
  • src/command/handlers/eventDetails.ts
  • src/command/handlers/history.ts
  • src/command/handlers/login.ts
  • src/command/handlers/logout.ts
  • src/command/handlers/start.ts
  • src/client/cosmoe.ts

章节来源

  • src/command/index.ts

核心组件

  • 命令入口与路由:集中注册命令与回调查询,绑定 KV 存储用于会话与凭证持久化。
  • 预约处理器:解析 /book_{eventid}{slot_id},校验用户登录状态,拉取活动详情与时间槽,支持优惠券选择与自动下单。
  • 取消处理器:解析 /cancel_{booking_id},展示确认键盘,二次确认后调用取消接口。
  • 客户端封装:统一的 CosmoeClient 提供认证、事件查询、预约、取消等能力,并维护认证状态。
  • 会话与存储:通过 KV 适配器为会话与对话状态提供持久化。

章节来源

  • src/command/index.ts
  • src/command/handlers/bookEvent.ts
  • src/command/handlers/cancel.ts
  • src/client/cosmoe.ts

架构总览

命令到 API 的整体调用链如下:

sequenceDiagram
participant U as "用户"
participant B as "命令入口<br/>src/command/index.ts"
participant HB as "预约处理器<br/>src/command/handlers/bookEvent.ts"
participant HC as "取消处理器<br/>src/command/handlers/cancel.ts"
participant CC as "CosmoeClient<br/>src/client/cosmoe.ts"
participant KV as "KV 存储"
U->>B : 发送命令 /book_{event_id}_{slot_id}
B->>HB : 路由到预约处理器
HB->>KV : 读取用户凭证
KV-->>HB : 返回凭证
HB->>CC : 获取活动详情与时间槽
CC-->>HB : 返回活动数据
HB->>U : 展示优惠券选择键盘如适用
U->>B : 回调选择优惠券
B->>HB : 调用优惠券选择处理器
HB->>CC : 下单含可选优惠券
CC-->>HB : 返回下单结果
HB-->>U : 成功/失败消息
U->>B : 发送命令 /cancel_{booking_id}
B->>HC : 路由到取消处理器
HC->>CC : 查询我的预约
CC-->>HC : 返回预约列表
HC->>U : 展示取消确认键盘
U->>B : 回调确认取消
B->>HC : 调用取消确认处理器
HC->>CC : 执行取消
CC-->>HC : 返回取消结果
HC-->>U : 成功/失败消息

图表来源

  • src/command/index.ts
  • src/command/handlers/bookEvent.ts
  • src/command/handlers/cancel.ts
  • src/client/cosmoe.ts

详细组件分析

预约命令 /book_{eventid}{slot_id}

  • 命令解析:使用正则匹配 /book_{eventid}{slot_index},提取活动 ID 与时间槽索引。
  • 认证检查:从 KV 中读取用户凭证,若无则提示先登录。
  • 活动与时间槽:调用客户端获取活动详情,按 range 排序,校验索引有效性与剩余容量。
  • 优惠券应用:
    • 若存在多个可用优惠券,生成内联键盘让用户选择;支持“不使用优惠券”选项。
    • 若仅有一个优惠券,自动应用;若无优惠券,则直接下单。
  • 下单流程:构造下单请求(event_id、time_slot、可选 coupon_code),调用客户端下单接口,返回最终价格、预约编号等信息并反馈给用户。

    flowchart TD
    Start(["进入 /book_{event_id}_{slot_id}"]) --> Parse["解析命令参数<br/>提取 event_id, slot_index"]
    Parse --> CheckAuth["从 KV 读取用户凭证"]
    CheckAuth --> HasAuth{"有凭证?"}
    HasAuth --> |否| PromptLogin["提示先登录"] --> End
    HasAuth --> |是| FetchEvent["获取活动详情与时间槽"]
    FetchEvent --> ValidateIndex{"索引有效且有余量?"}
    ValidateIndex --> |否| ShowError["提示错误并结束"] --> End
    ValidateIndex --> |是| CheckCoupons{"是否有可用优惠券?"}
    CheckCoupons --> |多张| ShowKeyboard["展示优惠券选择键盘"] --> End
    CheckCoupons --> |一张| AutoApply["自动应用唯一优惠券"]
    CheckCoupons --> |无| NoCoupon["不使用优惠券"]
    AutoApply --> PlaceOrder["调用下单接口"]
    NoCoupon --> PlaceOrder
    PlaceOrder --> OrderOK{"下单成功?"}
    OrderOK --> |是| ReplySuccess["回复成功消息含最终价格/编号/优惠码"] --> End
    OrderOK --> |否| ReplyFail["回复失败消息"] --> End
    

图表来源

  • src/command/handlers/bookEvent.ts
  • src/client/cosmoe.ts

章节来源

  • src/command/handlers/bookEvent.ts
  • src/client/cosmoe.ts

取消命令 /cancel_{booking_id}

  • 命令解析:使用正则匹配 /cancel_{booking_id},提取预约 ID。
  • 认证检查:从 KV 读取凭证,确保已登录。
  • 预约确认:调用客户端获取我的预约,查找目标预约,不存在则提示。
  • 确认流程:生成“确认/取消”内联键盘,展示预约详情与风险提示。
  • 取消执行:用户确认后调用取消接口,返回结果并更新消息。

    sequenceDiagram
    participant U as "用户"
    participant B as "命令入口"
    participant HC as "取消处理器"
    participant CC as "CosmoeClient"
    participant KV as "KV 存储"
    U->>B : 发送 /cancel_{booking_id}
    B->>HC : 路由到取消处理器
    HC->>KV : 读取用户凭证
    KV-->>HC : 返回凭证
    HC->>CC : 获取我的预约
    CC-->>HC : 返回预约列表
    HC->>U : 展示确认键盘
    U->>B : 回调 confirm_cancel 或 cancel_action
    alt 确认取消
    B->>HC : 调用取消确认处理器
    HC->>CC : 执行取消
    CC-->>HC : 返回取消结果
    HC-->>U : 更新为成功/失败消息
    else 取消
    HC-->>U : 更新为已取消
    end
    

图表来源

  • src/command/handlers/cancel.ts
  • src/command/handlers/cancel.ts
  • src/client/cosmoe.ts
  • src/client/cosmoe.ts

章节来源

  • src/command/handlers/cancel.ts
  • src/command/handlers/cancel.ts
  • src/client/cosmoe.ts
  • src/client/cosmoe.ts

活动与时间槽展示

  • /events:列出最近的摄影活动,每个活动附带跳转到详情页的命令链接。
  • /event{id}:获取活动详情,排序时间槽并显示剩余/容量;对可预约且当天或之前的时间槽,提供对应的 /book{eventid}{slot_index} 链接。

章节来源

  • src/command/handlers/events.ts
  • src/command/handlers/eventDetails.ts

历史与登录/登出

  • /history:获取用户预约历史,按时间倒序取最新若干条,对可取消的预约显示 /cancel_{booking_id} 链接。
  • /login:交互式登录,向 Cosmoe API 获取 token 并存入 KV。
  • /logout:删除 KV 中的用户凭证。
  • /start:欢迎信息与可用命令提示。

章节来源

  • src/command/handlers/history.ts
  • src/command/handlers/login.ts
  • src/command/handlers/logout.ts
  • src/command/handlers/start.ts

依赖关系分析

  • 命令入口依赖各处理器与 KV 存储,负责命令与回调查询的路由。
  • 处理器依赖 CosmoeClient 进行 API 调用,并依赖 KV 存储进行凭证与会话持久化。
  • 客户端封装统一的 API 行为,包括认证状态检查与错误处理。

    graph LR
    CMD_INDEX["src/command/index.ts"] --> H_BOOK["src/command/handlers/bookEvent.ts"]
    CMD_INDEX --> H_CANCEL["src/command/handlers/cancel.ts"]
    CMD_INDEX --> H_EVENTS["src/command/handlers/events.ts"]
    CMD_INDEX --> H_EVENTD["src/command/handlers/eventDetails.ts"]
    CMD_INDEX --> H_HISTORY["src/command/handlers/history.ts"]
    CMD_INDEX --> H_LOGIN["src/command/handlers/login.ts"]
    CMD_INDEX --> H_LOGOUT["src/command/handlers/logout.ts"]
    CMD_INDEX --> H_START["src/command/handlers/start.ts"]
    H_BOOK --> C_CLIENT["src/client/cosmoe.ts"]
    H_CANCEL --> C_CLIENT
    H_EVENTS --> C_CLIENT
    H_EVENTD --> C_CLIENT
    H_HISTORY --> C_CLIENT
    H_LOGIN --> C_CLIENT
    H_LOGOUT --> C_CLIENT
    H_START --> C_CLIENT
    

图表来源

  • src/command/index.ts
  • src/command/handlers/bookEvent.ts
  • src/command/handlers/cancel.ts
  • src/command/handlers/events.ts
  • src/command/handlers/eventDetails.ts
  • src/command/handlers/history.ts
  • src/command/handlers/login.ts
  • src/command/handlers/logout.ts
  • src/command/handlers/start.ts
  • src/client/cosmoe.ts

章节来源

  • src/command/index.ts
  • src/client/cosmoe.ts

性能考虑

  • API 调用频率:活动列表、详情、预约历史、下单与取消均涉及网络请求,建议在处理器中避免重复请求,必要时缓存短期结果。
  • 消息长度限制:历史消息可能较长,已做截断处理,避免超出 Telegram API 限制。
  • KV 存储:凭证与会话存储在 KV 中,注意键空间命名与过期策略,避免无限增长。
  • 时间计算:活动日与当前时间比较使用北京时间偏移,确保本地化正确性。

章节来源

  • src/command/handlers/history.ts
  • src/command/handlers/eventDetails.ts

故障排查指南

  • 命令未响应
    • 检查命令是否被正确注册与路由(命令入口)。
    • 确认回调查询正则匹配是否正确。
  • 无法登录
    • 确认 /login 是否成功写入 KV,检查凭证格式与有效期。
  • 预约失败
    • 检查时间槽剩余容量与索引合法性。
    • 确认优惠券是否仍有效且适用于该活动。
  • 取消失败
    • 确认预约是否存在且状态允许取消。
    • 检查回调数据格式与解析逻辑。
  • 错误处理策略
    • 所有处理器均包含 try/catch,出现异常时回复通用错误消息并记录日志。
    • 客户端方法在未认证时抛出错误,需在调用前确保已设置凭证。

章节来源

  • src/command/index.ts
  • src/command/handlers/bookEvent.ts
  • src/command/handlers/cancel.ts
  • src/client/cosmoe.ts

结论

该预约系统通过清晰的命令分发与处理器职责划分,结合 KV 存储与客户端封装,实现了从活动浏览、时间槽选择、优惠券应用到预约与取消的完整闭环。系统具备良好的可扩展性与错误处理能力,适合在此基础上进一步增强并发控制、状态机与审计日志。

附录

命令一览与行为

  • /start:欢迎信息与可用命令提示。
  • /events:列出最近活动,附带 /event_{id} 链接。
  • /event{id}:展示活动详情与时间槽,提供 /book{eventid}{slot_index} 链接。
  • /book_{eventid}{slot_index}:预约创建,支持优惠券选择与自动下单。
  • /history:展示预约历史,对可取消项提供 /cancel_{booking_id} 链接。
  • /cancel_{booking_id}:取消预约,二次确认后执行。
  • /login:交互式登录,保存凭证至 KV。
  • /logout:删除 KV 中的用户凭证。

章节来源

  • src/command/handlers/start.ts
  • src/command/handlers/events.ts
  • src/command/handlers/eventDetails.ts
  • src/command/handlers/bookEvent.ts
  • src/command/handlers/history.ts
  • src/command/handlers/cancel.ts
  • src/command/handlers/login.ts
  • src/command/handlers/logout.ts

数据模型与 API 关键点

  • CosmoeClient 提供认证、事件、预约、取消等方法,内部维护 userId 与 token。
  • 预约请求包含 event_id、time_slot、可选 coupon_code。
  • 预约响应包含最终价格、预约编号等字段,便于回执展示。

章节来源

  • src/client/cosmoe.ts

并发控制与状态管理

  • 当前实现未显式引入分布式锁或队列,建议在关键路径(如下单)增加幂等键与重试策略,避免重复提交。
  • 使用 KV 存储会话与凭证,注意键冲突与并发读写的一致性问题。
  • 对于高并发场景,可在客户端层引入重试与退避策略,并在处理器中对同一用户的连续请求进行限流。

章节来源

  • src/command/index.ts
  • src/client/cosmoe.ts

扩展开发指导

  • 新增命令:在命令入口注册新命令与回调查询,编写处理器文件并在入口中导入。
  • 新增 API:在 CosmoeClient 中新增方法,遵循现有认证与错误处理模式。
  • 优化体验:引入会话状态机管理多步流程,减少 KV 读写次数;对长消息进行分片发送。
  • 安全加固:对命令输入进行更严格的校验与白名单过滤;对敏感操作增加二次确认与审计日志。

章节来源

  • src/command/index.ts
  • src/client/cosmoe.ts
  • package.json