项目概述.md 14 KB

项目概述

本文引用的文件

  • package.json
  • src/index.ts
  • src/command/index.ts
  • src/client/cosmoe.ts
  • src/command/handlers/start.ts
  • src/command/handlers/login.ts
  • src/command/handlers/events.ts
  • src/command/handlers/eventDetails.ts
  • src/command/handlers/bookEvent.ts
  • src/command/handlers/history.ts
  • src/command/handlers/cancel.ts
  • src/command/handlers/logout.ts
  • src/scheduler/index.ts
  • wrangler.jsonc
  • tsconfig.json
  • test/index.spec.ts

目录

  1. 引言
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖分析
  7. 性能考虑
  8. 故障排除指南
  9. 结论
  10. 附录

引言

Cosmoe Bot 是一个基于 Cloudflare Workers 的 Telegram 摄影活动预约管理机器人。它通过与 Cosmoe 摄影平台的 API 集成,为用户提供便捷的活动浏览、登录认证、在线预约与取消、预约历史查询等功能,并支持定时任务推送新活动通知。项目采用 TypeScript 开发,结合 grammY 框架与 Cloudflare Workers 平台,具备高扩展性与低运维成本。

项目结构

项目采用按功能模块划分的目录组织方式,核心入口位于 src/index.ts,命令路由与处理器集中在 src/command 下,客户端封装在 src/client 中,定时任务逻辑位于 src/scheduler。Wrangler 作为部署与配置工具,tsconfig 提供类型检查与编译选项,test 目录包含单元与集成测试。

graph TB
A["src/index.ts<br/>Worker 入口与 Webhook"] --> B["src/command/index.ts<br/>命令注册与对话插件"]
B --> C["src/command/handlers/*.ts<br/>命令处理器"]
A --> D["src/scheduler/index.ts<br/>定时任务"]
C --> E["src/client/cosmoe.ts<br/>Cosmoe API 客户端"]
F["wrangler.jsonc<br/>部署与触发器配置"] --> A
G["tsconfig.json<br/>TypeScript 编译配置"] --> A
H["test/index.spec.ts<br/>测试用例"] --> A

图表来源

  • src/index.ts
  • src/command/index.ts
  • src/client/cosmoe.ts
  • src/scheduler/index.ts
  • wrangler.jsonc
  • tsconfig.json
  • test/index.spec.ts

章节来源

  • src/index.ts
  • src/command/index.ts
  • wrangler.jsonc
  • tsconfig.json

核心组件

  • Worker 入口与 Webhook:负责初始化 Bot、注册命令菜单、设置 Webhook 回调,并在定时事件触发时执行调度逻辑。
  • 命令系统与对话插件:通过 grammY 的 conversations 插件实现多步交互式登录与状态持久化;统一注册各类命令与回调。
  • Cosmoe API 客户端:封装与 Cosmoe 平台的交互,包括认证、活动列表、活动详情、预约、历史、取消等接口。
  • 定时任务:周期性拉取活动列表,识别新增活动并向已登录用户发送通知。
  • 存储层:使用 Cloudflare KV 保存用户凭证与对话状态,确保跨实例一致性与可扩展性。

章节来源

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

架构总览

下图展示了从 Telegram 用户到 Cloudflare Workers、grammY、KV 存储与外部 Cosmoe API 的整体数据流与控制流。

sequenceDiagram
participant U as "Telegram 用户"
participant W as "Cloudflare Worker<br/>src/index.ts"
participant CMD as "命令系统<br/>src/command/index.ts"
participant CONV as "对话插件<br/>conversations"
participant KV as "KV 存储<br/>COSMOE_CREDENTIALS/COSMOE_STORAGE"
participant API as "Cosmoe API 客户端<br/>src/client/cosmoe.ts"
participant S as "定时任务<br/>src/scheduler/index.ts"
U->>W : 发送命令/消息
W->>CMD : 路由到对应处理器
CMD->>CONV : 进入对话如登录
CONV->>KV : 读写对话状态
CMD->>API : 调用 Cosmoe API
API-->>CMD : 返回结果
CMD-->>U : 发送回复/内联键盘
S->>API : 拉取活动列表
API-->>S : 返回活动数据
S->>KV : 读取/更新最新活动ID
S-->>U : 推送新活动通知

图表来源

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

详细组件分析

命令系统与对话插件

  • 组件职责
    • 注册命令菜单与路由:start、login、events、event{id}、book{event}{slot}、history、cancel{id}、callbackQuery 等。
    • 对话插件:基于 @grammyjs/conversations,使用 @grammyjs/storage-cloudflare 将对话状态持久化至 KV。
    • 环境绑定:通过 Env 接口注入 KV 命名空间与 Bot 配置。
  • 关键流程
    • 登录对话:交互式收集用户名与密码,调用 Cosmoe API 获取 token,存入 KV。
    • 预约流程:解析 /book{event}{slot},校验时段余量,支持优惠券选择与二次确认。
    • 取消流程:解析 /cancel_{id},弹出确认内联键盘,二次确认后调用取消接口。
  • 错误处理

    • 对话读写 KV 失败时记录日志并提示用户重试。
    • API 调用异常时捕获并反馈错误信息。

      flowchart TD
      Start(["进入命令处理"]) --> Route{"匹配命令/正则/回调"}
      Route --> |"/login"| LoginConv["进入登录对话"]
      Route --> |"/events"| EventsList["获取活动列表并展示"]
      Route --> |"/event_{id}"| EventDetail["获取活动详情并展示时段"]
      Route --> |"/book_{event}_{slot}"| BookFlow["校验余量/优惠券并下单"]
      Route --> |"/history"| History["获取并格式化历史记录"]
      Route --> |"/cancel_{id}"| CancelFlow["生成确认内联键盘"]
      Route --> |回调: 确认/优惠券选择| ConfirmOrCoupon["执行确认或优惠券选择"]
      LoginConv --> End(["结束"])
      EventsList --> End
      EventDetail --> End
      BookFlow --> End
      History --> End
      CancelFlow --> End
      ConfirmOrCoupon --> End
      

图表来源

  • src/command/index.ts
  • src/command/handlers/login.ts
  • src/command/handlers/events.ts
  • src/command/handlers/eventDetails.ts
  • src/command/handlers/bookEvent.ts
  • src/command/handlers/history.ts
  • src/command/handlers/cancel.ts

章节来源

  • src/command/index.ts
  • src/command/handlers/login.ts
  • src/command/handlers/events.ts
  • src/command/handlers/eventDetails.ts
  • src/command/handlers/bookEvent.ts
  • src/command/handlers/history.ts
  • src/command/handlers/cancel.ts

Cosmoe API 客户端

  • 组件职责
    • 封装认证、活动查询、详情获取、个人资料、预约、历史、取消、优惠券等 API。
    • 支持手动设置凭证与自动读取 KV 凭证。
  • 数据模型要点
    • 认证响应包含 user_id 与 token。
    • 活动详情包含多个时间段与剩余容量。
    • 预约返回包含最终价格与订单号等字段。
  • 错误处理

    • 未认证调用抛出错误;KV 读写失败记录日志并提示用户。

      classDiagram
      class CosmoeClient {
      +getToken(username, password)
      +setCredentials(userId, token)
      +getCredentials()
      +isAuthenticated()
      +getEvents()
      +getEventDetail(eventId)
      +getProfile()
      +getMyBookings()
      +bookEvent(bookingRequest)
      +getAvailableCoupons(eventId)
      +cancelBooking(bookingId)
      +updatePaymentOrder(bookingId, orderId)
      +updateBookingNote(bookingId, note)
      +selfReschedule(bookingId, newSlot)
      +selfTransfer(bookingId, recipient)
      +changePassword(current, new)
      +register(key, username, email, password, identity)
      }
      

图表来源

  • src/client/cosmoe.ts

章节来源

  • src/client/cosmoe.ts

定时任务与新活动通知

  • 组件职责
    • 每分钟检查一次新活动,对比上次最大活动 ID,向所有已登录用户推送通知。
    • 使用 KV 存储“最新活动ID”,保证幂等与去重。
  • 关键流程

    • 拉取活动列表 → 过滤新活动 → 遍历已登录用户 → 发送通知 → 更新最新活动ID。

      flowchart TD
      Tick["定时触发"] --> LoadLast["读取最新活动ID"]
      LoadLast --> Fetch["拉取活动列表"]
      Fetch --> Filter{"过滤新活动"}
      Filter --> |有| Notify["遍历已登录用户并发送通知"]
      Filter --> |无| End["结束"]
      Notify --> Update["更新最新活动ID"]
      Update --> End
      

图表来源

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

章节来源

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

存储与环境配置

  • KV 命名空间
    • COSMOE_CREDENTIALS:存储用户的认证凭证(user_id、token、timestamp)。
    • COSMOE_STORAGE:存储调度任务的“最新活动ID”等状态。
  • 环境变量
    • BOT_INFO、BOT_TOKEN:Bot 基本信息与令牌。
    • KV 绑定:通过 wrangler.jsonc 配置。

章节来源

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

依赖分析

  • 运行时依赖
    • grammY:Telegram Bot 框架,提供命令路由、回调、内联键盘等能力。
    • @grammyjs/conversations:对话插件,配合 KV 实现多步交互。
    • @grammyjs/storage-cloudflare:KV 适配器,用于对话状态持久化。
  • 开发依赖
    • wrangler:Cloudflare Workers 部署与本地开发工具。
    • vitest 与 @cloudflare/vitest-pool-workers:Workers 友好的测试框架。
    • typescript:类型系统与编译支持。
  • 项目脚本

    • dev/start:本地开发与调试。
    • deploy:部署到 Cloudflare Workers。
    • test:运行测试。
    • cf-typegen:生成 Cloudflare 类型定义。

      graph LR
      P["package.json"] --> G["grammy"]
      P --> C["@grammyjs/conversations"]
      P --> K["@grammyjs/storage-cloudflare"]
      P --> W["wrangler"]
      P --> V["vitest"]
      P --> T["typescript"]
      

图表来源

  • package.json

章节来源

  • package.json

性能考虑

  • 无服务器冷启动:Cloudflare Workers 在首次访问时可能产生冷启动延迟,建议通过常驻与合理拆分任务降低影响。
  • KV 读写:对话状态与用户凭证均使用 KV,注意批量读写与错误重试策略,避免阻塞主线程。
  • API 调用:对 Cosmoe API 的调用应尽量减少不必要的请求,例如在预约前先获取活动详情以校验时段。
  • 定时任务频率:当前每分钟触发一次,建议根据实际业务量调整 cron 表达式,避免过度轮询。
  • 消息长度限制:历史查询与活动详情需遵守 Telegram 的消息长度限制,必要时截断或分条发送。

故障排除指南

  • 登录失败
    • 检查用户名/密码是否正确,确认 Cosmoe API 返回码与消息。
    • 确认 KV 写入是否成功,查看日志输出。
  • 预约失败
    • 确认用户已登录且凭证有效。
    • 检查活动时段余量与优惠券可用性。
    • 查看 API 返回的错误信息并提示用户。
  • 取消失败
    • 确认预约状态允许取消,且未过期。
    • 检查回调数据解析与 KV 凭证有效性。
  • 新活动通知未送达
    • 检查定时任务是否正常触发与 KV 最新活动ID是否更新。
    • 确认已登录用户列表是否正确,关注用户拒收或账号异常情况。
  • 测试与本地调试
    • 使用 vitest 与 @cloudflare/vitest-pool-workers 运行测试。
    • 通过 wrangler dev 启动本地服务,结合日志定位问题。

章节来源

  • src/command/handlers/login.ts
  • src/command/handlers/bookEvent.ts
  • src/command/handlers/cancel.ts
  • src/scheduler/index.ts
  • test/index.spec.ts

结论

Cosmoe Bot 通过 Cloudflare Workers 与 grammY 的组合,构建了一个轻量、可扩展、易于维护的摄影活动预约机器人。其清晰的模块划分、完善的错误处理与定时通知机制,使其能够稳定支撑日常运营与用户交互。未来可在前端界面、支付对接与更细粒度的权限控制方面进一步增强用户体验与安全性。

附录

快速开始指南

  • 环境准备
    • 安装依赖:使用包管理器安装项目依赖。
    • 配置 Wrangler:在 wrangler.jsonc 中完善 KV 绑定、Bot 令牌与 Cron 触发器。
  • 本地开发
    • 启动本地服务:运行开发脚本,访问本地端口进行调试。
    • 运行测试:使用测试脚本验证核心流程。
  • 部署上线
    • 执行部署脚本,将 Worker 部署到 Cloudflare Workers。
    • 在 Telegram 中配置 Webhook 与命令菜单,完成机器人上线。

章节来源

  • package.json
  • wrangler.jsonc
  • src/index.ts
  • test/index.spec.ts