面向运营/客服:按「用户看到什么 → 怎么排查 → 怎么处置」编排;文案按源码整理,数字由场景推演得出。
| 场景 | 用户看到 | 出处 | 矩阵中的组合数 |
|---|---|---|---|
| 目录提示(添加页签顶部) | “这里只列公开开放的、且还没添加的。目录收录不代表一定能对话 —— 平台只会给已接入连接器的机器人转发消息。” | AddAgentBubble.vue | 矩阵 A 段:目录可见 48 种组合,其余 384 种不出现 |
| 卡片标签:需邀请码 | “需邀请码”(仅 review 且非我创建) | AddAgentBubble.vue | 目录中 review 组合 24 条 |
| 卡片标签:未接入连接器 | “未接入连接器” + “无法添加”按钮(禁用) | AddAgentBubble.vue | 目录可见但 connector 未注册 |
| 卡片标签:你创建的 | “你创建的” + 按钮“重新添加” | AddAgentBubble.vue | owner 自己的机器人 |
| 服务端:私密无码 | 403「该机器人是私密的,需要邀请码」 | joinPolicy.canJoin | B 段 need_invite 类 2 条(另有带码组合走放行) |
| 服务端:需要邀请码 | 403「该机器人需要邀请码才能加入」 | joinPolicy.canJoin | review 无码 |
| 服务端:邀请码过期 | 403「邀请码已于 YYYY-MM-DD HH:mm 过期,请向创建者要一个新的」 | joinPolicy.canJoin / remote.js | 矩阵 8 条(拒 6 + 预校验 2) |
| 服务端:邀请码被作废 | 403「这个邀请码已失效(被作废或被换掉了),请向创建者要一个新的」 | joinPolicy.canJoin / remote.js | 矩阵 8 条(拒 6 + 预校验 2) |
| 服务端:邀请码无效(凭码入口) | 403「邀请码无效或已作废」 | remote.js bindings/join | 矩阵 48 条 |
| 服务端:被拉黑 | 403「你已被移出这台机器人,且被禁止再次加入(如需恢复请联系创建者)」 | joinPolicy.canJoin | 矩阵 102 条(申请/发送/预校验) |
| 服务端:机器人已退役 | 404「机器人已下架(已退役),无法再加入」 | joinPolicy.canJoin(D065 P1) | 矩阵 84 条(拒 60 + 预校验 24) |
| 服务端:机器人不存在 | 404「机器人不存在」;预校验「机器人不存在了(可能已被删除)」 | routes/agents.js / remote.js | 不在矩阵(333 脚本的每个"目标机器人"都恒存在,故不产生该组合) |
| 服务端:已有申请待审批 | 403「你之前的申请仍在等待审批,无需重复提交」 | routes/agents.js(D065 P2) | 矩阵 30 条 |
| 发送:未添加 | 「该机器人未添加,请先在「添加机器人」中申请」 | index.js WS 绑定校验 | 矩阵 G 段 6 条 |
| 发送:待审批 | 「该机器人添加申请待管理员审批」 | index.js WS 绑定校验 | 矩阵 G 段 6 条 |
| 发送:Agent 不存在 | 「Agent "xxx" 不存在」 | index.js WS | 矩阵 G 段 18 条 |
| 发送:频控 | 「你发得太快了:每分钟最多 N 条,请 X 秒后再发。」 | index.js 频控 | 矩阵 G 段 3 条 |
| 发送:配额用尽 | 「今天的额度用完了:每天最多 N 条,YYYY/MM/DD HH:mm:ss 重置。如需调整请联系管理员。」 | index.js 配额(D063) | 矩阵 G 段 1 条 |
| 发送:账号被封禁 | 「账号已被封禁,无法继续使用」(WS 4003) | index.js 封禁即时校验 | 矩阵 G 段 36 条 |
| 创建:名称问题 | 400「需要机器人名称」/「名称最多 40 个字」/「visibility 只能是 open(公开开放)/ private(定向邀请)」 | managed.js | 矩阵 E 段 18 + 18 + 6 条 |
| 创建:名额满 | 429「最多创建 20 个托管机器人(治理限制)」 | managed.js | 矩阵 E 段 4 条 |
| 创建:凭据提示 | “App Secret 只显示这一次,请立刻保存。丢了只能重置(旧密钥会立即失效)。” | managed.js / AddAgentBubble | 创建成功后的凭据态 |
| 治理:拉黑自己/创建者 | 400「不能拉黑自己(你就是创建者)。」/「不能拉黑创建者。」 | remote.js bans | 矩阵 H 段 2 + 2 条 |
| 治理:转让接收方满额 | 400「你已有 N 台托管机器人(上限 20),无法接收更多。」 | remote.js transfers | 矩阵 F 段 2 条 |
| 旧接口(极少见) | 410「该接口已废弃…请改用 POST /api/managed/agents」 | routes/agents.js | 只会在调用旧地址时出现 |
使用提示:先按用户贴出来的原话在上表定位"是哪一层拦截",再去第二节查处置动作。
顺序是硬编码的:封禁 > 机器人存在 > 绑定 > 频控 > 配额。用户说"发不出去"时按此顺序查,前三层与"添加"有关,后两层是运行时限制。
| 层 | 检查什么 | 典型表现 | 怎么查 | 怎么处置 |
|---|---|---|---|---|
| 第 1 层 | 账号是否被封禁 | 发送即报「账号已被封禁」/ WS 4003,且重连也进不来 | GET /api/users?search=(运营后台用户页)或 data/users/<id>.json 的 banned | 运营后台「用户」→ 解封;或 PUT /api/users/:id {banned:false} |
| 第 2 层 | 机器人是否存在/已下架 | 「Agent "xxx" 不存在」;目录里消失 | GET /api/agents / GET /api/version 的 connectors 清单;agents.json 的 hidden | 确认是否被下架/退役;必要时恢复(去掉 hidden 或重新上架) |
| 第 3 层 | 有没有绑定(active/pending) | 「该机器人未添加,请先在「添加机器人」中申请」或「申请待管理员审批」 | data/bindings/<uid>.json;或 GET /api/remote/agents/:id/bindings | 让用户走「添加/加入」;或管理员审批;确认是否被踢 |
| 第 4 层 | 频控(默认 20 条/分钟) | 「你发得太快了:每分钟最多 N 条」 | GET /api/ratelimit/status(管理端)或错误码 rate_limited | 等 1 分钟;若需调整 CHAT_RATE_PER_MIN 或 agents.json[id].rateLimitPerMin |
| 第 5 层 | 每日配额(默认关闭) | 「今天的额度用完了:每天最多 N 条…重置」 | GET /api/admin/quota/:userId(运营后台额度页,接口已上线) | 调额度 PUT /api/admin/quota/:userId {dailyQuota};或明天自动重置 |
| 要做的事 | 接口 | 入口 |
|---|---|---|
| 看某人今天用了多少条 | GET /api/admin/quota/:userId | 运营后台「配额」页(已上线) |
| 给某人加/减额度 | PUT /api/admin/quota/:userId {dailyQuota}(0=不限制,null=回默认) | 同上 |
| 全站默认额度 | GET/PUT /api/admin/quota-config {defaultDaily} | 需二次确认(影响所有人) |
| 改机器人可见性 | PUT /api/admin/agents/:id {visibility} | 运营后台「机器人」页(接口已上线) |
| 看实际生效可见性 | GET /api/agents 的 effectiveVisibility | 注意 visibility 只是原值 |
| 封禁/解封账号 | PUT /api/users/:id {banned} | 运营后台「用户」页 |
| 重设密码 | PUT /api/users/:id/password {new_password} | 运营后台「用户」页 |
| 查管理操作 | GET /api/logs?limit= | 运营后台「审计」页(可按用户/方法/时间过滤,v0.3.0) |
| 拉黑/踢人/转让 | POST /api/remote/agents/:id/bans、DELETE .../bindings/:uid、POST /api/remote/agents/:id/transfer | 用户端「机器人设置 → 成员治理」 |
| 结论 | 组合数 |
|---|---|
hidden-from-catalog | 192 |
reject-retired(404) | 60 |
reject-banned(403) | 54 |
already-active(200) | 36 |
reject-banned(WS 4003) | 36 |
reject-pending-waiting(403) | 30 |
| 结论 | 组合数 |
|---|---|
hidden-from-catalog | 192 |
join-active(200) | 84 |
already-active(200) | 48 |
pending→active(200) | 48 |
valid:true | 48 |
already(200) | 36 |
| 结论 | 组合数 |
|---|---|
hidden-from-catalog | 216 |
already-active(200) | 72 |
join-active(200) | 66 |
reject-retired(404) | 60 |
pending→active(200) | 48 |
valid:true | 48 |
| 结论 | 组合数 |
|---|---|
hidden-from-catalog | 288 |
join-active(200) | 46 |
already-active(200) | 44 |
pending→active(200) | 33 |
valid:true | 33 |
reject-retired(404) | 20 |
review 条目要码;未接入连接器 的条目即使加上也发不出消息。jiangpan 的码也能进 jiangpan-docker;反之改可见性/作废码会影响同容器所有别名。| 能力 | 证据 |
|---|---|
| 配额(默认关闭/跨天/豁免/超限拦在调用前) | quota-test 15/15、quota-live-check 7/7 |
可见性接口 + effectiveVisibility | visibility-admin-test 10/10(含线上) |
| 退役机不可加入 / 下架清绑定 / pending 提示 | add-robot-gaps-test 13/13(含线上) |
| 目录/加入/创建/转让/发送门禁的全组合 | 仅矩阵推演(真模块判定 + 路由建模),未逐条 HTTP 实测 |
node 系统开发/后端/测试脚本/scenario-matrix.mjs # 重新生成矩阵(确定性)
node 系统开发/后端/测试脚本/ops-cheatsheet.mjs # 重新生成本页(数字随之更新)