你说的路由是:有归属 → admin + 销售;归属不确定 → 全推。第一条早就实现了
(resolve_recipient_names 读 profile.md 的 sales_owner)。
问题在第二条 —— 你把它当边缘情况,但数据上它是主路径:
68% 的活跃客户没有归属销售。「归属不确定 → 全推」如果照做, 三分之二的通知会推给所有人 —— 然后所有人静音,回到「谁也收不到」。
一场会是谁安排的,系统 100% 知道。
而「谁安排了跟这家客户的会」就是「谁在跟这家客户」最直接的证据 ——
比 profile.md 里一个要人手填的字段可靠得多,因为它是行为留下的,不是维护出来的。
| 收件人 | 说明 | |
|---|---|---|
| ① | admin + sales_owner | 已实现,不用动 |
| ② | admin + 会议组织者 | 新增。数据现成,100% 覆盖 循环会已经这么做了(handlers 3416),只是没推广到所有情形 |
| ③ | admin + 待认领 | 兜底。不是「全推」,是「明确说这条没主」 |
「全推」和「设一个专门角色」两条都不需要了 —— 前者制造噪音,后者是给缺失的数据配一个人肉补丁, 而那个数据其实已经在库里。
组织者信号不只能用来推送,还能反过来回填归属:
同一个人连续组织了某客户 3 场会 → 他基本就是这家的担当 → 提名写进 profile.md
| 为什么是提名不是自动写 | 照你定的规矩:agent 只提名,系统执行,人拍板。 自动写会把「某次代开的会」固化成归属,而归属错了 = #201 那种污染 |
| 为什么值得做 | 68% 无归属不是「大家懒」,是这个字段没有产生它的机制 —— 只有人手填,就只会一直空着 |
| 组织者的 open_id 不能直接用 | 日历返回的 organizer_open_id 属于另一个 Lark app 的命名空间,拿去发 DM 发不出去。必须走 名字 → 邮箱(org-members.json)→ 本 bot 的 open_id。 现有代码已经知道这件事(循环会那条路走的就是 _name_to_open_id),照抄即可 |
| 而那条链在别的组织是断的 | acme 盒子没有 org-members.json → 名字解析不到邮箱 → 一条 DM 都发不出去,而且现在只有一行 log.warning。这就是我上一条说的「收不到」。 |
| 序 | 做什么 | 为什么在这 |
|---|---|---|
| 1 | 路由三档(补②③)+ 送达落库 | 用户可见价值最大 —— 现在 68% 的客户消息只有 admin 收得到,
对应的销售根本不知道自己客户开过会。 送达落库同期做,否则改完了也不知道有没有改对 |
| 2 | 统计 tab 加「送达」一维 | 把失败摆在领导已经会去的地方 |
| 3 | 拆两层 + Teams 骨架 | 结构清理。不产生用户可见价值,但决定下次接渠道疼不疼 |
| 4 | 通知粒度 + 管理 UI | 要动前端,等前面稳 |
上一版我把「拆两层」排第 2 —— 现在往后挪了。 路由三档是真有人在疼的事,拆层只是我们自己疼。