本文引用的文件
本项目为基于 Cloudflare Workers 的 Telegram 机器人,采用三层架构:
架构决策要点:
项目采用按功能模块划分的目录组织方式,核心入口位于 src/index.ts,命令处理集中在 src/command,定时任务在 src/scheduler,对外 API 客户端封装在 src/client。
graph TB
subgraph "运行时与配置"
WR["wrangler.jsonc"]
PKG["package.json"]
TS["tsconfig.json"]
WCFG["worker-configuration.d.ts"]
end
subgraph "应用入口"
IDX["src/index.ts"]
end
subgraph "业务逻辑层"
CMD["src/command/index.ts"]
HANDLERS["src/command/handlers/*.ts"]
end
subgraph "数据访问层"
SCHED["src/scheduler/index.ts"]
CLIENT["src/client/cosmoe.ts"]
KV1["KV: COSMOE_CREDENTIALS"]
KV2["KV: COSMOE_STORAGE"]
end
subgraph "测试"
TEST["test/index.spec.ts"]
end
WR --> IDX
PKG --> IDX
TS --> IDX
WCFG --> IDX
IDX --> CMD
CMD --> HANDLERS
CMD --> KV2
SCHED --> KV1
SCHED --> KV2
SCHED --> CLIENT
HANDLERS --> CLIENT
图表来源
章节来源
章节来源
整体架构以 Cloudflare Workers 为核心运行时,通过 webhook 接收 Telegram 请求,grammy 负责路由与状态管理,KV 提供会话与用户凭证存储,定时触发器负责后台任务。
graph TB
TG["Telegram 用户"] --> WEBHOOK["Cloudflare Workers<br/>fetch 事件"]
WEBHOOK --> BOT["grammy Bot"]
BOT --> CMDS["命令与回调处理"]
CMDS --> CONV["conversations 插件"]
CONV --> KVSTORE["KV: COSMOE_STORAGE"]
BOT --> API["Telegram API"]
SCHED["Cron 触发器"] --> SCHEDTASK["定时任务处理器"]
SCHEDTASK --> KVREG["KV: COSMOE_CREDENTIALS"]
SCHEDTASK --> API
SCHEDTASK --> CLIENT["CosmoeClient"]
subgraph "KV 命名空间"
KVREG
KVSTORE
end
图表来源
Webhook 回调:通过 webhookCallback(bot, "cloudflare-mod") 将请求交由 grammy 处理,返回响应。
sequenceDiagram
participant TG as "Telegram"
participant CF as "Cloudflare Workers"
participant BOT as "grammy Bot"
participant CMD as "命令处理器"
participant KV as "KV 存储"
TG->>CF : "POST /webhook"
CF->>BOT : "webhookCallback(...)"
BOT->>CMD : "匹配命令/回调"
CMD->>KV : "读写会话/凭证"
CMD-->>TG : "发送消息/内联键盘"
图表来源
章节来源
事件与预约:调用 CosmoeClient 获取活动列表与详情,支持优惠券选择与取消确认等交互。
flowchart TD
Start(["进入 /login"]) --> AskUser["提示输入用户名"]
AskUser --> WaitUser["等待用户回复"]
WaitUser --> AskPass["提示输入密码"]
AskPass --> WaitPass["等待用户回复"]
WaitPass --> CallAPI["调用 getToken 获取 token"]
CallAPI --> SaveKV["以 Telegram 用户ID 为键保存凭证到 KV"]
SaveKV --> Done(["完成登录"])
图表来源
章节来源
定时任务:从 COSMOE_STORAGE 读取 latestEventId,对比新活动列表,向所有已注册用户发送通知后更新最新 ID。
flowchart TD
Tick(["Cron 触发"]) --> LoadLast["从 COSMOE_STORAGE 读取 latestEventId"]
LoadLast --> Fetch["调用 CosmoeClient.getEvents()"]
Fetch --> Filter["筛选大于 latestEventId 的新活动"]
Filter --> ListUsers["从 COSMOE_CREDENTIALS 列出所有用户键"]
ListUsers --> Notify["逐用户发送通知消息"]
Notify --> Update["更新 COSMOE_STORAGE 中的 latestEventId"]
Update --> End(["结束"])
图表来源
章节来源
错误处理:未认证时抛出异常,便于上层统一处理。
classDiagram
class CosmoeClient {
+getToken(username, password) ApiResponse<TokenResponse>
+setCredentials(userId, token) void
+getCredentials() {userId, token} | null
+isAuthenticated() boolean
+getEvents() ApiResponse<Event[]>
+getEventDetail(eventId) ApiResponse<EventDetail>
+getProfile() ApiResponse<ProfileData>
+getMyBookings() ApiResponse<Booking[]>
+bookEvent(req) ApiResponse<any>
+cancelBooking(bookingId) ApiResponse<any>
}
图表来源
章节来源
类型与配置:tsconfig.json 指定目标与模块解析策略;worker-configuration.d.ts 提供 Cloudflare 运行时类型声明。
graph LR
PKG["package.json"] --> GRAMMY["grammy"]
PKG --> CONVS["@grammyjs/conversations"]
PKG --> KVADAPTER["@grammyjs/storage-cloudflare"]
PKG --> WRANGLER["wrangler"]
PKG --> VITEST["@cloudflare/vitest-pool-workers"]
WR["wrangler.jsonc"] --> ENV["环境变量/KV 绑定"]
TS["tsconfig.json"] --> TYPES["类型声明"]
WCFG["worker-configuration.d.ts"] --> TYPES
图表来源
章节来源
[本节为通用性能讨论,不直接分析具体文件]
章节来源
章节来源
章节来源
本项目以 Cloudflare Workers 为基础,结合 grammy 框架与 KV 存储,实现了高可用、低延迟且易于扩展的 Telegram 机器人。通过清晰的三层架构与完善的错误处理,系统能够在无服务器环境下稳定运行,并为后续功能扩展(如队列、Durable Objects 或更复杂的缓存策略)预留空间。