本文引用的文件
本设计文档围绕 Cosmoe Bot 的数据流进行系统性梳理,覆盖从 Telegram 用户消息进入 Cloudflare Workers,经由 grammY 框架解析与路由,到各命令处理器执行业务逻辑、调用 Cosmoe API 客户端访问外部服务,并通过 KV 存储完成状态持久化的完整链路。文档同时给出数据流向图、关键数据节点结构定义、缓存策略与一致性保障、异步处理与错误恢复机制等。
该项目采用按功能模块组织的目录结构,核心入口在 Cloudflare Workers 中,使用 grammY 作为 Telegram Bot 框架,配合 @grammyjs/conversations 实现对话式交互,使用 @grammyjs/storage-cloudflare 将会话状态持久化至 KV。
graph TB
subgraph "Cloudflare Workers"
A["src/index.ts<br/>入口与webhook回调"]
B["src/command/index.ts<br/>命令注册与会话存储"]
C["src/scheduler/index.ts<br/>定时任务"]
end
subgraph "命令处理器"
H1["start.ts"]
H2["login.ts"]
H3["events.ts"]
H4["eventDetails.ts"]
H5["bookEvent.ts"]
H6["history.ts"]
H7["cancel.ts"]
H8["logout.ts"]
end
subgraph "外部服务"
E["Telegram API"]
F["Cosmoe API"]
end
subgraph "KV 存储"
K1["COSMOE_CREDENTIALS<br/>用户凭证"]
K2["COSMOE_STORAGE<br/>通用状态"]
end
A --> B
A --> C
B --> H1
B --> H2
B --> H3
B --> H4
B --> H5
B --> H6
B --> H7
B --> H8
H2 --> K1
H6 --> K1
H8 --> K1
H5 --> F
H6 --> F
H7 --> F
H3 --> F
H4 --> F
C --> F
C --> K2
图表来源
章节来源
章节来源
下图展示从 Telegram 到 Cloudflare Workers、grammY、命令处理器、Cosmoe API 客户端以及 KV 存储的整体数据流。
sequenceDiagram
participant U as "用户"
participant T as "Telegram API"
participant W as "Cloudflare Workers<br/>src/index.ts"
participant G as "grammY 框架"
participant CMD as "命令处理器<br/>src/command/handlers/*"
participant KV as "KV 存储<br/>COSMOE_CREDENTIALS/COSMOE_STORAGE"
participant API as "Cosmoe API"
U->>T : "发送消息/命令"
T-->>W : "HTTP 请求"
W->>G : "webhookCallback 分发"
G->>CMD : "匹配命令/回调并执行"
CMD->>KV : "读取/写入用户凭证/状态"
CMD->>API : "调用 Cosmoe API"
API-->>CMD : "返回业务数据"
CMD-->>G : "构造响应"
G-->>W : "生成 Telegram 响应"
W-->>T : "回传消息"
T-->>U : "显示结果"
图表来源
命令路由:注册 /start、/login、/events、/event{id}、/book{event}{slot}、/history、/cancel{id}、回调等。
flowchart TD
Start(["进入 setupCommands"]) --> KV["创建 KV 适配器<br/>绑定 COSMOE_STORAGE"]
KV --> Conv["安装 conversations 插件<br/>指定 storage=KV"]
Conv --> Login["注册 /login 对话<br/>enter('login')"]
Login --> ReadCreds["读取用户凭证<br/>COSMOE_CREDENTIALS"]
ReadCreds --> ExecCmd["执行命令处理器"]
ExecCmd --> WriteKV["写入 KV 状态/凭证"]
WriteKV --> End(["完成"])
图表来源
章节来源
异常处理:输入缺失、认证失败、KV 写入异常均进行友好提示与日志记录。
sequenceDiagram
participant U as "用户"
participant CMD as "handleInteractiveLogin"
participant KV as "COSMOE_CREDENTIALS"
participant API as "CosmoeClient.getToken"
U->>CMD : "/login 进入对话"
CMD->>U : "提示输入用户名"
U-->>CMD : "用户名"
CMD->>U : "提示输入密码"
U-->>CMD : "密码"
CMD->>API : "getToken(username,password)"
API-->>CMD : "返回 {user_id,token}"
CMD->>KV : "put(telegramUserId, JSON)"
CMD-->>U : "登录成功提示"
图表来源
章节来源
/event{id}:调用 getEventDetail 获取活动详情,渲染时间段、价格、剩余容量,并对可预约时间段提供 /book{event}_{slot} 链接。
flowchart TD
A["/events"] --> B["CosmoeClient.getEvents"]
B --> C["筛选最新N条"]
C --> D["拼装 Markdown 列表"]
D --> E["发送消息"]
F["/event_{id}"] --> G["CosmoeClient.getEventDetail"]
G --> H["排序时间槽"]
H --> I{"是否可预约"}
I --> |是| J["生成 /book_{event}_{slot} 链接"]
I --> |否| K["仅展示信息"]
图表来源
章节来源
调用 bookEvent 提交预约,返回最终价格、预约编号等信息。
sequenceDiagram
participant U as "用户"
participant CMD as "handleBookEvent"
participant KV as "COSMOE_CREDENTIALS"
participant API as "CosmoeClient"
participant CB as "handleCouponSelection"
U->>CMD : "/book_{event}_{slot}"
CMD->>KV : "读取凭证"
CMD->>API : "getEventDetail(eventId)"
CMD->>API : "getAvailableCoupons(eventId)"
alt 多个优惠券
CMD-->>U : "显示内联键盘选择"
U->>CB : "回调 : select_coupon_{...}"
CB->>API : "bookEvent(带coupon)"
else 单个/无优惠券
CMD->>API : "bookEvent(直接提交)"
end
API-->>CMD : "返回预约结果"
CMD-->>U : "发送成功/失败消息"
图表来源
章节来源
/cancel_{id}:弹出确认内联键盘,确认后调用 cancelBooking 执行取消。
flowchart TD
H1["/history"] --> H2["读取凭证"]
H2 --> H3["CosmoeClient.getMyBookings"]
H3 --> H4["格式化 Markdown"]
H4 --> H5["发送消息"]
C1["/cancel_{id}"] --> C2["读取凭证"]
C2 --> C3["获取预约详情"]
C3 --> C4["内联键盘确认"]
C4 --> C5["cancelBooking"]
C5 --> C6["编辑消息反馈结果"]
图表来源
章节来源
逻辑:读取 COSMOE_STORAGE 中的 latestEventId,拉取全部活动,过滤新增活动,遍历 COSMOE_CREDENTIALS 中的用户键,逐个发送通知,并更新 latestEventId。
flowchart TD
S["scheduled 触发"] --> L["读取 latestEventId"]
L --> E["CosmoeClient.getEvents"]
E --> F["过滤新活动"]
F --> K["遍历已注册用户键"]
K --> N["bot.api.sendMessage"]
N --> U["更新 latestEventId"]
图表来源
章节来源
章节来源
章节来源
章节来源
构建与脚本:使用 TypeScript 与 Vitest,部署与开发通过 Wrangler CLI。
graph LR
P["package.json 依赖"] --> G["grammy"]
P --> C["conversations"]
P --> S["storage-cloudflare"]
W["wrangler.jsonc 配置"] --> T["worker-configuration.d.ts 类型"]
图表来源
章节来源
章节来源
该系统通过 grammY 与 Cloudflare Workers 实现高可用的 Telegram Bot 数据流:用户消息经由 webhook 进入 Worker,命令处理器负责业务编排,Cosmoe API 客户端承担外部数据交互,KV 存储贯穿凭证与会话状态管理。整体具备清晰的模块边界、完善的错误处理与可观测性配置,适合在生产环境中稳定运行与扩展。