# 扩展开发
**本文引用的文件**
- [src/index.ts](file://src/index.ts)
- [src/command/index.ts](file://src/command/index.ts)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts)
- [src/scheduler/index.ts](file://src/scheduler/index.ts)
- [src/command/handlers/start.ts](file://src/command/handlers/start.ts)
- [src/command/handlers/login.ts](file://src/command/handlers/login.ts)
- [src/command/handlers/events.ts](file://src/command/handlers/events.ts)
- [src/command/handlers/history.ts](file://src/command/handlers/history.ts)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts)
- [package.json](file://package.json)
- [tsconfig.json](file://tsconfig.json)
- [worker-configuration.d.ts](file://worker-configuration.d.ts)
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本指南面向希望为 Cosmoe Bot 进行扩展开发的工程师,覆盖以下主题:
- 如何新增命令处理器:从命令注册、参数解析到业务逻辑实现的完整流程
- 对话状态管理的扩展方法:自定义对话状态、状态转换规则、数据持久化策略
- 新增 API 客户端:端点封装、认证集成、统一错误处理
- 插件系统的使用:基于 grammY 的插件架构扩展功能
- 最佳实践与代码规范:确保新功能与现有系统兼容一致
- 实际扩展示例与常见场景:快速上手与问题定位
## 项目结构
Cosmoe Bot 采用按职责分层的组织方式:
- 入口与运行时:Cloudflare Worker 入口负责初始化 Bot、注册命令菜单、接入 Webhook 与定时任务
- 命令层:集中注册命令与回调,协调对话与业务处理器
- 业务处理器:每个命令对应一个处理器模块,负责参数解析与调用 API 客户端
- API 客户端:对第三方 API 的统一封装,提供认证、错误处理与数据模型
- 调度器:基于 Cloudflare Cron 的定时任务,用于推送新活动通知等
```mermaid
graph TB
A["入口
src/index.ts"] --> B["命令注册与对话
src/command/index.ts"]
B --> C["命令处理器
src/command/handlers/*.ts"]
C --> D["API 客户端
src/client/cosmoe.ts"]
A --> E["定时任务
src/scheduler/index.ts"]
A --> F["环境变量与类型
worker-configuration.d.ts"]
```
图表来源
- [src/index.ts](file://src/index.ts#L13-L46)
- [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)
章节来源
- [src/index.ts](file://src/index.ts#L1-L47)
- [src/command/index.ts](file://src/command/index.ts#L1-L110)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L1-L503)
- [src/scheduler/index.ts](file://src/scheduler/index.ts#L1-L88)
- [worker-configuration.d.ts](file://worker-configuration.d.ts#L1-L200)
## 核心组件
- Bot 与上下文:通过 grammY 初始化 Bot,并注入对话风味(ConversationFlavor)以支持对话状态
- 命令注册中心:集中安装 conversations 插件、KV 存储适配器,并注册各类命令与回调
- API 客户端:封装第三方 API 的认证、端点与错误处理,统一返回结构
- KV 持久化:使用 Cloudflare KV 作为对话状态与用户凭证的存储介质
- 定时任务:基于 Cloudflare Cron 推送新活动通知
章节来源
- [src/index.ts](file://src/index.ts#L13-L46)
- [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 W as "Worker 入口
src/index.ts"
participant B as "Bot/命令注册
src/command/index.ts"
participant H as "命令处理器
handlers/*.ts"
participant C as "API 客户端
src/client/cosmoe.ts"
participant K as "KV 存储
COSMOE_STORAGE/COSMOE_CREDENTIALS"
U->>W : "发送消息/回调"
W->>B : "webhookCallback 分发"
B->>H : "匹配命令/正则/回调键"
H->>K : "读取/写入对话状态/凭证"
H->>C : "调用 API 方法"
C-->>H : "返回统一结构"
H-->>U : "回复消息/内联键盘"
```
图表来源
- [src/index.ts](file://src/index.ts#L13-L46)
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
## 详细组件分析
### 命令注册与路由
- 安装对话插件与 KV 存储:通过 @grammyjs/storage-cloudflare 的 KvAdapter 将对话状态持久化至 KV
- 注册命令与回调:
- 基础命令:/start、/events、/history、/login、/logout
- 正则路由:/event_{id}、/book_{event_id}_{slot_id}、/cancel_{booking_id}
- 回调查询:确认取消、优惠券选择等
- 设置命令菜单:在入口中一次性设置 Bot 命令列表
```mermaid
flowchart TD
A["setupCommands 启动"] --> B["安装 conversations 插件"]
B --> C["注册命令与回调"]
C --> D["/start /events /history /login /logout"]
C --> E["正则路由:/event_*/book_*/cancel_*"]
C --> F["回调查询:confirm_cancel_* / select_coupon_*"]
A --> G["设置命令菜单"]
```
图表来源
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
- [src/index.ts](file://src/index.ts#L24-L32)
章节来源
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
- [src/index.ts](file://src/index.ts#L13-L46)
### 对话状态管理扩展
- 自定义对话状态:通过 conversations 插件与 KV 存储,对话状态可跨多轮消息保存
- 状态转换规则:在对话处理器内部使用 conversation.wait() 等 API 控制等待与流转
- 数据持久化策略:KV 适配器负责序列化/反序列化,异常时记录日志并保持健壮性
```mermaid
sequenceDiagram
participant U as "用户"
participant B as "Bot"
participant CV as "对话处理器
login.ts"
participant K as "KV 存储"
U->>B : "/login"
B->>CV : "enter('login')"
CV->>U : "提示输入用户名"
U->>CV : "用户名"
CV->>U : "提示输入密码"
U->>CV : "密码"
CV->>K : "写入凭证"
CV-->>U : "登录结果"
```
图表来源
- [src/command/index.ts](file://src/command/index.ts#L54-L57)
- [src/command/handlers/login.ts](file://src/command/handlers/login.ts#L13-L75)
章节来源
- [src/command/index.ts](file://src/command/index.ts#L20-L57)
- [src/command/handlers/login.ts](file://src/command/handlers/login.ts#L1-L75)
### API 客户端集成指南
- 端点封装:每个 API 方法封装为独立方法,统一参数与返回结构
- 认证机制:支持显式设置凭证或通过登录流程自动获取并存入 KV
- 错误处理:统一返回结构包含 code/msg/data;在客户端内部抛出语义化错误或返回错误码
```mermaid
classDiagram
class CosmoeClient {
+getToken(username, password)
+setCredentials(userId, token)
+getCredentials()
+isAuthenticated()
+getEvents()
+getEventDetail(eventId)
+getProfile()
+getMyBookings()
+bookEvent(request)
+changePassword(...)
+getUserProfile()
+getAvailableCoupons(eventId)
+updatePaymentOrder(...)
+updateBookingNote(...)
+cancelBooking(bookingId)
+selfReschedule(...)
+selfTransfer(...)
+register(...)
}
```
图表来源
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
章节来源
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
### 新增命令处理器:从零到一
- 步骤概览
1) 在命令注册处引入新处理器并注册命令/回调
2) 在处理器中解析参数(命令参数、正则捕获、回调数据)
3) 读取 KV 凭证或对话状态,调用 API 客户端
4) 组织消息内容,必要时构造内联键盘
5) 返回响应并处理异常
- 参考实现路径
- 基础命令:/start、/events、/history、/login、/logout
- 参数解析:正则路由与回调键解析
- KV 读写:凭证与对话状态
- API 调用:统一在处理器中调用 CosmoeClient
章节来源
- [src/command/index.ts](file://src/command/index.ts#L59-L110)
- [src/command/handlers/start.ts](file://src/command/handlers/start.ts#L1-L6)
- [src/command/handlers/events.ts](file://src/command/handlers/events.ts#L1-L27)
- [src/command/handlers/history.ts](file://src/command/handlers/history.ts#L1-L107)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L1-L226)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L1-L132)
### 插件系统与扩展点
- conversations 插件:用于多轮对话与状态持久化
- @grammyjs/storage-cloudflare:KV 存储适配器
- grammY 中间件与插件:可在入口或命令注册阶段安装更多插件
章节来源
- [src/command/index.ts](file://src/command/index.ts#L2-L52)
- [package.json](file://package.json#L18-L22)
### 定时任务与通知
- 触发时机:Cloudflare Cron 定时触发
- 逻辑要点:拉取最新事件、对比上次 ID、向已登录用户逐一推送通知
- KV 使用:存储最新事件 ID 与用户凭证
```mermaid
sequenceDiagram
participant S as "调度器
src/scheduler/index.ts"
participant C as "API 客户端"
participant K as "KV 存储"
participant T as "Telegram Bot"
S->>C : "getEvents()"
C-->>S : "事件列表"
S->>K : "读取/更新 latestEventId"
loop 遍历新事件
S->>K : "列出已注册用户"
S->>T : "sendMessage(用户, 新活动通知)"
end
```
图表来源
- [src/scheduler/index.ts](file://src/scheduler/index.ts#L12-L88)
章节来源
- [src/scheduler/index.ts](file://src/scheduler/index.ts#L1-L88)
## 依赖关系分析
- 运行时依赖:grammy、@grammyjs/conversations、@grammyjs/storage-cloudflare
- 类型与环境:通过 wrangler 生成的类型声明与 Cloudflare Worker 环境对接
```mermaid
graph LR
P["package.json 依赖"] --> G["grammy"]
P --> GC["conversations"]
P --> KS["@grammyjs/storage-cloudflare"]
T["tsconfig.json 编译配置"] --> R["运行时类型/严格检查"]
W["worker-configuration.d.ts"] --> E["Env 类型注入"]
```
图表来源
- [package.json](file://package.json#L18-L22)
- [tsconfig.json](file://tsconfig.json#L2-L46)
- [worker-configuration.d.ts](file://worker-configuration.d.ts#L1-L200)
章节来源
- [package.json](file://package.json#L1-L24)
- [tsconfig.json](file://tsconfig.json#L1-L46)
- [worker-configuration.d.ts](file://worker-configuration.d.ts#L1-L200)
## 性能考量
- KV 读写:对话状态与凭证均走 KV,注意批量读取与序列化开销
- API 调用:避免在高频路径重复请求,可结合缓存策略(如仅在需要时刷新)
- 消息长度:输出内容需遵守 Telegram API 限制,必要时截断或分段发送
- 并发控制:定时任务与 Webhook 并发执行,注意 KV 写入竞争与幂等设计
## 故障排查指南
- 常见错误与处理
- KV 读写异常:在对话存储适配器中已记录错误日志,检查命名空间权限与键名
- 认证失败:确认凭证是否过期或被清理,必要时引导用户重新登录
- API 返回非 200:在处理器中统一解析 msg 字段并反馈给用户
- 正则解析失败:检查命令格式与回调键拼接规则
- 日志与可观测性
- 在命令处理器与 API 客户端中保留必要的错误日志
- 定时任务中对每个用户的推送结果进行验证与日志记录
章节来源
- [src/command/index.ts](file://src/command/index.ts#L25-L49)
- [src/command/handlers/history.ts](file://src/command/handlers/history.ts#L103-L107)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L124-L140)
## 结论
通过统一的命令注册中心、KV 持久化的对话状态、以及统一封装的 API 客户端,Cosmoe Bot 提供了清晰的扩展路径。新增命令时遵循“注册—解析—调用—回复—异常”的闭环流程,并在处理器中完成 KV 与 API 的交互,即可快速实现新功能并与现有系统保持一致。
## 附录
### 新增命令处理器最佳实践
- 命令注册
- 在命令注册文件中引入处理器并注册命令/回调
- 为回调键与正则表达式定义稳定的格式,便于解析与维护
- 参数解析
- 使用正则捕获关键字段,或在处理器中解析命令文本
- 对用户输入进行最小化校验,尽早失败
- 业务逻辑
- 优先读取 KV 凭证或对话状态,再调用 API 客户端
- 统一处理 API 返回结构,提取 msg 作为用户可见错误提示
- 消息与交互
- 必要时构造内联键盘,区分编辑消息与发送新消息
- 控制消息长度,避免超过平台限制
- 异常处理
- 在处理器中捕获异常并记录日志,向用户返回友好提示
- 对于 KV 与网络异常,区分重试策略与降级方案
章节来源
- [src/command/index.ts](file://src/command/index.ts#L59-L110)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L11-L118)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L11-L84)
### 对话状态扩展清单
- 自定义对话:使用 createConversation 定义新对话,绑定环境变量
- 状态读写:通过 conversations 插件与 KV 适配器实现状态持久化
- 等待与恢复:在对话处理器中使用 wait/answerCallbackQuery 等 API 控制流程
章节来源
- [src/command/index.ts](file://src/command/index.ts#L54-L57)
### API 客户端扩展清单
- 新增端点:在客户端类中新增方法,遵循统一的参数与返回结构
- 认证集成:支持 setCredentials 或通过登录流程自动写入 KV
- 错误处理:在客户端内部抛出语义化错误或返回错误码,由调用方统一处理
章节来源
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
### 插件系统使用建议
- conversations:用于多轮对话与状态持久化
- @grammyjs/storage-cloudflare:KV 存储适配器
- grammY 生态:根据需求引入中间件或插件,注意版本兼容与类型声明
章节来源
- [package.json](file://package.json#L18-L22)
- [src/command/index.ts](file://src/command/index.ts#L2-L52)