整体架构.md 15 KB

整体架构

本文引用的文件

  • package.json
  • wrangler.jsonc
  • src/index.ts
  • src/command/index.ts
  • src/command/handlers/start.ts
  • src/command/handlers/login.ts
  • src/command/handlers/events.ts
  • src/scheduler/index.ts
  • src/client/cosmoe.ts
  • worker-configuration.d.ts
  • tsconfig.json
  • test/index.spec.ts

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能与成本考量
  8. 可扩展性与容错设计
  9. 监控与可观测性
  10. 故障排查指南
  11. 结论

简介

本项目为基于 Cloudflare Workers 的 Telegram 机器人,采用三层架构:

  • Webhook 接收层:通过 Cloudflare Workers 的 fetch 事件接收 Telegram Webhook 请求,并交由 grammy 框架处理。
  • 业务逻辑层:grammy 框架承载命令路由、对话(conversations)状态管理、回调查询处理等;结合 KV 存储实现对话状态持久化。
  • 数据访问层:使用 Cloudflare KV 命名空间存储用户凭证与会话状态;同时通过定时触发器执行周期性任务(如新活动通知)。

架构决策要点:

  • 运行时:选择 Cloudflare Workers 作为无服务器运行时,具备全球边缘节点、低延迟、按需计费与自动扩缩容能力。
  • 框架:grammy 提供简洁的 Telegram Bot API 封装、插件生态(如 conversations),便于快速构建复杂交互。
  • 数据层:KV 命名空间满足轻量级键值存储需求,配合 @grammyjs/storage-cloudflare 实现对话状态持久化。
  • 可观测性:启用 Wrangler 观测性开关,结合日志与错误处理实现基础监控。

项目结构

项目采用按功能模块划分的目录组织方式,核心入口位于 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

图表来源

  • wrangler.jsonc
  • package.json
  • tsconfig.json
  • worker-configuration.d.ts
  • src/index.ts
  • src/command/index.ts
  • src/scheduler/index.ts
  • src/client/cosmoe.ts
  • test/index.spec.ts

章节来源

  • wrangler.jsonc
  • package.json
  • tsconfig.json
  • worker-configuration.d.ts

核心组件

  • 入口与运行时适配:src/index.ts 作为 Cloudflare Worker 入口,初始化 Bot、设置命令菜单、挂载 webhook 回调,并注册定时任务处理器。
  • 命令与对话系统:src/command/index.ts 注册命令路由、回调查询、对话(conversations)以及基于 KV 的会话存储。
  • 外部 API 客户端:src/client/cosmoe.ts 封装对第三方摄影平台 API 的调用,统一响应结构与认证流程。
  • 定时任务:src/scheduler/index.ts 通过 Cloudflare Cron 触发器定期拉取新活动并向已注册用户推送通知。
  • 配置与类型:wrangler.jsonc 定义 Worker 名称、入口、KV 绑定、定时触发器与变量;tsconfig.json 与 worker-configuration.d.ts 提供类型支持。

章节来源

  • src/index.ts
  • src/command/index.ts
  • src/client/cosmoe.ts
  • src/scheduler/index.ts
  • wrangler.jsonc
  • tsconfig.json
  • worker-configuration.d.ts

架构总览

整体架构以 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

图表来源

  • src/index.ts
  • src/command/index.ts
  • src/scheduler/index.ts
  • src/client/cosmoe.ts
  • wrangler.jsonc

详细组件分析

Webhook 接收层(HTTP 请求处理)

  • 入口函数:src/index.ts 中导出的默认对象包含 fetch 与 scheduled 方法,分别处理 HTTP 请求与定时任务。
  • 初始化 Bot:从环境变量读取 BOT_INFO 与 BOT_TOKEN,构造 Bot 实例。
  • 命令菜单:首次部署时设置可用命令列表,便于用户发现。
  • 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 : "发送消息/内联键盘"
    

图表来源

  • src/index.ts
  • src/command/index.ts

章节来源

  • src/index.ts

业务逻辑层(grammy 框架与命令处理器)

  • 对话(conversations):通过 @grammyjs/conversations 与 @grammyjs/storage-cloudflare 实现跨请求的状态持久化,KV 适配器负责序列化/反序列化。
  • 命令路由:注册 /start、/login、/events、/event{id}、/book{eventid}{slotid}、/history、/cancel{booking_id} 等命令与回调查询。
  • 登录流程:交互式对话收集用户名/密码,调用 CosmoeClient 获取 token 并存入 KV,绑定 Telegram 用户 ID。
  • 事件与预约:调用 CosmoeClient 获取活动列表与详情,支持优惠券选择与取消确认等交互。

    flowchart TD
    Start(["进入 /login"]) --> AskUser["提示输入用户名"]
    AskUser --> WaitUser["等待用户回复"]
    WaitUser --> AskPass["提示输入密码"]
    AskPass --> WaitPass["等待用户回复"]
    WaitPass --> CallAPI["调用 getToken 获取 token"]
    CallAPI --> SaveKV["以 Telegram 用户ID 为键保存凭证到 KV"]
    SaveKV --> Done(["完成登录"])
    

图表来源

  • src/command/index.ts
  • src/command/handlers/login.ts

章节来源

  • src/command/index.ts
  • src/command/handlers/start.ts
  • src/command/handlers/login.ts
  • src/command/handlers/events.ts

数据访问层(KV 存储)

  • KV 命名空间:
    • COSMOE_CREDENTIALS:存储已登录用户的凭证(user_id、token、timestamp),键为 Telegram 用户 ID。
    • COSMOE_STORAGE:存储会话状态与系统状态(如 latestEventId)。
  • 会话存储:通过 KV 适配器实现 conversations 的 read/write/delete,确保多实例间状态一致。
  • 定时任务:从 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(["结束"])
    

图表来源

  • src/scheduler/index.ts

章节来源

  • wrangler.jsonc
  • src/scheduler/index.ts

外部 API 客户端(CosmoeClient)

  • 统一响应结构:定义 ApiResponse,便于统一处理 code/msg/data。
  • 认证与令牌:getToken 获取 user_id 与 token,setCredentials/getCredentials 支持手动设置与读取。
  • 业务接口:提供 getEvents、getEventDetail、getProfile、getMyBookings、bookEvent、cancelBooking 等方法,参数与返回值均遵循 API 文档约定。
  • 错误处理:未认证时抛出异常,便于上层统一处理。

    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>
    }
    
  • 图表来源

    • src/client/cosmoe.ts

    章节来源

    • src/client/cosmoe.ts

    依赖关系分析

    • 运行时与工具链:依赖 Wrangler 作为部署与开发工具,@cloudflare/vitest-pool-workers 提供 Workers 测试环境。
    • 框架与插件:grammy 提供核心 Bot 能力;@grammyjs/conversations 提供对话状态管理;@grammyjs/storage-cloudflare 提供 KV 存储适配。
    • 类型与配置: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
      

    图表来源

    • package.json
    • wrangler.jsonc
    • tsconfig.json
    • worker-configuration.d.ts

    章节来源

    • package.json
    • wrangler.jsonc
    • tsconfig.json
    • worker-configuration.d.ts

    性能与成本考量

    • 无服务器优势:Cloudflare Workers 具备全球边缘节点与按请求计费模式,适合突发流量与低延迟场景。
    • KV 成本:KV 读写次数与存储容量影响成本,建议合理设计键命名与数据结构,避免频繁小对象写入。
    • API 调用:外部 API 调用存在网络开销,建议在客户端层进行必要的缓存与去抖(可在后续扩展中引入)。
    • 扩展性:grammy 插件生态与 KV 存储天然支持水平扩展,无需维护数据库连接池或主从复制。

    [本节为通用性能讨论,不直接分析具体文件]

    可扩展性与容错设计

    • 可扩展性:
      • 命令与处理器模块化,新增命令只需在 command/index.ts 中注册路由与处理器。
      • KV 命名空间可按功能拆分,如将会话与用户凭证分离,提升隔离度。
      • 定时任务可按业务拆分为多个 cron 表达式,降低单任务负载。
    • 容错机制:
      • 命令与定时任务均包含 try/catch 与错误日志输出,便于定位问题。
      • KV 读写失败时记录错误并继续执行,避免单点故障导致整体失败。
      • 对外 API 调用失败时返回友好提示,避免崩溃。

    章节来源

    • src/command/index.ts
    • src/scheduler/index.ts

    监控与可观测性

    • 观测性开关:wrangler.jsonc 启用 observability,便于在 Cloudflare 控制台查看日志与追踪。
    • 日志:命令与定时任务中广泛使用 console.log/error,便于排查问题。
    • 测试:使用 @cloudflare/vitest-pool-workers 提供 Workers 测试环境,支持单元与集成测试。

    章节来源

    • wrangler.jsonc
    • test/index.spec.ts

    故障排查指南

    • Webhook 不生效:
      • 检查 wrangler.jsonc 中的 main 与 name 是否正确。
      • 确认部署后是否设置了正确的 Telegram Webhook。
    • 命令无响应:
      • 查看控制台日志,确认命令是否被正确注册与路由。
      • 检查 KV 命名空间绑定是否正确。
    • 登录失败:
      • 确认外部 API 返回码与消息,检查用户名/密码是否正确。
      • 检查 KV 写入是否成功。
    • 定时任务未执行:
      • 检查 cron 表达式与触发器配置。
      • 查看控制台日志,确认任务是否被调度。

    章节来源

    • wrangler.jsonc
    • src/index.ts
    • src/command/handlers/login.ts
    • src/scheduler/index.ts

    结论

    本项目以 Cloudflare Workers 为基础,结合 grammy 框架与 KV 存储,实现了高可用、低延迟且易于扩展的 Telegram 机器人。通过清晰的三层架构与完善的错误处理,系统能够在无服务器环境下稳定运行,并为后续功能扩展(如队列、Durable Objects 或更复杂的缓存策略)预留空间。