本文档引用的文件
本项目是一个基于 Cloudflare Workers 的 Telegram 机器人,提供用户认证与活动预约功能。认证系统采用交互式对话完成用户名/密码登录,通过 Cosmoe API 获取 Token 并持久化到 KV 存储;后续需要授权的操作(如查看历史、预约活动)均需使用已存储的凭证进行鉴权。系统未实现中间件层,而是通过各命令处理器在执行前主动检查凭证有效性。
项目采用按职责分层的组织方式:
配置:wrangler.jsonc 定义 Worker 名称、触发器、KV 绑定等运行时配置
graph TB
A["入口: src/index.ts"] --> B["命令注册: src/command/index.ts"]
B --> C["登录处理器: src/command/handlers/login.ts"]
B --> D["登出处理器: src/command/handlers/logout.ts"]
B --> E["历史查询: src/command/handlers/history.ts"]
B --> F["活动预约: src/command/handlers/bookEvent.ts"]
B --> G["活动列表: src/command/handlers/events.ts"]
B --> H["活动详情: src/command/handlers/eventDetails.ts"]
C --> I["认证客户端: src/client/cosmoe.ts"]
D --> I
E --> I
F --> I
G --> I
H --> I
A --> J["配置: wrangler.jsonc"]
B --> K["依赖: package.json"]
图表来源
章节来源
章节来源
下图展示了认证系统的关键交互路径:用户通过 /login 进入对话,输入凭据后由认证客户端向外部 API 请求 Token,并将凭证存入 KV;后续命令在执行前从 KV 读取凭证并设置到认证客户端以完成鉴权。
sequenceDiagram
participant U as "用户"
participant T as "Telegram Bot"
participant L as "登录处理器(login.ts)"
participant C as "认证客户端(cosmoe.ts)"
participant KV as "KV存储(COSMOE_CREDENTIALS)"
participant API as "Cosmoe API"
U->>T : "/login"
T->>L : 进入对话
L->>U : "请输入用户名"
U-->>L : 用户名
L->>U : "请输入密码"
U-->>L : 密码
L->>C : getToken(用户名, 密码)
C->>API : POST /CreatToken.php
API-->>C : 返回 {code, data : {user_id, token}}
C-->>L : 认证结果
alt 成功
L->>KV : put(Telegram用户ID, {user_id, token, timestamp})
L-->>U : "登录成功,凭证已存储"
else 失败
L-->>U : "登录失败:用户名或密码错误"
end
图表来源
章节来源
异常处理:捕获并记录错误,向用户反馈“稍后重试”
flowchart TD
Start(["进入登录对话"]) --> AskUser["提示输入用户名"]
AskUser --> GetUser["等待用户名输入"]
GetUser --> CheckUser{"用户名存在?"}
CheckUser --> |否| Cancel1["取消登录并提示"]
CheckUser --> |是| AskPass["提示输入密码"]
AskPass --> GetPass["等待密码输入"]
GetPass --> CheckPass{"密码存在?"}
CheckPass --> |否| Cancel2["取消登录并提示"]
CheckPass --> |是| CallAPI["调用getToken获取Token"]
CallAPI --> Result{"code=200且有token?"}
Result --> |是| SaveKV["以Telegram用户ID为键保存凭证到KV"]
SaveKV --> Done(["回复登录成功"])
Result --> |否| Fail(["回复登录失败"])
Cancel1 --> End(["结束"])
Cancel2 --> End
Done --> End
Fail --> End
图表来源
章节来源
认证状态:认证客户端提供 isAuthenticated 与 getCredentials 方法用于判断与获取当前凭证
classDiagram
class CosmoeClient {
-number userId
-string token
+getToken(username, password) ApiResponse
+setCredentials(userId, token) void
+getCredentials() {userId, token}|null
+isAuthenticated() boolean
}
class LoginHandler {
+handleInteractiveLogin(conversation, ctx, env) Promise
}
class HistoryHandler {
+handleHistoryCommand(ctx, env) Promise
}
class BookEventHandler {
+handleBookEvent(ctx, env) Promise
}
LoginHandler --> CosmoeClient : "获取Token并设置凭证"
HistoryHandler --> CosmoeClient : "读取凭证并调用受保护接口"
BookEventHandler --> CosmoeClient : "读取凭证并调用受保护接口"
图表来源
章节来源
反馈与异常:统一回复与错误日志记录
sequenceDiagram
participant U as "用户"
participant T as "Telegram Bot"
participant LO as "登出处理器(logout.ts)"
participant KV as "KV存储(COSMOE_CREDENTIALS)"
U->>T : "/logout"
T->>LO : 处理登出请求
LO->>LO : 获取Telegram用户ID
LO->>KV : get(用户ID)
alt 无凭证
LO-->>U : "请先使用 /login 命令登录"
else 有凭证
LO->>KV : delete(用户ID)
LO-->>U : "成功登出,账户信息已清除"
end
图表来源
章节来源
最佳实践:对敏感操作(如变更密码、取消预约)在处理器内部再次校验认证状态,确保安全性
flowchart TD
Enter(["进入受保护操作"]) --> ReadKV["从KV读取凭证"]
ReadKV --> Parse{"解析成功?"}
Parse --> |否| PromptLogin["提示先登录"]
Parse --> |是| SetCreds["设置到认证客户端"]
SetCreds --> CheckAuth{"isAuthenticated()?"}
CheckAuth --> |否| PromptReauth["提示凭证无效并重新登录"]
CheckAuth --> |是| CallAPI["调用受保护接口"]
CallAPI --> Resp{"返回code=200?"}
Resp --> |是| Success(["处理成功响应"])
Resp --> |否| ShowErr(["显示错误消息"])
PromptLogin --> End(["结束"])
PromptReauth --> End
Success --> End
ShowErr --> End
图表来源
章节来源
[本节为通用建议,无需特定文件引用]
[本节为概念性说明,无需特定文件引用]
内部依赖:命令处理器依赖认证客户端;登录/登出/历史/预约处理器共同依赖 KV 存储
graph LR
P["package.json"] --> G["grammy"]
P --> C["@grammyjs/conversations"]
P --> S["@grammyjs/storage-cloudflare"]
W["wrangler.jsonc"] --> KV1["COSMOE_CREDENTIALS"]
W --> KV2["COSMOE_STORAGE"]
CMD["命令注册(command/index.ts)"] --> H1["login.ts"]
CMD --> H2["logout.ts"]
CMD --> H3["history.ts"]
CMD --> H4["bookEvent.ts"]
CMD --> H5["events.ts"]
CMD --> H6["eventDetails.ts"]
H1 --> CL["cosmoe.ts"]
H2 --> CL
H3 --> CL
H4 --> CL
H5 --> CL
H6 --> CL
CL --> API["Cosmoe API"]
图表来源
章节来源
[本节提供一般性指导,无需特定文件引用]
章节来源
本认证系统通过交互式对话完成登录,使用 KV 存储凭证并在受保护操作前进行状态检查,整体流程清晰、易于维护。建议后续引入中间件统一鉴权、增加凭证过期与自动刷新机制,并完善错误日志与监控,以进一步提升安全性与用户体验。