我本身没有ts和koishi基础,对特性了解不深,本贴作为我研究koishi白名单机制的学习笔记,希望大家能指正错误的地方。
首先 看一下内置的 assign 机制,碰巧可以满足部分白名单需求。
- 在启用了多个 bot 的场景下,assign 机制可以自动获取广播消息的受理人。
- assign 也参与到 Koishi 的中间件系统中。Koishi 的中间件监听
message消息,并注册attach方法作为第一个中间件。
attach方法会判断当前消息的发送者是否为 bot 的受理人。除非用户直接 @ 这个 bot,attach方法才会继续受理消息,否则将直接返回。
基于 assign 实现白名单
基于这一机制,通过修改数据库中 channel 表的 assignee 字段,可以初步实现白名单机制,只需要将assignee 字段瞎改成一个不存在的botId。
白名单机制的逃逸分析
经过实践和代码分析,基于 assign 机制的白名单存在以下三种可能的“逃逸”情况:
- 直接 @ bot: 正如
attach方法的逻辑所示,如果用户直接 @ 了 bot,assign 机制的限制将被绕过,消息会继续被受理。 - 事件发布/订阅机制不走中间件: Koishi 的事件发布/订阅机制(
dispatch)不受中间件的限制。部分插件可能直接通过事件来处理消息或执行操作,从而绕过中间件中的attach方法。 - 插件模拟虚拟的 Session 对象: 某些插件可能会创建和模拟虚拟的
Session对象(这一点我还没搞清楚)
现在想讨论的是,不修改核心代码,从哪里介入比较合适呢?
- 从中间件角度入手无论如何都干涉不到事件系统,无非就是attach方法的扩充。
- 从适配器入手就完全不符合定义了,耦合度高,但我想这个方法肯定最稳定。
- 从输出入手局限性很大,插件仍然会执行并且有记录。
- 部分打补丁,比如说 session.execute这类方法,能这么干吗?
暂时先写到这

