# API 客户端集成 **本文档引用的文件** - [src/client/cosmoe.ts](file://src/client/cosmoe.ts) - [src/command/index.ts](file://src/command/index.ts) - [src/index.ts](file://src/index.ts) - [src/command/handlers/login.ts](file://src/command/handlers/login.ts) - [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts) - [src/command/handlers/history.ts](file://src/command/handlers/history.ts) - [src/scheduler/index.ts](file://src/scheduler/index.ts) - [wrangler.jsonc](file://wrangler.jsonc) - [package.json](file://package.json) - [test/index.spec.ts](file://test/index.spec.ts) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考量](#性能考量) 8. [故障排除指南](#故障排除指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本指南面向需要在 Cosmoe Bot 中集成与扩展 API 客户端的开发者,系统讲解如何封装新的 API 端点调用(请求构建、响应处理、错误管理)、认证机制(token 管理、权限验证、安全考虑)、设计模式(可维护性与可测试性)、异步操作与超时控制、重试机制、数据模型定义与验证,以及实际扩展示例(新增服务端功能或第三方 API 集成)。 ## 项目结构 该项目基于 Cloudflare Workers 与 GrammY 框架,采用分层组织: - 客户端层:封装对 Cosmoe 服务端 API 的调用,统一请求参数、响应格式与错误处理 - 命令层:通过 Telegram Bot 命令与交互式会话触发业务流程 - 调度层:定时任务轮询新活动并向已注册用户推送通知 - 配置层:Wrangler 配置 KV 命名空间用于凭证与状态存储 ```mermaid graph TB subgraph "客户端层" C1["CosmoeClient
封装 API 调用"] end subgraph "命令层" CMD["命令路由与会话"] H1["登录处理器"] H2["预约处理器"] H3["历史处理器"] end subgraph "调度层" SCH["定时任务处理器"] end subgraph "配置层" W["Wrangler 配置
KV 命名空间"] end CMD --> C1 H1 --> C1 H2 --> C1 H3 --> C1 SCH --> C1 C1 --> W ``` 图表来源 - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503) - [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/index.ts](file://src/index.ts#L1-L47) - [src/command/index.ts](file://src/command/index.ts#L1-L110) - [src/scheduler/index.ts](file://src/scheduler/index.ts#L1-L88) - [wrangler.jsonc](file://wrangler.jsonc#L1-L31) ## 核心组件 - CosmoeClient:统一的 API 客户端,负责认证、事件查询、用户资料、预约、支付订单更新、取消与转约等操作 - 命令路由与处理器:将 Telegram 命令映射到具体业务逻辑,并通过 CosmoeClient 执行 - 定时任务:周期性拉取新活动并推送通知 - KV 存储:凭证与状态持久化(COSMOE_CREDENTIALS、COSMOE_STORAGE) 章节来源 - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503) - [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) ## 架构总览 下图展示了从 Telegram 命令到 API 调用再到 KV 存储的整体流程。 ```mermaid sequenceDiagram participant U as "用户" participant B as "Bot 命令路由" participant H as "命令处理器" participant C as "CosmoeClient" participant S as "Cosmoe 服务端" participant K as "KV 存储" U->>B : 发送命令/回调 B->>H : 分发到对应处理器 H->>K : 读取用户凭证 alt 凭证存在 H->>C : 初始化并设置凭证 H->>C : 调用 API 方法 C->>S : 发起 HTTP 请求 S-->>C : 返回 JSON 响应 C-->>H : 解析并返回结果 H-->>U : 发送回复 else 凭证不存在 H-->>U : 提示先登录 end ``` 图表来源 - [src/command/index.ts](file://src/command/index.ts#L59-L109) - [src/command/handlers/login.ts](file://src/command/handlers/login.ts#L43-L69) - [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L37-L117) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503) - [wrangler.jsonc](file://wrangler.jsonc#L21-L30) ## 详细组件分析 ### CosmoeClient 组件分析 CosmoeClient 是整个系统的 API 封装核心,提供以下能力: - 认证:获取 token 并缓存用户标识与 token - 查询:活动列表、活动详情、用户资料、预约历史 - 业务:预约、修改密码、优惠券查询、支付订单更新、备注更新、取消、改签、转约 - 安全:所有需要鉴权的方法均在调用前校验认证状态 ```mermaid classDiagram class CosmoeClient { -baseUrl : string -userId : number -token : string +getToken(username, password) Promise~ApiResponse~ +setCredentials(userId, token) void +getCredentials() {userId, token} | null +isAuthenticated() boolean +getEvents() Promise~ApiResponse~ +getEventDetail(eventId) Promise~ApiResponse~ +getProfile() Promise~ApiResponse~ +getMyBookings() Promise~ApiResponse~ +bookEvent(req) Promise~ApiResponse~ +changePassword(old, new) Promise~ApiResponse~ +getUserProfile() Promise~ApiResponse~ +getAvailableCoupons(eventId) Promise~ApiResponse~ +updatePaymentOrder(bookingId, orderId) Promise~ApiResponse~ +updateBookingNote(bookingId, note) Promise~ApiResponse~ +cancelBooking(bookingId) Promise~ApiResponse~ +selfReschedule(bookingId, newSlot) Promise~ApiResponse~ +selfTransfer(bookingId, recipient) Promise~ApiResponse~ +register(key, username, email, password, identity) Promise~ApiResponse<{user_id, username}>~ } ``` 图表来源 - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503) 章节来源 - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503) ### 登录流程与认证集成 登录流程通过交互式会话完成,成功后将凭证写入 KV 命名空间,后续命令处理器读取并注入到 CosmoeClient。 ```mermaid sequenceDiagram participant U as "用户" participant C as "对话处理器" participant CL as "CosmoeClient" participant S as "Cosmoe 服务端" participant K as "KV 命名空间" U->>C : 输入用户名/密码 C->>CL : 创建实例并调用 getToken CL->>S : POST /CreatToken.php S-->>CL : 返回 {code, data : {user_id, token}} CL-->>C : 返回结果 alt 成功 C->>K : put(telegramUserId, {user_id, token, timestamp}) C-->>U : 登录成功 else 失败 C-->>U : 登录失败 end ``` 图表来源 - [src/command/handlers/login.ts](file://src/command/handlers/login.ts#L13-L74) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L124-L140) - [wrangler.jsonc](file://wrangler.jsonc#L21-L30) 章节来源 - [src/command/handlers/login.ts](file://src/command/handlers/login.ts#L1-L75) ### 预约流程与优惠券选择 预约流程包含活动详情获取、时间槽选择、优惠券查询与选择、最终提交预约。 ```mermaid sequenceDiagram participant U as "用户" participant B as "命令路由" participant H as "预约处理器" participant C as "CosmoeClient" participant S as "Cosmoe 服务端" participant K as "KV 命名空间" U->>B : /book_{eventId}_{slotIndex} B->>H : 触发 handleBookEvent H->>K : 读取凭证 H->>C : setCredentials(...) H->>C : getEventDetail(eventId) C->>S : GET /api.php?action=get_event_detail S-->>C : 返回 EventDetail C-->>H : 返回详情 alt 多个优惠券 H-->>U : 展示优惠券选择键盘 U->>B : 回调选择优惠券 B->>H : 触发 handleCouponSelection else 单个或无优惠券 H->>C : bookEvent({event_id, time_slot, coupon_code?}) C->>S : POST /api.php S-->>C : 返回结果 C-->>H : 返回结果 H-->>U : 成功/失败提示 end ``` 图表来源 - [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L11-L118) - [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L159-L226) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L191-L199) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L247-L270) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L329-L343) 章节来源 - [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L1-L226) ### 预约历史与取消 历史查询与取消流程展示了认证检查、数据排序与条件生成。 ```mermaid flowchart TD Start(["进入历史命令"]) --> ReadKV["读取 KV 中用户凭证"] ReadKV --> HasCreds{"凭证是否存在?"} HasCreds --> |否| PromptLogin["提示先登录"] --> End HasCreds --> |是| InitClient["初始化 CosmoeClient 并 setCredentials"] InitClient --> GetBookings["getMyBookings()"] GetBookings --> ResultOK{"code == 200 且有数据?"} ResultOK --> |否| ShowError["显示获取失败"] --> End ResultOK --> |是| Sort["按日期降序排序并取最新若干条"] Sort --> BuildMsg["构建 Markdown 格式消息"] BuildMsg --> CancelLink{"满足取消条件?"} CancelLink --> |是| AddCancel["添加取消链接"] CancelLink --> |否| SkipCancel["跳过取消链接"] AddCancel --> Send["发送消息"] SkipCancel --> Send Send --> 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#L1-L107) ### 定时任务与新活动通知 定时任务每分钟执行一次,比较最新事件 ID 并向所有已注册用户推送新活动通知。 ```mermaid sequenceDiagram participant T as "定时器" participant SCH as "调度处理器" participant C as "CosmoeClient" participant S as "Cosmoe 服务端" participant K as "KV 命名空间" participant U as "Telegram 用户" T->>SCH : 触发 scheduled SCH->>C : getEvents() C->>S : GET /api.php?action=get_events S-->>C : 返回事件列表 C-->>SCH : 返回事件列表 SCH->>K : list() 获取所有已注册用户 loop 对每个新事件 SCH->>U : 发送通知消息 end SCH->>K : 更新 latestEventId ``` 图表来源 - [src/scheduler/index.ts](file://src/scheduler/index.ts#L12-L88) - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L177-L184) - [wrangler.jsonc](file://wrangler.jsonc#L13-L17) 章节来源 - [src/scheduler/index.ts](file://src/scheduler/index.ts#L1-L88) ## 依赖关系分析 - 运行时依赖:grammy、@grammyjs/conversations、@grammyjs/storage-cloudflare - Worker 配置:KV 命名空间绑定、定时触发器、环境变量 - 测试:Vitest + Cloudflare Workers 测试工具链 ```mermaid graph LR P["package.json 依赖"] --> G["grammy"] P --> GC["grammy conversations"] P --> GS["grammy storage-cloudflare"] W["wrangler.jsonc"] --> KV1["COSMOE_CREDENTIALS"] W --> KV2["COSMOE_STORAGE"] W --> TRIG["定时触发器"] ``` 图表来源 - [package.json](file://package.json#L18-L22) - [wrangler.jsonc](file://wrangler.jsonc#L13-L30) 章节来源 - [package.json](file://package.json#L1-L24) - [wrangler.jsonc](file://wrangler.jsonc#L1-L31) ## 性能考量 - 请求合并与去抖:对于频繁查询的场景(如历史列表),可在客户端层增加本地缓存与去抖策略 - 异步并发:命令处理器中避免不必要的串行等待,合理使用 Promise 并行 - KV 读写:KV 写入为最终一致,建议在关键路径上做幂等与重试 - 超时与重试:当前实现未显式设置超时与重试,建议在 fetch 层增加超时控制与指数退避重试 - 数据量限制:历史消息长度超过平台限制时需截断或分页 ## 故障排除指南 - 认证失败 - 检查 KV 中是否正确存储了凭证 - 确认 CosmoeClient 是否已 setCredentials - 查看服务端返回的错误码与消息 - 服务端响应异常 - 捕获网络错误与 JSON 解析异常 - 在处理器中对 code 字段进行严格判断 - KV 读写异常 - 检查命名空间绑定与权限 - 对 JSON 解析失败进行容错处理 - 定时任务失败 - 查看日志输出,确认事件列表与用户列表读取是否成功 - 注意消息发送失败时的回退策略 章节来源 - [src/command/handlers/login.ts](file://src/command/handlers/login.ts#L70-L74) - [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L114-L118) - [src/command/handlers/history.ts](file://src/command/handlers/history.ts#L103-L107) - [src/scheduler/index.ts](file://src/scheduler/index.ts#L81-L84) ## 结论 本项目以 CosmoeClient 为核心,结合 GrammY 命令系统与 Cloudflare KV 实现了完整的聊天机器人 API 集成方案。通过清晰的职责分离与模块化设计,既保证了可维护性,也为后续扩展新的服务端功能或第三方 API 提供了良好基础。 ## 附录 ### 设计模式与最佳实践 - 单一职责:每个 API 方法只负责一个业务动作 - 统一错误处理:所有 API 方法返回统一的 ApiResponse 结构 - 权限前置:所有需要鉴权的方法在调用前检查认证状态 - 可测试性:将 KV 读写抽象为接口,便于单元测试替换 - 可扩展性:新增 API 时遵循现有模式,保持一致的请求/响应结构 ### 数据模型与验证 - 统一响应结构:包含 code、msg、data 字段 - 关键实体:Event、EventDetail、UserInfo、UserProfile、Booking、Coupon 等 - 参数校验:在客户端层对输入参数进行基本校验(如密码长度、时间槽索引范围) - 类型约束:使用 TypeScript 接口确保数据结构一致性 章节来源 - [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L9-L112) ### 扩展指南:新增 API 端点 步骤概览: 1. 在 CosmoeClient 中新增方法,定义请求参数与返回类型 2. 在命令处理器中调用新方法并处理返回结果 3. 如需持久化状态,使用 KV 命名空间进行读写 4. 编写单元测试与集成测试,覆盖正常与异常分支 ```mermaid flowchart TD A["定义新 API 方法"] --> B["实现请求构建与响应解析"] B --> C["在处理器中调用新方法"] C --> D["处理返回结果与错误"] D --> E["必要时写入 KV"] E --> F["编写测试用例"] ``` [此图为概念性流程图,无需图表来源] ### 超时与重试机制建议 - 超时控制:在 fetch 层设置合理的超时时间(例如 10 秒) - 指数退避重试:对 5xx 或网络瞬时错误进行最多 3 次重试,间隔 1、2、4 秒 - 幂等性:对可能重复提交的操作(如支付订单更新)确保幂等 - 降级策略:在网络不可用时返回友好提示并记录日志 [本节为通用指导,无需章节来源]