1
0
mirror of https://github.com/fumiama/ReiBot.git synced 2026-06-10 13:00:40 +08:00
This commit is contained in:
源文雨
2022-06-02 14:36:43 +08:00
parent 7c90c8b7d3
commit 8b6817acea
13 changed files with 802 additions and 17 deletions

276
rules.go
View File

@@ -1,12 +1,15 @@
package rei
import (
"reflect"
"regexp"
"strings"
"time"
tgba "github.com/go-telegram-bot-api/telegram-bot-api/v5"
)
// PrefixRule check if the message has the prefix and trim the prefix
// PrefixRule check if the text message has the prefix and trim the prefix
//
// 检查消息前缀
func PrefixRule(prefixes ...string) Rule {
@@ -26,3 +29,274 @@ func PrefixRule(prefixes ...string) Rule {
return false
}
}
// SuffixRule check if the text message has the suffix and trim the suffix
//
// 检查消息后缀
func SuffixRule(suffixes ...string) Rule {
return func(ctx *Ctx) bool {
msg, ok := ctx.Value.(*tgba.Message)
if !ok || msg.Text == "" { // 确保无空
return false
}
for _, suffix := range suffixes {
if strings.HasSuffix(msg.Text, suffix) {
ctx.State["suffix"] = suffix
arg := strings.TrimRight(msg.Text[:len(msg.Text)-len(suffix)], " ")
ctx.State["args"] = arg
return true
}
}
return false
}
}
// CommandRule check if the message is a command and trim the command name
func CommandRule(commands ...string) Rule {
return func(ctx *Ctx) bool {
msg, ok := ctx.Value.(*tgba.Message)
if !ok || msg.Text == "" || !msg.IsCommand() { // 确保无空
return false
}
ctx.State["command"] = msg.CommandWithAt()
ctx.State["args"] = msg.CommandArguments()
return true
}
}
// RegexRule check if the message can be matched by the regex pattern
func RegexRule(regexPattern string) Rule {
regex := regexp.MustCompile(regexPattern)
return func(ctx *Ctx) bool {
msg, ok := ctx.Value.(*tgba.Message)
if !ok || msg.Text == "" { // 确保无空
return false
}
if matched := regex.FindStringSubmatch(msg.Text); matched != nil {
ctx.State["regex_matched"] = matched
return true
}
return false
}
}
// ReplyRule check if the message is replying some message
func ReplyRule(messageID int) Rule {
return func(ctx *Ctx) bool {
msg, ok := ctx.Value.(*tgba.Message)
if !ok || msg.ReplyToMessage == nil { // 确保无空
return false
}
return messageID == msg.MessageID
}
}
// KeywordRule check if the message has a keyword or keywords
func KeywordRule(src ...string) Rule {
return func(ctx *Ctx) bool {
msg, ok := ctx.Value.(*tgba.Message)
if !ok || msg.Text == "" { // 确保无空
return false
}
for _, str := range src {
if strings.Contains(msg.Text, str) {
ctx.State["keyword"] = str
return true
}
}
return false
}
}
// FullMatchRule check if src has the same copy of the message
func FullMatchRule(src ...string) Rule {
return func(ctx *Ctx) bool {
msg, ok := ctx.Value.(*tgba.Message)
if !ok || msg.Text == "" { // 确保无空
return false
}
for _, str := range src {
if str == msg.Text {
ctx.State["matched"] = msg.Text
return true
}
}
return false
}
}
// ShellRule 定义shell-like规则
func ShellRule(cmd string, model interface{}) Rule {
cmdRule := CommandRule(cmd)
t := reflect.TypeOf(model)
return func(ctx *Ctx) bool {
if !cmdRule(ctx) {
return false
}
// bind flag to struct
args := ParseShell(ctx.State["args"].(string))
val := reflect.New(t)
fs := registerFlag(t, val)
err := fs.Parse(args)
if err != nil {
return false
}
ctx.State["args"] = fs.Args()
ctx.State["flag"] = val.Interface()
return true
}
}
// OnlyToMe only triggered in conditions of @bot or begin with the nicknames
func OnlyToMe(ctx *Ctx) bool {
msg, ok := ctx.Value.(*tgba.Message)
if !ok || msg.Text == "" { // 确保无空
return false
}
name := ctx.Caller.Self.String()
if strings.HasPrefix(msg.Text, name) {
return true
}
n := 0
for _, e := range msg.Entities {
if e.IsMention() && e.Length > 0 && msg.Text[n+1:n+e.Length] == name {
return true
}
n += e.Length
}
return false
}
// CheckUser only triggered by specific person
func CheckUser(userId ...int64) Rule {
return func(ctx *Ctx) bool {
msg, ok := ctx.Value.(*tgba.Message)
if !ok || msg.From == nil { // 确保无空
return false
}
for _, uid := range userId {
if msg.From.ID == uid {
return true
}
}
return false
}
}
// CheckChat only triggered in specific chat
func CheckChat(chatId ...int64) Rule {
return func(ctx *Ctx) bool {
msg, ok := ctx.Value.(*tgba.Message)
if !ok || msg.Chat == nil { // 确保无空
return false
}
for _, cid := range chatId {
if msg.Chat.ID == cid {
return true
}
}
return false
}
}
// SuperUserPermission only triggered by the bot's owner
func SuperUserPermission(ctx *Ctx) bool {
msg, ok := ctx.Value.(*tgba.Message)
if !ok || msg.From == nil { // 确保无空
return false
}
for _, su := range ctx.Caller.b.SuperUsers {
if su == msg.From.ID {
return true
}
}
return false
}
// CreaterPermission only triggered by the group creater or higher permission
func CreaterPermission(ctx *Ctx) bool {
msg, ok := ctx.Value.(*tgba.Message)
if !ok || msg.From == nil || msg.Chat == nil { // 确保无空
return false
}
for _, su := range ctx.Caller.b.SuperUsers {
if su == msg.From.ID {
return true
}
}
m, err := ctx.Caller.GetChatMember(
tgba.GetChatMemberConfig{
ChatConfigWithUser: tgba.ChatConfigWithUser{
ChatID: msg.Chat.ID,
UserID: msg.From.ID,
},
},
)
if err != nil {
return false
}
return m.IsCreator()
}
// AdminPermission only triggered by the group admins or higher permission
func AdminPermission(ctx *Ctx) bool {
msg, ok := ctx.Value.(*tgba.Message)
if !ok || msg.From == nil || msg.Chat == nil { // 确保无空
return false
}
for _, su := range ctx.Caller.b.SuperUsers {
if su == msg.From.ID {
return true
}
}
m, err := ctx.Caller.GetChatMember(
tgba.GetChatMemberConfig{
ChatConfigWithUser: tgba.ChatConfigWithUser{
ChatID: msg.Chat.ID,
UserID: msg.From.ID,
},
},
)
if err != nil {
return false
}
return m.IsCreator() || m.IsAdministrator()
}
// IsPhoto 消息是图片返回 true
func IsPhoto(ctx *Ctx) bool {
msg, ok := ctx.Value.(*tgba.Message)
if !ok || len(msg.Photo) == 0 { // 确保无空
return false
}
ctx.State["photos"] = msg.Photo
return true
}
// MustProvidePhoto 消息不存在图片阻塞120秒至有图片超时返回 false
func MustProvidePhoto(ctx *Ctx, needphohint, failhint string) bool {
msg, ok := ctx.Value.(*tgba.Message)
if ok && len(msg.Photo) > 0 { // 确保无空
ctx.State["photos"] = msg.Photo
return true
}
// 没有图片就索取
if needphohint != "" {
_, err := ctx.Caller.Send(tgba.NewMessage(msg.Chat.ID, needphohint))
if err != nil {
return false
}
}
next := NewFutureEvent("message", 999, false, ctx.CheckSession(), IsPhoto).Next()
select {
case <-time.After(time.Second * 120):
if failhint != "" {
_, _ = ctx.Caller.Send(tgba.NewMessage(msg.Chat.ID, failhint))
}
return false
case newCtx := <-next:
ctx.State["photos"] = newCtx.State["photos"]
ctx.Event = newCtx.Event
return true
}
}