响应器规则
注意
编写此文档时,GoneBot
版本为 v1.1.4
简介
响应器规则的写法非常简洁,但它仍然功能齐全,能满足各种复杂的规则需求。
你可以使用 rule.NewRule()
来创建一个新的响应规则组,你必须为规则组指定第一个规则,如果你不需要添加规则,你可以使用 rule.NewRule(rule.Always())
来让响应器始终响应收到的消息。
内置规则
GoneBot
内置了一系列常用的规则,你可以直接使用它们来创建规则组:
rule.Always()
始终返回 true
,即始终响应收到的消息。
// Always always returns true
func Always() *Rule {
return &Rule{
Filter: func(msg message.Message) bool {
return true
},
}
}
rule.Never()
始终返回 false
,即始终不响应收到的消息。
// Never never returns true
func Never() *Rule {
return &Rule{
Filter: func(msg message.Message) bool {
return false
},
}
}
rule.Command()
在消息开头包含 COMMAND_START
加上其中指定的任一命令时返回 true
。
func Command(prefixList ...string) *Rule {
return &Rule{
Filter: func(msg message.Message) bool {
for _, prefix := range prefixList {
if strings.HasPrefix(
msg.GetRawText(),
configurations.GetConf("COMMAND_START")+prefix,
) {
return true
}
}
return false
},
}
}
提示
COMMAND_START
在 .env
文件中指定,默认为 /
在 rule.Command()
中可以填入若干条字符串,只要消息开头包含 COMMAND_START
+其中任一字符串,就会返回 true
,之后的一些内置响应规则也是如此。
rule.FullMatch()
在消息完全匹配指定的若干条字符串时返回 true
。
func FullMatch(strs ...string) *Rule {
return &Rule{
Filter: func(msg message.Message) bool {
for _, str := range strs {
if str == msg.GetRawText() {
return true
}
}
return false
},
}
}
rule.Keyword()
在消息中包含指定的若干条字符串中的任一条时返回 true
。
如果 forceStart
为 true
,则要求消息中包含的该字符串一定要在消息的开头。
func Keyword(forceStart bool, keywords ...string) *Rule {
return &Rule{
Filter: func(msg message.Message) bool {
for _, keyword := range keywords {
if forceStart && strings.HasPrefix(msg.GetRawText(), keyword) {
return true
}
if !forceStart && strings.Contains(msg.GetRawText(), keyword) {
return true
}
}
return false
},
}
}
rule.RegEx()
允许你传入若干个正则表达式字符串,只要消息能被其中任一正则表达式匹配,就会返回 true
。
同时,正则表达式可能会编译错误,为了更清晰的错误信息,你需要传入插件名称来标记使用该规则的插件。
func RegEx(pluginName string, exprs ...string) *Rule {
return &Rule{
Filter: func(msg message.Message) bool {
for _, expr := range exprs {
reg, err := regexp.Compile(expr)
if err != nil {
log.Printf("[GONEBOT] | %s: RegEx filter rule compilation error!\n", pluginName)
return false
}
if reg.FindStringIndex(msg.GetRawText()) != nil {
return true
}
}
return false
},
}
}
rule.ToMe()
在消息体的 IsToMe
字段为 true
时返回 true
。
func ToMe() *Rule {
return &Rule{
Filter: func(msg message.Message) bool {
return msg.IsToMe
},
}
}
提示
IsToMe
字段由适配器决定,例如在 QQ 机器人中,如果消息开头包含 @机器人QQ号
,或者有事件是针对机器人的(如戳一戳),则 IsToMe
为 true
。
rule.OfType()
在消息段的第一段的 Type
字段和 AdapterName
字段都匹配指定的字符串时返回 true
。
func OfType(typeName, adapterName string) *Rule {
return &Rule{
Filter: func(msg message.Message) bool {
return msg.GetSegments()[0].Type == typeName && msg.GetSegments()[0].Data.AdapterName() == adapterName
},
}
}
rule.Notice()
在消息中包含指定的若干类型中的任一种时返回 true
。
func Notice(typeList ...string) *Rule {
return &Rule{
Filter: func(msg message.Message) bool {
for _, typeName := range typeList {
for _, segment := range msg.GetSegments() {
if segment.Type == typeName {
return true
}
}
}
return false
},
}
}
自定义规则
如果内置规则不能满足你的要求,你可以自定义规则,只需要像这样创建一个新的 *rule.Rule
类型就可以:
Rules: rule.NewRule(rule.IsToMe()).And(&rule.Rule{
Filter: func(msg message.Message) bool {
if strings.HasSuffix(msg.GetRawText(), "喵~") {
return true
}
return false
}
})
这样就创建了一个检测消息末尾是否为 喵~
的规则,并且只有当消息是 IsToMe
时才会触发。
连接规则
rule.NewRule()
创建了一个规则块,其中可以包含多个规则,它们之间可以使用 And()
和 Or()
来连接,这些规则会按照连接顺序依次运算,最后得到结果。
如果你需要多个规则块协同运作,你可以使用 rule.AndRules()
和 rule.OrRules()
来为规则块连接一个新的规则块,运算规则同理。
例如,你需要你的机器人响应 @自己
并且包含 111
的消息,或者是针对自己的戳一戳消息:
Rules: rule.NewRule(rule.IsToMe()).And(rule.Keyword(false, "111")).
AndRules(rule.NewRule(rule.IsToMe()).And(rule.Notice("group_poke", "friend_poke")))
提示
这样构造的规则可能会很长,可以适当换行以更清楚的区分各规则块。