Telegram 集成.md 15 KB

Telegram 集成

本文引用的文件

  • src/index.ts
  • src/command/index.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/client/cosmoe.ts
  • src/scheduler/index.ts
  • wrangler.jsonc
  • package.json
  • tsconfig.json
  • vitest.config.mts
  • test/index.spec.ts

目录

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

简介

本项目为基于 Cloudflare Workers 的 Telegram Bot,采用 grammY 框架与 @grammyjs/conversations 插件实现对话式交互,结合 Cloudflare KV 存储完成用户会话与凭证持久化。Bot 提供命令系统(/start、/login、/events、/history、/logout)以及事件浏览、预约、取消等完整业务流程;通过计划任务实现新活动推送通知。

项目结构

  • 入口与运行环境
    • Worker 入口:src/index.ts,负责 Bot 初始化、命令菜单注册、Webhook 回调接入与定时任务调度。
    • 配置:wrangler.jsonc 定义 Worker 名称、兼容日期、触发器、KV 绑定与变量。
  • 命令系统
    • src/command/index.ts:安装 conversations 插件、注册命令与回调查询处理器。
    • 各命令处理器位于 src/command/handlers/ 下,按功能模块划分。
  • 客户端
    • src/client/cosmoe.ts:封装 Cosmoe API 客户端,统一认证、事件、预约、取消等接口。
  • 调度器
    • src/scheduler/index.ts:基于 Cron 触发,向已注册用户推送新活动通知。
  • 测试与类型

    • Vitest 配置与测试用例位于 test/ 与 vitest.config.mts。
    • 类型声明位于 worker-configuration.d.ts(在 tsconfig 中引入)。

      graph TB
      A["src/index.ts<br/>Worker 入口"] --> B["src/command/index.ts<br/>命令与对话注册"]
      B --> C["src/command/handlers/*.ts<br/>命令处理器"]
      C --> D["src/client/cosmoe.ts<br/>Cosmoe API 客户端"]
      A --> E["src/scheduler/index.ts<br/>计划任务"]
      F["wrangler.jsonc<br/>Worker 配置"] --> A
      G["package.json<br/>依赖与脚本"] --> A
      H["tsconfig.json<br/>TypeScript 配置"] --> A
      I["vitest.config.mts<br/>测试配置"] --> J["test/index.spec.ts<br/>单元/集成测试"]
      

图表来源

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

章节来源

  • src/index.ts
  • wrangler.jsonc
  • package.json
  • tsconfig.json
  • vitest.config.mts
  • test/index.spec.ts

核心组件

  • Bot 实例与 Webhook
    • 在入口中创建带对话风味的 Bot 实例,解析 botInfo 并注册命令菜单,最后通过 webhookCallback 将请求交由 grammY 处理。
  • 对话管理器(Conversations)
    • 使用 @grammyjs/conversations 与 @grammyjs/storage-cloudflare 的 KV 适配器,将对话状态持久化到 COSMOE_STORAGE。
    • 在命令注册处安装 conversations 插件,并定义交互式登录对话“login”。
  • 命令系统
    • 注册 /start、/login、/events、/history、/logout 等命令;对特定格式的消息(如 /event{id}、/book{eventid}{slotid}、/cancel{booking_id})使用 hears 与 callbackQuery 进行路由。
  • API 客户端
    • CosmoeClient 封装认证、事件列表、活动详情、预约、取消、历史等接口,支持设置/读取凭证与自动校验登录状态。
  • 计划任务
    • 通过 Cron 每分钟触发一次,对比最新事件 ID,向已注册用户发送新活动通知。

章节来源

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

架构总览

下图展示从 Telegram 请求到业务处理与外部 API 调用的整体流程。

sequenceDiagram
participant U as "用户"
participant T as "Telegram"
participant W as "Cloudflare Worker<br/>src/index.ts"
participant C as "命令系统<br/>src/command/index.ts"
participant H as "命令处理器<br/>handlers/*.ts"
participant K as "KV 存储<br/>COSMOE_CREDENTIALS/COSMOE_STORAGE"
participant API as "Cosmoe API<br/>src/client/cosmoe.ts"
U->>T : 发送命令/消息/回调
T->>W : HTTP 请求Webhook
W->>C : 转发至 grammY Bot
C->>H : 匹配命令/正则/回调
H->>K : 读写用户凭证/会话状态
H->>API : 调用认证/事件/预约/取消等接口
API-->>H : 返回业务数据
H-->>U : 发送消息/内联键盘/编辑消息

图表来源

  • src/index.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
  • src/client/cosmoe.ts

详细组件分析

Bot 初始化与 Webhook 接入

  • 创建带对话风味的 Bot 实例,注入 botInfo 与 token。
  • 注册命令菜单 setMyCommands,异常捕获避免部署失败。
  • 使用 webhookCallback("cloudflare-mod") 将请求交由 grammY 处理。

章节来源

  • src/index.ts

对话管理器(Conversations)与 KV 存储

  • 使用 @grammyjs/storage-cloudflare 的 KvAdapter 作为对话存储后端。
  • 自定义 KV 读写删除适配器,JSON 序列化对话状态。
  • 安装 conversations 插件并注册交互式登录对话“login”。

    flowchart TD
    Start(["进入对话"]) --> ReadKV["从 COSMOE_STORAGE 读取对话状态"]
    ReadKV --> State{"是否存在状态?"}
    State --> |否| Init["初始化状态"]
    State --> |是| Resume["恢复状态"]
    Init --> Run["执行对话步骤"]
    Resume --> Run
    Run --> Persist["写回 COSMOE_STORAGE"]
    Persist --> End(["结束对话"])
    

图表来源

  • src/command/index.ts

章节来源

  • src/command/index.ts

命令系统与路由

  • /start:欢迎语与可用命令提示。
  • /login:进入交互式登录对话,获取用户名/密码并调用 Cosmoe API 获取 token,存入 COSMOE_CREDENTIALS。
  • /events:获取最近活动列表,生成命令链接。
  • /event_{id}:显示活动详情与可预约时间段,含预约链接。
  • /book_{eventid}{slot_id}:根据索引选择时间段,处理优惠券选择与最终预约。
  • /history:获取用户预约历史,含取消链接。
  • /cancel_{booking_id}:发起取消确认,回调 confirmcancel* 或 cancel_action。
  • /logout:删除用户凭证。

章节来源

  • src/command/index.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

内联键盘与回调查询

  • 事件详情页:当时间段有余量且活动处于活跃期,为每个时间段生成“预约”链接。
  • 优惠券选择:多优惠券时以内联键盘列出,回调格式 selectcoupon{eventid}{slotindex}{coupon_code|none}。
  • 取消确认:内联键盘“确认/取消”,回调格式 confirmcancel{booking_id} 或 cancel_action。

    sequenceDiagram
    participant U as "用户"
    participant H as "事件详情处理器"
    participant KB as "内联键盘"
    participant CB as "回调处理器"
    U->>H : 发送 /event_{id}
    H-->>U : 返回活动详情与可预约时间段
    U->>KB : 点击“预约”
    KB-->>CB : 回调 /book_{event_id}_{slot_index}
    CB-->>U : 显示优惠券选择或直接预约
    

图表来源

  • src/command/handlers/eventDetails.ts
  • src/command/handlers/bookEvent.ts
  • src/command/handlers/cancel.ts

章节来源

  • src/command/handlers/eventDetails.ts
  • src/command/handlers/bookEvent.ts
  • src/command/handlers/cancel.ts

文件上传/下载与媒体资源

  • 当前代码未实现文件上传/下载逻辑。
  • 活动详情包含封面图与图集 URL,可在消息中直接展示或引导用户查看。

章节来源

  • src/command/handlers/eventDetails.ts
  • src/client/cosmoe.ts

错误处理与重试策略

  • 命令处理器普遍使用 try/catch 捕获异常并回复友好提示。
  • KV 读写与 API 调用均包含错误日志输出,便于定位问题。
  • 建议在关键路径增加指数退避重试与超时控制(当前未实现)。

章节来源

  • src/command/handlers/login.ts
  • src/command/handlers/events.ts
  • src/command/handlers/history.ts

用户体验优化

  • Markdown 格式化消息,突出关键信息(活动名、时间、价格、状态)。
  • 控制消息长度(历史记录限制),避免超出 Telegram API 限制。
  • 取消操作提供二次确认,降低误操作风险。

章节来源

  • src/command/handlers/history.ts
  • src/command/handlers/cancel.ts

计划任务与推送通知

  • Cron 每分钟触发一次,比较最新事件 ID,向所有已注册用户发送新活动通知。
  • 使用 bot.api.sendMessage 推送 Markdown 格式消息。

    flowchart TD
    S["Cron 触发"] --> L["读取最新事件ID"]
    L --> Q["拉取全部活动"]
    Q --> N{"存在新活动?"}
    N --> |否| E["结束"]
    N --> |是| U["遍历已注册用户"]
    U --> M["发送通知消息"]
    M --> R["更新最新事件ID"]
    R --> E
    

图表来源

  • src/scheduler/index.ts

章节来源

  • src/scheduler/index.ts

依赖关系分析

  • grammY 与 @grammyjs/conversations:提供 Bot 核心能力与对话管理。
  • @grammyjs/storage-cloudflare:KV 存储适配器,用于对话状态持久化。
  • Cloudflare KV:COSMOE_CREDENTIALS 存放用户凭证,COSMOE_STORAGE 存放对话状态与最新事件 ID。
  • Cosmoe API:通过 CosmoeClient 统一访问认证、事件、预约、取消、历史等接口。

    graph LR
    P["package.json 依赖"] --> G["grammy"]
    P --> C["@grammyjs/conversations"]
    P --> S["@grammyjs/storage-cloudflare"]
    G --> B["Bot 核心"]
    C --> V["对话插件"]
    S --> K["KV 适配器"]
    B --> H["命令/回调处理"]
    H --> X["CosmoeClient"]
    X --> A["Cosmoe API"]
    

图表来源

  • package.json

章节来源

  • package.json
  • wrangler.jsonc

性能考虑

  • KV 读写:对话状态与用户凭证频繁读写,建议在高并发场景下评估 KV 延迟与吞吐。
  • API 调用:事件列表与历史记录可能返回大量数据,注意分页与截断(当前已做截断)。
  • 消息长度:Markdown 消息超过阈值会被截断,确保用户体验一致。
  • 计划任务:每分钟触发一次,建议在大规模用户场景下优化遍历与发送逻辑。

故障排查指南

  • Webhook 未生效
    • 检查 Worker 是否正确暴露 fetch/scheduled 生命周期。
    • 确认 Wrangler 配置与部署状态。
  • 命令无响应
    • 查看 setMyCommands 是否成功执行(入口已捕获异常)。
    • 检查命令路由是否匹配(/event_、/book_、/cancel_)。
  • 登录失败
    • 确认 Cosmoe API 返回 code=200 且包含 user_id/token。
    • 检查 KV 写入是否成功(COSMOE_CREDENTIALS)。
  • 预约/取消异常
    • 检查回调数据格式与解析逻辑。
    • 确认 CosmoeClient 已设置正确的凭证。
  • 计划任务未推送
    • 检查 Cron 配置与 scheduled 生命周期。
    • 确认 KV 中已存在用户键并可被枚举。

章节来源

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

结论

本项目以 grammY 为核心,结合 @grammyjs/conversations 与 Cloudflare KV,构建了完整的 Telegram Bot 业务闭环:从命令交互、内联键盘、回调处理到外部 API 调用与计划任务推送。建议后续增强错误重试、超时控制与限流策略,以提升稳定性与用户体验。

附录

  • 部署与开发
    • 使用 Wrangler 部署与本地开发,脚本已在 package.json 中定义。
    • Vitest 配置指向 wrangler.jsonc,便于集成测试。
  • 类型与配置
    • tsconfig.json 启用严格模式与 isolatedModules,确保类型安全。
    • worker-configuration.d.ts 由 tsconfig 引入,提供 Cloudflare Worker 类型支持。

章节来源

  • package.json
  • vitest.config.mts
  • tsconfig.json
  • test/index.spec.ts