Skip to content

过滤器

过滤器是 Kotori 提供的一种强大的上下文筛选机制,可以根据多种条件对消息和事件进行过滤。通过过滤器,你可以精确控制模块的处理范围。

基本用法

过滤器通过 ctx.filter() 方法使用,接受一个过滤选项对象作为参数,返回新的上下文对象。过滤选项可以是单个条件或条件组:

tsx
// 基础过滤条件
ctx.filter({
  test: FilterTestList.PLATFORM,
  operator: '==',
  value: 'discord'
})

// 等价的组过滤条件
ctx.filter({
  type: 'all_of',
  filters: [
    {
      test: FilterTestList.PLATFORM,
      operator: '==',
      value: 'discord'
    }
  ]
})

多条件过滤

当需要更复杂的过滤逻辑时,可以使用条件组:

tsx
// 全部匹配
ctx.filter({
  type: 'all_of',
  filters: [
    {
      test: FilterTestList.PLATFORM,
      operator: '==',
      value: 'discord'
    },
    {
      test: FilterTestList.USER_ID,
      operator: '!=',
      value: '123456'
    }
  ]
})

// 任一匹配
ctx.filter({
  type: 'any_of',
  filters: [
    {
      test: FilterTestList.GROUP_ID,
      operator: '==',
      value: '789012'
    },
    {
      test: FilterTestList.ACCESS,
      operator: '>=',
      value: 3
    }
  ]
})

// 全部不匹配
ctx.filter({
  type: 'none_of',
  filters: [
    {
      test: FilterTestList.SELF_ID,
      operator: '==',
      value: 'bot123'
    },
    {
      test: FilterTestList.LOCALE_TYPE,
      operator: '==',
      value: 'zh_CN'
    }
  ]
})

条件组类型

  • all_of: 所有条件都必须匹配
  • any_of: 任意一个条件匹配即可
  • none_of: 所有条件都不能匹配

过滤条件

NOTE

滤器的过滤选项设计参考了 某个像素游戏 中的设计。

测试项

typescript
enum FilterTestList {
  PLATFORM = "platform",      // 平台名称
  USER_ID = "userId",        // 用户 ID
  GROUP_ID = "groupId",      // 群组 ID
  OPERATOR_ID = "operatorId", // 操作者 ID
  MESSAGE_ID = "messageId",   // 消息 ID
  SCOPE = "scope",           // 作用域
  ACCESS = "access",         // 访问权限等级
  IDENTITY = "identity",     // 身份标识
  LOCALE_TYPE = "localeType", // 语言类型
  SELF_ID = "selfId"         // 机器人账号
}

操作符

支持以下比较操作符:

  • ==: 等于
  • !=: 不等于
  • >: 大于
  • <: 小于
  • >=: 大于等于
  • <=: 小于等于

最佳实践

查看以下示例了解过滤器的正确使用方式:

tsx
// 正确的使用方式
ctx.filter({
  test: FilterTestList.ACCESS,
  operator: '>=',
  value: 2
})

// 链式调用方式
ctx
  .filter({
    test: FilterTestList.PLATFORM,
    operator: '==',
    value: 'discord'
  })
  .filter({
    test: FilterTestList.ACCESS,
    operator: '>=',
    value: 2
  })

// 组织条件的正确方式
ctx.filter({
  type: 'all_of',
  filters: [
    {
      test: FilterTestList.PLATFORM,
      operator: '==',
      value: 'discord'
    },
    {
      type: 'any_of',
      filters: [
        {
          test: FilterTestList.ACCESS,
          operator: '>=',
          value: 3
        },
        {
          test: FilterTestList.IDENTITY,
          operator: '==',
          value: 'admin'
        }
      ]
    }
  ]
})

TIP

过滤器的条件会按声明顺序依次执行,建议将开销较小的条件放在前面,可以提高性能。