新命令开发.md 16 KB

新命令开发

本文档引用的文件

  • 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

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖分析
  7. 性能考虑
  8. 故障排除指南
  9. 结论
  10. 附录:新命令开发完整流程

简介

本指南面向希望为现有命令系统添加新命令的开发者,涵盖命令注册流程、参数解析方法、业务逻辑实现步骤、命令路由机制(command() 与 hears() 的使用场景与区别)、错误处理策略以及用户交互最佳实践。文档以项目现有实现为蓝本,提供可直接参考的扩展示例,帮助快速完成新命令的开发与集成。

项目结构

该项目基于 grammY 框架与 Cloudflare Workers 运行时,采用模块化组织方式:

  • 入口文件负责初始化 Bot 并设置命令菜单
  • 命令注册集中于命令模块,统一管理所有命令与回调
  • 命令处理器按功能拆分至 handlers 目录
  • 客户端封装对第三方 API 的调用

    graph TB
    A["入口: src/index.ts"] --> B["命令注册: src/command/index.ts"]
    B --> C["命令处理器: src/command/handlers/*.ts"]
    C --> D["客户端: src/client/cosmoe.ts"]
    A --> E["Cloudflare 环境变量"]
    

图表来源

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

章节来源

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

核心组件

  • Bot 初始化与 Webhook 回调:入口文件创建 Bot 实例,配置命令菜单,并通过 Cloudflare Worker 的 webhookCallback 接收外部请求。
  • 命令注册中心:命令模块集中导入各处理器,使用 bot.command() 与 bot.hears() 注册命令与模式匹配事件,并安装对话插件支持多步交互。
  • 命令处理器:每个处理器负责单一职责,处理参数、调用客户端 API、构建响应消息并进行错误处理。
  • 客户端封装:CosmoeClient 提供认证、活动查询、预约、取消等 API 调用,统一返回格式与错误处理。

章节来源

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

架构总览

下图展示了从用户触发命令到业务处理与响应的完整流程,以及命令路由机制的差异。

sequenceDiagram
participant U as "用户"
participant W as "Cloudflare Webhook"
participant B as "Bot 实例"
participant R as "命令路由"
participant H as "命令处理器"
participant C as "CosmoeClient"
participant API as "第三方 API"
U->>W : "发送消息/命令"
W->>B : "webhookCallback 分发"
B->>R : "根据路由规则匹配"
alt "命令路由 : bot.command()"
R->>H : "调用对应处理器"
else "模式路由 : bot.hears()"
R->>H : "正则匹配后调用处理器"
else "回调路由 : bot.callbackQuery()"
R->>H : "回调数据解析后调用处理器"
end
H->>C : "调用客户端 API"
C->>API : "HTTP 请求"
API-->>C : "返回结果"
C-->>H : "标准化结果"
H-->>U : "发送响应消息"

图表来源

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

详细组件分析

命令注册与路由机制

  • bot.command("命令名", 处理器):用于标准命令触发,例如 /start、/login、/events、/history、/logout。
  • bot.hears(正则表达式, 处理器):用于模式匹配的消息触发,例如 /event{id}、/book{eventid}{slotid}、/cancel{booking_id}。
  • bot.callbackQuery(正则表达式, 处理器):用于内联键盘回调,例如确认取消、选择优惠券等。

    flowchart TD
    Start(["收到消息"]) --> Type{"消息类型"}
    Type --> |命令| Cmd["bot.command() 匹配"]
    Type --> |文本/正则| Hears["bot.hears() 匹配"]
    Type --> |回调| CB["bot.callbackQuery() 匹配"]
    Cmd --> Handler["调用对应处理器"]
    Hears --> Handler
    CB --> Handler
    Handler --> End(["发送响应"])
    

图表来源

  • src/command/index.ts

章节来源

  • src/command/index.ts

参数解析与业务逻辑实现步骤

  • 解析上下文参数:从 ctx.from、ctx.message、ctx.match、ctx.callbackQuery.data 等提取必要信息。
  • 数据校验:检查用户身份、登录状态、参数有效性、业务约束(如时间范围、库存)。
  • 调用客户端 API:通过 CosmoeClient 执行业务操作,统一处理返回码与错误信息。
  • 构建响应消息:使用 Markdown 或纯文本格式,注意长度限制与 Telegram API 限制。
  • 错误处理:捕获异常、记录日志、向用户反馈错误信息。

章节来源

  • 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/login.ts
  • src/command/handlers/logout.ts

命令处理器示例分析

启动命令处理器

  • 功能:向用户展示可用命令列表。
  • 关键点:使用 ctx.reply 发送文本;适合简单无状态命令。

章节来源

  • src/command/handlers/start.ts

事件列表命令处理器

  • 功能:拉取最新活动并生成列表链接。
  • 关键点:调用 CosmoeClient.getEvents;限制数量;Markdown 格式化;错误兜底。

章节来源

  • src/command/handlers/events.ts

事件详情与预约命令处理器

  • 功能:解析 /event{id} 与 /book{eventid}{slot_id},展示时间槽并支持优惠券选择。
  • 关键点:正则匹配参数;KV 存储用户凭证;调用 getEventDetail 与 getAvailableCoupons;内联键盘与回调处理;Markdown 格式化;库存与时间判断。

    sequenceDiagram
    participant U as "用户"
    participant B as "Bot"
    participant ED as "事件详情处理器"
    participant BE as "预约处理器"
    participant C as "CosmoeClient"
    participant API as "第三方 API"
    U->>B : "/event_123"
    B->>ED : "匹配 /event_{id}"
    ED->>C : "getEventDetail(id)"
    C->>API : "请求"
    API-->>C : "返回活动详情"
    C-->>ED : "返回数据"
    ED-->>U : "发送活动详情与可预约链接"
    U->>B : "/book_123_0"
    B->>BE : "匹配 /book_{event_id}_{slot_id}"
    BE->>C : "getEventDetail(eventId)"
    C-->>BE : "返回数据"
    BE->>BE : "检查库存与优惠券"
    alt "多个优惠券"
    BE-->>U : "显示优惠券选择键盘"
    U->>B : "回调 : select_coupon_123_0_xxx"
    B->>BE : "解析回调"
    BE->>C : "bookEvent(couponCode)"
    else "单个/无优惠券"
    BE->>C : "bookEvent()"
    end
    C-->>BE : "返回结果"
    BE-->>U : "发送预约结果"
    

图表来源

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

章节来源

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

预约历史与取消命令处理器

  • 功能:读取用户凭证,查询预约历史,生成 Markdown 列表,并提供取消链接与确认回调。
  • 关键点:KV 读写凭证;认证校验;排序与截断;贝时拼接与比较;内联键盘确认;回调解析与状态更新。

    sequenceDiagram
    participant U as "用户"
    participant B as "Bot"
    participant HC as "历史处理器"
    participant CC as "取消处理器"
    participant C as "CosmoeClient"
    participant API as "第三方 API"
    U->>B : "/history"
    B->>HC : "调用历史处理器"
    HC->>HC : "KV 读取凭证"
    HC->>C : "getMyBookings()"
    C-->>HC : "返回历史数据"
    HC-->>U : "发送历史列表(含取消链接)"
    U->>B : "/cancel_456"
    B->>CC : "匹配 /cancel_{booking_id}"
    CC->>C : "getMyBookings() 确认"
    CC-->>U : "发送确认键盘"
    U->>B : "回调 : confirm_cancel_456"
    B->>CC : "解析回调"
    CC->>C : "cancelBooking(456)"
    C-->>CC : "返回结果"
    CC-->>U : "编辑消息为取消结果"
    

图表来源

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

章节来源

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

登录与登出命令处理器

  • 功能:登录采用对话式多步交互,登出清理 KV 中的凭证。
  • 关键点:对话插件与 KV 适配器;凭证持久化;错误处理与提示。

章节来源

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

客户端 API 封装

CosmoeClient 统一封装了认证、活动、预约、取消、转账、改密等 API,提供一致的返回格式与错误处理,便于命令处理器复用。

章节来源

  • src/client/cosmoe.ts

依赖分析

  • grammY:核心框架,提供 Bot、Context、InlineKeyboard、callbackQuery 等能力。
  • @grammyjs/conversations:对话插件,支持多步交互与状态存储。
  • @grammyjs/storage-cloudflare:KV 存储适配器,用于会话状态持久化。
  • Cloudflare Workers:运行时环境,提供 KVNamespace、Webhook 回调等。

    graph TB
    Pkg["package.json 依赖"] --> G["grammy"]
    Pkg --> Conv["@grammyjs/conversations"]
    Pkg --> KV["@grammyjs/storage-cloudflare"]
    G --> Bot["Bot/Context"]
    Conv --> Conversations["对话插件"]
    KV --> Storage["KV 适配器"]
    

图表来源

  • package.json

章节来源

  • package.json

性能考虑

  • 消息长度控制:历史与详情消息可能较长,需限制长度避免 Telegram API 限制。
  • KV 访问优化:尽量减少 KV 读写次数,合并请求或缓存必要数据。
  • 异步并发:合理使用异步调用,避免阻塞主线程。
  • 错误快速失败:在参数无效或状态不满足时尽早返回,减少无效请求。

故障排除指南

  • 命令未生效:检查命令是否在入口文件中设置命令菜单,以及命令注册是否正确导入。
  • 参数解析失败:确认正则表达式与 ctx.match 是否匹配预期格式。
  • 凭证问题:检查 KV 中是否存在用户凭证,登录状态是否有效。
  • API 返回异常:查看客户端封装的错误处理与返回码,确保统一处理。
  • 回调无响应:确认回调查询与回调处理器的正则匹配一致,并正确调用 answerCallbackQuery。

章节来源

  • src/index.ts
  • src/command/index.ts
  • src/command/handlers/history.ts
  • src/command/handlers/bookEvent.ts

结论

通过统一的命令注册中心与清晰的处理器职责划分,项目实现了可扩展的命令系统。新增命令应遵循现有模式:在命令模块中注册路由,在 handlers 目录中实现处理器,利用 CosmoeClient 封装 API,严格进行参数校验与错误处理,并通过 Markdown 等格式提升用户体验。

附录:新命令开发完整流程

第一步:设计命令与参数

  • 明确命令名称与用途(如 /admin_stats)。
  • 设计参数格式与可选参数,决定使用 bot.command() 还是 bot.hears()。
  • 规划用户交互流程(是否需要内联键盘或对话)。

第二步:创建处理器文件

  • 在 src/command/handlers 下新建处理器文件,导出异步处理函数。
  • 处理函数签名建议:handleXxxCommand(ctx, env?),其中 env 可选用于访问 KV 等资源。

章节来源

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

第三步:实现业务逻辑

  • 解析参数:从 ctx.from、ctx.message、ctx.match、ctx.callbackQuery.data 获取必要信息。
  • 校验输入:检查用户身份、登录状态、参数合法性。
  • 调用客户端:通过 CosmoeClient 执行业务操作。
  • 构建响应:使用 Markdown 或纯文本,注意长度限制与格式规范。

章节来源

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

第四步:注册命令路由

  • 在命令模块中导入新处理器。
  • 使用 bot.command() 或 bot.hears() 注册路由,必要时使用 bot.callbackQuery() 注册回调。
  • 如需对话交互,使用 conversations 插件与 createConversation 包裹处理器。

章节来源

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

第五步:设置命令菜单

  • 在入口文件中调用 bot.api.setMyCommands 设置命令菜单,确保用户可见。

章节来源

  • src/index.ts

第六步:错误处理与测试

  • 添加 try-catch 捕获异常,记录日志并友好提示用户。
  • 编写单元测试覆盖正常与异常路径。
  • 在本地与生产环境中验证命令行为。

章节来源

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

示例:添加一个“管理员统计”命令

  • 命令设计:/admin_stats,仅管理员可用,返回预约统计与用户活跃度。
  • 参数:可选日期范围(YYYY-MM-DD),默认最近7天。
  • 路由:使用 bot.command() 注册。
  • 处理器:解析参数、校验管理员权限、调用客户端统计接口、构建 Markdown 表格并发送。
  • 回调:如需分页或筛选,使用内联键盘与回调处理。

章节来源

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