koishi白名单机制笔记(研究中)

我本身没有ts和koishi基础,对特性了解不深,本贴作为我研究koishi白名单机制的学习笔记,希望大家能指正错误的地方。

首先 看一下内置的 assign 机制,碰巧可以满足部分白名单需求。

  1. 在启用了多个 bot 的场景下,assign 机制可以自动获取广播消息的受理人。
  2. assign 也参与到 Koishi 的中间件系统中。Koishi 的中间件监听 message 消息,并注册 attach 方法作为第一个中间件。图片
    attach 方法会判断当前消息的发送者是否为 bot 的受理人。除非用户直接 @ 这个 bot,attach 方法才会继续受理消息,否则将直接返回。

基于 assign 实现白名单

基于这一机制,通过修改数据库中 channel 表的 assignee 字段,可以初步实现白名单机制,只需要将assignee 字段瞎改成一个不存在的botId。

白名单机制的逃逸分析

经过实践和代码分析,基于 assign 机制的白名单存在以下三种可能的“逃逸”情况:

  1. 直接 @ bot: 正如 attach 方法的逻辑所示,如果用户直接 @ 了 bot,assign 机制的限制将被绕过,消息会继续被受理。
  2. 事件发布/订阅机制不走中间件: Koishi 的事件发布/订阅机制(dispatch )不受中间件的限制。部分插件可能直接通过事件来处理消息或执行操作,从而绕过中间件中的 attach 方法。
  3. 插件模拟虚拟的 Session 对象: 某些插件可能会创建和模拟虚拟的 Session 对象(这一点我还没搞清楚)

现在想讨论的是,不修改核心代码,从哪里介入比较合适呢?

  1. 从中间件角度入手无论如何都干涉不到事件系统,无非就是attach方法的扩充。
  2. 从适配器入手就完全不符合定义了,耦合度高,但我想这个方法肯定最稳定。
  3. 从输出入手局限性很大,插件仍然会执行并且有记录。
  4. 部分打补丁,比如说 session.execute这类方法,能这么干吗?

暂时先写到这

2 个赞

我有点笨,没太看懂,你是想用白名单限制什么东西(?)

2 个赞

如果你是想通过白名单机制来限制bot,只允许在特定群互动的话,我有一些思路
可以先试试用message-create事件,这个事件应该在收到消息后最先触发,位于指令系统和中间件前面
如果这个事件不行,可以试试前置中间件,前置中间件位于普通中间件和指令系统的前面,临时中间件的后面(这一点我不太确定)
过滤器或许也能实现你的目标,但是过滤器不太好用

2 个赞

如果我没记错,assign不会限制中间件,所有中间件操作都会逃逸

2 个赞

assign 的最初目的是为了避免群内有两个 bot 的情况下,发出一条指令两个 bot 各回复一遍。他满足白名单需求如你所说只是「碰巧」,实际上我觉得他也满足不了白名单需求。


插件市场里已经有三个白名单插件了,可以参考他们的源码。

一般情况下,从中间件角度入手即可。事件系统本身的作用不是「处理并回复消息」这个需求,无需处理。如果有插件监听了某个事件,那么这个插件一般不是用来处理消息的,而是需要完成一些与处理消息无关的其他功能(群消息频率统计、聊天记录备份等等)。这类插件不应该被拦截,或者用你的话说,应当让他们逃逸,他们才能正常工作。

3 个赞