# 回调查询处理
**本文引用的文件**
- [src/index.ts](file://src/index.ts)
- [src/command/index.ts](file://src/command/index.ts)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts)
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件系统化阐述 Telegram 机器人中“回调查询(Callback Query)”的处理机制,重点覆盖以下方面:
- 确认取消与优惠券选择两类回调的触发、路由与处理流程
- 正则表达式匹配模式的语义解析:confirm_cancel_\d+、cancel_action、select_coupon_\d+_\d+_\w+
- 回调查询与对话系统(Conversations)的集成方式
- 安全性考虑与最佳实践
- 调试与监控方法
## 项目结构
该机器人采用模块化的命令注册与处理器组织方式,回调查询在命令入口集中注册,并通过正则表达式分发到具体处理器。关键文件如下:
- 入口与 Webhook:src/index.ts
- 命令与回调注册:src/command/index.ts
- 预约与优惠券选择处理:src/command/handlers/bookEvent.ts
- 取消预约与确认处理:src/command/handlers/cancel.ts
- 第三方 API 客户端:src/client/cosmoe.ts
```mermaid
graph TB
A["src/index.ts
创建 Bot 并设置命令菜单"] --> B["src/command/index.ts
注册命令与回调查询"]
B --> C["src/command/handlers/cancel.ts
取消命令与确认回调"]
B --> D["src/command/handlers/bookEvent.ts
预约与优惠券选择回调"]
D --> E["src/client/cosmoe.ts
Cosmoe API 客户端"]
C --> E
```
图表来源
- [src/index.ts](file://src/index.ts#L13-L35)
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L1-L226)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L1-L132)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
章节来源
- [src/index.ts](file://src/index.ts#L1-L47)
- [src/command/index.ts](file://src/command/index.ts#L1-L110)
## 核心组件
- Bot 实例与 Webhook:入口文件创建 Bot 并启用 Cloudflare Worker 的 webhook 回调适配器,同时设置命令菜单。
- 命令与回调注册:命令入口安装对话插件(Conversations),并注册各类命令与回调查询处理器。
- 取消流程回调:针对 confirm_cancel_{booking_id} 与 cancel_action 的回调查询进行处理。
- 优惠券选择回调:针对 select_coupon_{event_id}_{slot_index}_{coupon_code_or_none} 的回调查询进行处理。
- API 客户端:封装对第三方服务的调用,包括获取活动详情、查询可用优惠券、取消预约等。
章节来源
- [src/index.ts](file://src/index.ts#L13-L35)
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L1-L226)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L1-L132)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
## 架构总览
回调查询处理的整体流程如下:
- 用户点击内联键盘按钮触发回调查询
- Bot 根据回调数据的前缀与格式匹配正则表达式
- 将回调数据交由对应处理器执行业务逻辑
- 使用 answerCallbackQuery 进行响应,避免 Telegram 显示“加载中”
- 对于需要更新消息的场景,使用 editMessageText 更新确认提示或选择结果
```mermaid
sequenceDiagram
participant U as "用户"
participant B as "Bot(grammy)"
participant R as "回调路由"
participant H1 as "取消确认处理器"
participant H2 as "优惠券选择处理器"
participant API as "CosmoeClient"
U->>B : 点击内联键盘按钮
B->>R : 分发回调查询
alt 匹配 confirm_cancel_\\d+ 或 cancel_action
R->>H1 : 调用取消确认处理器
H1->>API : 取消预约
API-->>H1 : 返回结果
H1-->>U : 编辑消息反馈
else 匹配 select_coupon_\\d+_\\d+_\\w+
R->>H2 : 调用优惠券选择处理器
H2->>API : 获取活动详情/执行预约
API-->>H2 : 返回结果
H2-->>U : 编辑消息反馈
end
R->>B : 调用 answerCallbackQuery
```
图表来源
- [src/command/index.ts](file://src/command/index.ts#L91-L105)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L86-L132)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L159-L226)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L247-L422)
## 详细组件分析
### 回调查询路由与匹配规则
- 取消确认回调路由
- 正则:confirm_cancel_\\d+|cancel_action
- 触发条件:按钮数据以 confirm_cancel_{booking_id} 开头,或为 cancel_action
- 处理流程:解析 booking_id,校验用户凭证,调用取消接口,编辑消息反馈结果
- 优惠券选择回调路由
- 正则:select_coupon_\\d+_\\d+_\\w+
- 触发条件:按钮数据以 select_coupon_{event_id}_{slot_index}_{coupon_code_or_none} 形式
- 处理流程:解析 event_id、slot_index、coupon_code,校验用户凭证,获取活动详情,执行预约,编辑消息反馈结果
章节来源
- [src/command/index.ts](file://src/command/index.ts#L91-L105)
### 确认取消回调逻辑
- 触发来源:取消命令生成的内联键盘,包含“确认”和“取消”两个按钮
- 数据格式:confirm_cancel_{booking_id}、cancel_action
- 处理要点:
- 解析 action 字符串,区分 confirm_cancel 与 cancel_action
- 从 KV 中读取用户凭证,校验认证状态
- 调用取消接口,根据返回结果编辑消息提示
- 使用 answerCallbackQuery 清除加载态
```mermaid
flowchart TD
Start(["收到回调查询"]) --> Parse["解析 action 字符串"]
Parse --> Type{"类型判断"}
Type --> |confirm_cancel_*| Validate["校验用户凭证"]
Validate --> CancelAPI["调用取消接口"]
CancelAPI --> Result{"返回码为 200?"}
Result --> |是| EditSuccess["编辑消息:成功"]
Result --> |否| EditFail["编辑消息:失败"]
Type --> |cancel_action| EditCancel["编辑消息:已取消"]
EditSuccess --> Done(["结束"])
EditFail --> Done
EditCancel --> Done
```
图表来源
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L86-L132)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L405-L422)
章节来源
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L1-L132)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L405-L422)
### 优惠券选择回调逻辑
- 触发来源:预约流程中存在多个可用优惠券时,展示选择键盘
- 数据格式:select_coupon_{event_id}_{slot_index}_{coupon_code_or_none}
- 处理要点:
- 解析 action,提取 event_id、slot_index、coupon_code(none 表示不使用)
- 从 KV 中读取用户凭证,校验认证状态
- 获取活动详情与时间槽,校验索引有效性
- 编辑消息显示所选优惠券,随后执行预约并反馈结果
- 使用 answerCallbackQuery 清除加载态
```mermaid
flowchart TD
Start(["收到回调查询"]) --> Parse["解析 action 字符串"]
Parse --> Extract["提取 event_id/slot_index/coupon_code"]
Extract --> Validate["校验用户凭证与活动详情"]
Validate --> FetchSlots["获取并排序时间槽"]
FetchSlots --> CheckIdx{"slot_index 有效?"}
CheckIdx --> |否| EditErr["编辑消息:无效时间段"]
CheckIdx --> |是| ShowSel["编辑消息:显示所选优惠券"]
ShowSel --> Book["执行预约可带 coupon_code"]
Book --> Result{"返回码为 200?"}
Result --> |是| EditOk["编辑消息:成功并显示最终价格/编号"]
Result --> |否| EditErr2["编辑消息:失败"]
EditErr --> Done(["结束"])
EditErr2 --> Done
EditOk --> Done
```
图表来源
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L159-L226)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L191-L270)
章节来源
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L1-L226)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L191-L270)
### 回调查询与对话系统的集成
- 对话插件安装:命令入口安装 conversations 插件,并使用 KV 存储对话状态
- 登录对话:通过 createConversation 创建交互式登录对话,便于后续流程复用
- 回调处理中的对话:回调处理器内部不直接进入对话,而是基于 KV 凭证与 API 客户端完成业务处理
- 存储与恢复:对话状态通过 KVAdapter 读写,确保跨请求的状态一致性
```mermaid
graph LR
Cfg["对话配置
KVAdapter + conversations"] --> KV["COSMOE_STORAGE KV"]
LoginConv["登录对话"] --> KV
CancelHandler["取消处理器"] --> KV
CouponHandler["优惠券处理器"] --> KV
```
图表来源
- [src/command/index.ts](file://src/command/index.ts#L20-L57)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L1-L132)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L1-L226)
章节来源
- [src/command/index.ts](file://src/command/index.ts#L20-L57)
### 正则表达式匹配模式解析
- confirm_cancel_\\d+
- 含义:以 confirm_cancel_ 开头,后接一个或多个数字(表示预约 ID)
- 用途:用于取消确认的回调
- cancel_action
- 含义:固定字符串,表示用户选择“取消”操作
- 用途:用于取消确认的回调
- select_coupon_\\d+_\\d+_\\w+
- 含义:以 select_coupon_ 开头,后接事件 ID、下划线、时间段索引、下划线、优惠券代码或 none
- 用途:用于优惠券选择的回调
章节来源
- [src/command/index.ts](file://src/command/index.ts#L91-L105)
## 依赖关系分析
- 模块耦合
- 回调路由集中在命令入口注册,处理器之间低耦合,职责清晰
- 处理器依赖 API 客户端,API 客户端依赖第三方服务
- 外部依赖
- grammy:Telegram Bot SDK
- @grammyjs/conversations:对话插件
- @grammyjs/storage-cloudflare:KV 存储适配器
- 关键依赖链
- 回调查询 -> 路由 -> 处理器 -> API 客户端 -> 第三方服务
- 对话状态 -> KV 存储 -> KV 命名空间
```mermaid
graph TB
Q["回调查询"] --> M["回调路由"]
M --> H1["取消处理器"]
M --> H2["优惠券处理器"]
H1 --> K["KV 凭证/COSMOE_CREDENTIALS"]
H2 --> K
H1 --> A["CosmoeClient"]
H2 --> A
A --> S["第三方服务"]
```
图表来源
- [src/command/index.ts](file://src/command/index.ts#L91-L105)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L1-L132)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L1-L226)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
章节来源
- [src/command/index.ts](file://src/command/index.ts#L1-L110)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
## 性能考量
- 回调查询处理应尽量短小精悍,避免阻塞
- 使用 answerCallbackQuery 快速响应,减少 Telegram 端“加载中”提示
- 对外 API 调用建议异步并发控制,避免频繁请求导致超时
- 对 KV 读写进行必要的缓存与去重,降低 KV 访问频率
- 在高频场景下,可考虑对回调数据进行幂等设计,避免重复处理
## 故障排查指南
- 回调无响应
- 检查回调路由是否正确注册(正则匹配)
- 确认 answerCallbackQuery 是否被调用
- 权限不足或凭证缺失
- 检查 KV 中是否存在用户凭证
- 确认凭证是否过期或被删除
- 业务异常
- 查看处理器日志输出,定位具体步骤
- 核对第三方服务返回码与消息
- 消息未更新
- 确认 editMessageText 的调用时机与目标消息 ID
- 检查内联键盘是否仍存在(按钮点击后可能失效)
章节来源
- [src/command/index.ts](file://src/command/index.ts#L91-L105)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L86-L132)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L159-L226)
## 结论
本项目的回调查询处理通过明确的正则路由与清晰的处理器职责,实现了“确认取消”和“优惠券选择”的完整闭环。结合对话插件与 KV 存储,既保证了用户体验,也确保了状态管理的一致性。建议在生产环境中强化日志与监控,完善错误处理与重试策略,持续优化第三方服务调用的稳定性与性能。
## 附录
- 安全最佳实践
- 对回调数据进行严格的格式校验与长度限制
- 对关键操作(取消、支付)增加二次确认与权限校验
- 对 KV 读写进行访问控制与审计
- 对外 API 调用增加超时与重试策略
- 调试与监控
- 在处理器中记录关键参数与返回值
- 使用日志平台聚合回调处理日志
- 对高频回调进行采样与告警阈值设置