Files
trbot/plugins/plugin_limit_message.go
Hubert Chen a84d22e7e2 add DeleteOldPinnedMessage flag
update help text for plugins
2025-08-28 08:20:32 +08:00

796 lines
27 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package plugins
import (
"context"
"fmt"
"os"
"path/filepath"
"reflect"
"strings"
"time"
"trbot/utils"
"trbot/utils/configs"
"trbot/utils/flaterr"
"trbot/utils/handler_params"
"trbot/utils/plugin_utils"
"trbot/utils/type/contain"
"trbot/utils/type/message_utils"
"trbot/utils/yaml"
"github.com/go-telegram/bot"
"github.com/go-telegram/bot/models"
"github.com/rs/zerolog"
)
var LimitMessageList map[int64]AllowMessages
var LimitMessageErr error
var LimitMessageDir string = filepath.Join(configs.YAMLDatabaseDir, "limitmessage/")
var LimitMessagePath string = filepath.Join(LimitMessageDir, configs.YAMLFileName)
type AllowMessages struct {
IsEnable bool `yaml:"IsEnable"`
IsUnderTest bool `yaml:"IsUnderTest"`
AddTime string `yaml:"AddTime"`
IsLogicAnd bool `yaml:"IsLogicAnd"` // true: `&&``, false: `||`
IsWhiteForType bool `yaml:"IsWhiteForType"`
MessageType message_utils.Message `yaml:"MessageType"`
IsWhiteForAttribute bool `yaml:"IsWhiteForAttribute"`
MessageAttribute message_utils.Attribute `yaml:"MessageAttribute"`
}
func init() {
plugin_utils.AddInitializer(plugin_utils.Initializer{
Name: "Limit Message",
Func: func(ctx context.Context, thebot *bot.Bot) error{
return ReadLimitMessageList(ctx)
},
})
plugin_utils.AddDataBaseHandler(plugin_utils.DatabaseHandler{
Name: "Limit Message",
Saver: SaveLimitMessageList,
Loader: ReadLimitMessageList,
})
plugin_utils.AddSlashCommandHandlers(plugin_utils.SlashCommand{
SlashCommand: "limitmessage",
MessageHandler: SomeMessageOnlyHandler,
})
plugin_utils.AddCallbackQueryHandlers(plugin_utils.CallbackQuery{
CallbackDataPrefix: "limitmsg_",
CallbackQueryHandler: LimitMessageCallback,
})
plugin_utils.AddHandlerHelpInfo(plugin_utils.HandlerHelp{
Name: "限制群组消息",
Description: "注意:此功能需要将 bot 设为群组管理员并给予删除消息的权限\n\n此功能可以设定一个消息类型和消息属性的组合由机器人自动删除不允许的消息支持自定逻辑和黑白名单\n\n由于此功能配置较为复杂请先在启用前先使用测试模式调整后再正式启用\n\n前往 @onlyforwardmessage 群组试试效果?",
ParseMode: models.ParseModeHTML,
})
}
func ReadLimitMessageList(ctx context.Context) error {
logger := zerolog.Ctx(ctx).
With().
Str("pluginName", "LimitMessage").
Str(utils.GetCurrentFuncName()).
Logger()
err := yaml.LoadYAML(LimitMessagePath, &LimitMessageList)
if err != nil {
if os.IsNotExist(err) {
logger.Warn().
Err(err).
Str("path", LimitMessagePath).
Msg("Not found limit message list file. Created new one")
// 如果是找不到文件,新建一个
err = yaml.SaveYAML(LimitMessagePath, &LimitMessageList)
if err != nil {
logger.Error().
Err(err).
Str("path", LimitMessagePath).
Msg("Failed to create empty limit message list file")
LimitMessageErr = fmt.Errorf("failed to create empty limit message list file: %w", err)
}
} else {
logger.Error().
Err(err).
Str("path", LimitMessagePath).
Msg("Failed to load limit message list file")
LimitMessageErr = fmt.Errorf("failed to load limit message list file: %w", err)
}
} else {
LimitMessageErr = nil
}
if LimitMessageList == nil {
LimitMessageList = map[int64]AllowMessages{}
}
buildLimitGroupList()
return LimitMessageErr
}
func SaveLimitMessageList(ctx context.Context) error {
logger := zerolog.Ctx(ctx).
With().
Str("pluginName", "LimitMessage").
Str(utils.GetCurrentFuncName()).
Logger()
err := yaml.SaveYAML(LimitMessagePath, &LimitMessageList)
if err != nil {
logger.Error().
Err(err).
Str("path", LimitMessagePath).
Msg("Failed to save limit message list")
LimitMessageErr = fmt.Errorf("failed to save limit message list: %w", err)
} else {
LimitMessageErr = nil
}
return LimitMessageErr
}
func SomeMessageOnlyHandler(opts *handler_params.Message) error {
logger := zerolog.Ctx(opts.Ctx).
With().
Str("pluginName", "LimitMessage").
Str(utils.GetCurrentFuncName()).
Dict(utils.GetUserDict(opts.Message.From)).
Dict(utils.GetChatDict(&opts.Message.Chat)).
Logger()
var handlerErr flaterr.MultErr
if opts.Message.Chat.Type == models.ChatTypePrivate {
_, err := opts.Thebot.SendMessage(opts.Ctx, &bot.SendMessageParams{
ChatID: opts.Message.Chat.ID,
Text: "此功能被设计为仅在群组中可用",
ReplyParameters: &models.ReplyParameters{ MessageID: opts.Message.ID },
})
if err != nil {
logger.Error().
Err(err).
Str("content", "limit message only allows in group").
Msg(flaterr.SendMessage.Str())
handlerErr.Addt(flaterr.SendMessage, "limit message only allows in group", err)
}
} else {
if utils.UserIsAdmin(opts.Ctx, opts.Thebot, opts.Message.Chat.ID, opts.Message.From.ID) {
thisChat := LimitMessageList[opts.Message.Chat.ID]
var isNeedInit bool = false
if thisChat.AddTime == "" {
isNeedInit = true
thisChat.AddTime = time.Now().Format(time.RFC3339)
}
if utils.UserIsAdmin(opts.Ctx, opts.Thebot, opts.Message.Chat.ID, configs.BotMe.ID) && utils.UserHavePermissionDeleteMessage(opts.Ctx, opts.Thebot, opts.Message.Chat.ID, configs.BotMe.ID) {
_, err := opts.Thebot.SendMessage(opts.Ctx, &bot.SendMessageParams{
ChatID: opts.Message.Chat.ID,
Text: "Limit Message 菜单",
ReplyMarkup: buildMessageAllKB(thisChat),
})
if err != nil {
logger.Error().
Err(err).
Str("content", "limit message main menu").
Msg(flaterr.SendMessage.Str())
handlerErr.Addt(flaterr.SendMessage, "limit message main menu", err)
}
_, err = opts.Thebot.DeleteMessage(opts.Ctx, &bot.DeleteMessageParams{
ChatID: opts.Message.Chat.ID,
MessageID: opts.Message.ID,
})
if err != nil {
logger.Error().
Err(err).
Str("content", "limit message command").
Msg(flaterr.DeleteMessage.Str())
handlerErr.Addt(flaterr.DeleteMessage, "limit message command", err)
}
if isNeedInit {
LimitMessageList[opts.Message.Chat.ID] = thisChat
err = SaveLimitMessageList(opts.Ctx)
if err != nil {
logger.Error().
Err(err).
Msg("Failed to save limit message list after adding new chat")
handlerErr.Addf("failed to save limit message list after adding new chat: %w", err)
}
}
} else {
_, err := opts.Thebot.SendMessage(opts.Ctx, &bot.SendMessageParams{
ChatID: opts.Message.Chat.ID,
Text: "启用此功能前,请先将机器人设为管理员\n如果还是提示本消息请检查机器人是否有删除消息的权限",
})
if err != nil {
logger.Error().
Err(err).
Str("content", "bot need be admin and have delete message permission").
Msg(flaterr.SendMessage.Str())
handlerErr.Addt(flaterr.SendMessage, "bot need be admin and have delete message permission", err)
}
}
} else {
botMessage, err := opts.Thebot.SendMessage(opts.Ctx, &bot.SendMessageParams{
ChatID: opts.Message.Chat.ID,
Text: "抱歉,您不是群组的管理员,无法为群组更改此功能",
})
if err != nil {
logger.Error().
Err(err).
Str("content", "non-admin can not change limit message config").
Msg(flaterr.SendMessage.Str())
handlerErr.Addt(flaterr.SendMessage, "non-admin can not change limit message config", err)
}
time.Sleep(time.Second * 5)
_, err = opts.Thebot.DeleteMessages(opts.Ctx, &bot.DeleteMessagesParams{
ChatID: opts.Message.Chat.ID,
MessageIDs: []int{
opts.Message.ID,
botMessage.ID,
},
})
if err != nil {
logger.Error().
Err(err).
Str("content", "non-admin can not change limit message config").
Msg(flaterr.DeleteMessages.Str())
handlerErr.Addt(flaterr.DeleteMessages, "non-admin can not change limit message config", err)
}
}
}
return handlerErr.Flat()
}
func DeleteNotAllowMessage(opts *handler_params.Message) error {
logger := zerolog.Ctx(opts.Ctx).
With().
Str("pluginName", "LimitMessage").
Str(utils.GetCurrentFuncName()).
Dict(utils.GetChatDict(&opts.Message.Chat)).
Dict(utils.GetUserDict(opts.Message.From)).
Int("messageID", opts.Message.ID).
Logger()
var handlerErr flaterr.MultErr
var deleteAction bool
var deleteHelp string = "当前模式:"
if contain.AnyType(opts.Message.Chat.Type, models.ChatTypeGroup, models.ChatTypeSupergroup) {
// 处理消息删除逻辑,只有当群组启用该功能时才处理
thisChat := LimitMessageList[opts.Message.Chat.ID]
if thisChat.IsEnable || thisChat.IsUnderTest {
thisMsgType := message_utils.GetMessageType(opts.Message)
thisMsgAttr := message_utils.GetMessageAttribute(opts.Message)
// 根据规则的黑白名单选择判断逻辑
if thisChat.IsLogicAnd {
deleteHelp += "同时触发两个规则才删除消息\n"
msgType, typeHelp := CheckMessageType(thisMsgType, thisChat.MessageType, thisChat.IsWhiteForType)
deleteHelp += "消息类型:" + typeHelp
if msgType {
msgAttr, attrHelp := CheckMessageAttribute(thisMsgAttr, thisChat.MessageAttribute, thisChat.IsWhiteForAttribute)
deleteHelp += "消息属性:" + attrHelp
if msgType && msgAttr {
deleteAction = true
}
}
} else {
deleteHelp += "触发任一规则就删除消息\n"
msgType, typeHelp := CheckMessageType(thisMsgType, thisChat.MessageType, thisChat.IsWhiteForType)
deleteHelp += "消息类型:" + typeHelp
if msgType {
deleteAction = true
} else {
msgAttr, attrHelp := CheckMessageAttribute(thisMsgAttr, thisChat.MessageAttribute, thisChat.IsWhiteForAttribute)
deleteHelp += "消息属性:" + attrHelp
if msgAttr {
deleteAction = true
}
}
}
if thisChat.IsUnderTest {
_, err := opts.Thebot.SendMessage(opts.Ctx, &bot.SendMessageParams{
ChatID: opts.Message.Chat.ID,
Text: utils.TextForTrueOrFalse(deleteAction, "此消息会被设定的规则删除\n\n", "此消息不会被删除\n\n") +
deleteHelp +
utils.TextForTrueOrFalse(thisChat.IsEnable, "<blockquote>当前已启用,关闭测试模式将开始删除触发了规则的消息</blockquote>", "<blockquote>您可以继续进行测试,以便达到您想要的效果,之后请手动启用此功能\n</blockquote>"),
DisableNotification: true,
ParseMode: models.ParseModeHTML,
ReplyParameters: &models.ReplyParameters{ MessageID: opts.Message.ID },
ReplyMarkup: &models.InlineKeyboardMarkup{ InlineKeyboard: [][]models.InlineKeyboardButton{{
{
Text: "打开配置菜单",
CallbackData: "limitmsg_back",
},
{
Text: "关闭测试模式",
CallbackData: "limitmsg_offtest",
},
}}},
})
if err != nil {
logger.Error().
Err(err).
Str("content", "test mode delete message notification").
Msg(flaterr.SendMessage.Str())
handlerErr.Addt(flaterr.SendMessage, "test mode delete message notification", err)
}
} else if deleteAction {
_, err := opts.Thebot.DeleteMessage(opts.Ctx, &bot.DeleteMessageParams{
ChatID: opts.Message.Chat.ID,
MessageID: opts.Message.ID,
})
if err != nil {
logger.Error().
Err(err).
Str("messageType", thisMsgType.Str()).
Str("content", "message trigger limit message rules").
Bool("IsLogicAnd", thisChat.IsLogicAnd).
Msg(flaterr.DeleteMessage.Str())
handlerErr.Addt(flaterr.DeleteMessage, "message trigger limit message rules", err)
} else {
logger.Info().
Str("messageType", thisMsgType.Str()).
Bool("IsLogicAnd", thisChat.IsLogicAnd).
Msg("Deleted message trigger limit message rules")
}
}
}
}
return handlerErr.Flat()
}
func CheckMessageType(this, target message_utils.Message, IsWhiteList bool) (bool, string) {
var delete bool = IsWhiteList
var deleteHelp string
v1 := reflect.ValueOf(this)
v2 := reflect.ValueOf(target)
t := reflect.TypeOf(this)
for i := 0; i < v1.NumField(); i++ {
field := t.Field(i)
val1 := v1.Field(i).Interface()
val2 := v2.Field(i).Interface()
if val1 == true && val1 == val2 {
deleteHelp += fmt.Sprintf("%s 消息类型 %s %s\n",
utils.TextForTrueOrFalse(IsWhiteList, "白名单", "黑名单"),
field.Name,
utils.TextForTrueOrFalse(IsWhiteList, "不删除", "删除"),
)
if IsWhiteList {
delete = false
} else {
delete = true
}
} else if val1 == true && val1 != val2 {
deleteHelp += fmt.Sprintf("%s 未命中 消息类型 %s 遵循默认规则 %s\n",
utils.TextForTrueOrFalse(IsWhiteList, "白名单", "黑名单"),
field.Name,
utils.TextForTrueOrFalse(delete, "删除", "不删除"),
)
}
}
return delete, deleteHelp
}
func CheckMessageAttribute(this, target message_utils.Attribute, IsWhiteList bool) (bool, string) {
var delete bool = IsWhiteList
var noAttribute bool = true // 如果没有命中任何消息属性,提示内容,根据黑白名单判断是否删除
var deleteHelp string
v1 := reflect.ValueOf(this)
v2 := reflect.ValueOf(target)
t := reflect.TypeOf(this)
for i := 0; i < v1.NumField(); i++ {
field := t.Field(i)
val1 := v1.Field(i).Interface()
val2 := v2.Field(i).Interface()
if val1 == true && val1 == val2 {
noAttribute = false
deleteHelp += fmt.Sprintf("%s 消息属性 %s %s\n",
utils.TextForTrueOrFalse(IsWhiteList, "白名单", "黑名单"),
field.Name,
utils.TextForTrueOrFalse(IsWhiteList, "不删除", "删除"),
)
if IsWhiteList {
delete = false
} else {
delete = true
}
} else if val1 == true && val1 != val2 {
noAttribute = false
deleteHelp += fmt.Sprintf("%s 未命中 消息属性 %s 遵循默认规则 %s\n",
utils.TextForTrueOrFalse(IsWhiteList, "白名单", "黑名单"),
field.Name,
utils.TextForTrueOrFalse(delete, "删除", "不删除"),
)
}
}
if noAttribute {
deleteHelp += fmt.Sprintf("%s 未命中 消息属性 无 遵循默认规则 %s\n",
utils.TextForTrueOrFalse(IsWhiteList, "白名单", "黑名单"),
utils.TextForTrueOrFalse(delete, "删除", "不删除"),
)
}
return delete, deleteHelp
}
func buttonText(text string, opt, IsWhiteList bool) string {
if opt {
return utils.TextForTrueOrFalse(IsWhiteList, "✅ ", "❌ ") + text
}
return text
}
func buildMessageTypeKB(chat AllowMessages) models.ReplyMarkup {
var msgTypeItems [][]models.InlineKeyboardButton
var msgTypeItemsTemp []models.InlineKeyboardButton
v := reflect.ValueOf(chat.MessageType) // 解除指针获取值
t := reflect.TypeOf(chat.MessageType)
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
value := v.Field(i)
if i % 3 == 0 && i != 0 {
msgTypeItems = append(msgTypeItems, msgTypeItemsTemp)
msgTypeItemsTemp = []models.InlineKeyboardButton{}
}
msgTypeItemsTemp = append(msgTypeItemsTemp, models.InlineKeyboardButton{
Text: buttonText(field.Name, value.Bool(), chat.IsWhiteForType),
CallbackData: "limitmsg_type_" + field.Name,
})
}
if len(msgTypeItemsTemp) != 0 {
msgTypeItems = append(msgTypeItems, msgTypeItemsTemp)
}
msgTypeItems = append(msgTypeItems, []models.InlineKeyboardButton{{
Text: "⬅️ 返回上一级",
CallbackData: "limitmsg_back",
}})
kb := &models.InlineKeyboardMarkup{
InlineKeyboard: msgTypeItems,
}
return kb
}
func buildMessageAttributeKB(chat AllowMessages) models.ReplyMarkup {
var msgAttributeItems [][]models.InlineKeyboardButton
var msgAttributeItemsTemp []models.InlineKeyboardButton
v := reflect.ValueOf(chat.MessageAttribute) // 解除指针获取值
t := reflect.TypeOf(chat.MessageAttribute)
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
value := v.Field(i)
if i % 2 == 0 && i != 0 {
msgAttributeItems = append(msgAttributeItems, msgAttributeItemsTemp)
msgAttributeItemsTemp = []models.InlineKeyboardButton{}
}
msgAttributeItemsTemp = append(msgAttributeItemsTemp, models.InlineKeyboardButton{
Text: buttonText(field.Name, value.Bool(), chat.IsWhiteForAttribute),
CallbackData: "limitmsg_attr_" + field.Name,
})
}
if len(msgAttributeItemsTemp) != 0 {
msgAttributeItems = append(msgAttributeItems, msgAttributeItemsTemp)
}
msgAttributeItems = append(msgAttributeItems, []models.InlineKeyboardButton{{
Text: "⬅️ 返回上一级",
CallbackData: "limitmsg_back",
}})
kb := &models.InlineKeyboardMarkup{
InlineKeyboard: msgAttributeItems,
}
return kb
}
func buildMessageAllKB(chat AllowMessages) models.ReplyMarkup {
var chatAllow [][]models.InlineKeyboardButton
chatAllow = append(chatAllow, []models.InlineKeyboardButton{
{
Text: "选择消息类型",
CallbackData: "limitmsg_typekb",
},
{
Text: "🔄 " + utils.TextForTrueOrFalse(chat.IsWhiteForType, "白名单模式", "黑名单模式"),
CallbackData: "limitmsg_typekb_switchrule",
},
})
chatAllow = append(chatAllow, []models.InlineKeyboardButton{
{
Text: "选择消息属性",
CallbackData: "limitmsg_attrkb",
},
{
Text: "🔄 " + utils.TextForTrueOrFalse(chat.IsWhiteForAttribute, "白名单模式", "黑名单模式"),
CallbackData: "limitmsg_attrkb_switchrule",
},
})
chatAllow = append(chatAllow, []models.InlineKeyboardButton{
{
Text: "🔄 " + utils.TextForTrueOrFalse(chat.IsLogicAnd, "满足上方所有条件才删除消息", "满足其中一个条件就删除消息"),
CallbackData: "limitmsg_switchlogic",
},
})
chatAllow = append(chatAllow, []models.InlineKeyboardButton{
{
Text: "🔄 " + utils.TextForTrueOrFalse(chat.IsUnderTest, "测试模式已开启 ✅", "测试模式已关闭 ❌"),
CallbackData: "limitmsg_switchtest",
},
})
chatAllow = append(chatAllow, []models.InlineKeyboardButton{
{
Text: "🚫 关闭菜单",
CallbackData: "delete_this_message",
},
{
Text: "🔄 " + utils.TextForTrueOrFalse(chat.IsEnable, "当前已启用 ✅", "当前已关闭 ❌"),
CallbackData: "limitmsg_switchenable",
},
})
kb := &models.InlineKeyboardMarkup{
InlineKeyboard: chatAllow,
}
return kb
}
func LimitMessageCallback(opts *handler_params.CallbackQuery) error {
logger := zerolog.Ctx(opts.Ctx).
With().
Str("pluginName", "LimitMessage").
Str(utils.GetCurrentFuncName()).
Dict(utils.GetChatDict(&opts.CallbackQuery.Message.Message.Chat)).
Dict(utils.GetUserDict(&opts.CallbackQuery.From)).
Str("callbackQueryData", opts.CallbackQuery.Data).
Logger()
var handlerErr flaterr.MultErr
if !utils.UserIsAdmin(opts.Ctx, opts.Thebot, opts.CallbackQuery.Message.Message.Chat.ID, opts.CallbackQuery.From.ID) {
_, err := opts.Thebot.AnswerCallbackQuery(opts.Ctx, &bot.AnswerCallbackQueryParams{
CallbackQueryID: opts.CallbackQuery.ID,
Text: "您没有权限修改此配置",
ShowAlert: true,
})
if err != nil {
logger.Error().
Err(err).
Str("content", "no permission to change limit message config").
Msg(flaterr.AnswerCallbackQuery.Str())
handlerErr.Addt(flaterr.AnswerCallbackQuery, "no permission to change limit message config", err)
}
} else {
thisChat := LimitMessageList[opts.CallbackQuery.Message.Message.Chat.ID]
var needRebuildGroupList bool
var needSavelimitMessageList bool
var needEditMainMenuMessage bool
switch opts.CallbackQuery.Data {
case "limitmsg_typekb":
// opts.Thebot.AnswerCallbackQuery(opts.Ctx, &bot.AnswerCallbackQueryParams{
// CallbackQueryID: opts.CallbackQuery.ID,
// Text: "已选择消息类型",
// })
_, err := opts.Thebot.EditMessageText(opts.Ctx, &bot.EditMessageTextParams{
ChatID: opts.CallbackQuery.Message.Message.Chat.ID,
MessageID: opts.CallbackQuery.Message.Message.ID,
Text: utils.TextForTrueOrFalse(thisChat.IsWhiteForType, "白名单模式", "黑名单模式") + ": " + utils.TextForTrueOrFalse(thisChat.IsWhiteForType, "仅允许发送选中的项目,其他消息将被删除", "将删除选中的项目"),
ReplyMarkup: buildMessageTypeKB(thisChat),
})
if err != nil {
logger.Error().
Err(err).
Str("content", "limit message type keyboard").
Msg(flaterr.EditMessageText.Str())
handlerErr.Addt(flaterr.EditMessageText, "limit message type keyboard", err)
}
case "limitmsg_typekb_switchrule":
thisChat.IsWhiteForType = !thisChat.IsWhiteForType
needSavelimitMessageList = true
needEditMainMenuMessage = true
case "limitmsg_attrkb":
_, err := opts.Thebot.EditMessageText(opts.Ctx, &bot.EditMessageTextParams{
ChatID: opts.CallbackQuery.Message.Message.Chat.ID,
MessageID: opts.CallbackQuery.Message.Message.ID,
Text: utils.TextForTrueOrFalse(thisChat.IsWhiteForAttribute, "白名单模式", "黑名单模式") + ": " + utils.TextForTrueOrFalse(thisChat.IsWhiteForAttribute, "仅允许发送选中的项目,其他消息将被删除", "将删除选中的项目") + "\n有一些项目可能无法使用",
ReplyMarkup: buildMessageAttributeKB(thisChat),
})
if err != nil {
logger.Error().
Err(err).
Str("content", "limit message attribute keyboard").
Msg(flaterr.EditMessageText.Str())
handlerErr.Addt(flaterr.EditMessageText, "limit message attribute keyboard", err)
}
case "limitmsg_attrkb_switchrule":
thisChat.IsWhiteForAttribute = !thisChat.IsWhiteForAttribute
needSavelimitMessageList = true
needEditMainMenuMessage = true
case "limitmsg_back":
needEditMainMenuMessage = true
case "limitmsg_switchenable":
thisChat.IsEnable = !thisChat.IsEnable
if thisChat.IsEnable { thisChat.IsUnderTest = false }
needRebuildGroupList = true
needSavelimitMessageList = true
needEditMainMenuMessage = true
case "limitmsg_switchlogic":
thisChat.IsLogicAnd = !thisChat.IsLogicAnd
needSavelimitMessageList = true
needEditMainMenuMessage = true
case "limitmsg_switchtest":
thisChat.IsUnderTest = !thisChat.IsUnderTest
needEditMainMenuMessage = true
needRebuildGroupList = true
needSavelimitMessageList = true
case "limitmsg_offtest":
thisChat.IsUnderTest = false
needSavelimitMessageList = true
needRebuildGroupList = true
_, err := opts.Thebot.EditMessageReplyMarkup(opts.Ctx, &bot.EditMessageReplyMarkupParams{
ChatID: opts.CallbackQuery.Message.Message.Chat.ID,
MessageID: opts.CallbackQuery.Message.Message.ID,
ReplyMarkup: &models.InlineKeyboardMarkup{ InlineKeyboard: [][]models.InlineKeyboardButton{{{
Text: "删除此提醒",
CallbackData: "delete_this_message",
}}}},
})
if err != nil {
logger.Error().
Err(err).
Str("content", "test mode turned off notice").
Msg(flaterr.EditMessageText.Str())
handlerErr.Addt(flaterr.EditMessageText, "test mode turned off notice", err)
}
default:
if strings.HasPrefix(opts.CallbackQuery.Data, "limitmsg_type_") {
needSavelimitMessageList = true
callbackField := strings.TrimPrefix(opts.CallbackQuery.Data, "limitmsg_type_")
data := thisChat.MessageType
v := reflect.ValueOf(data) // 解除指针获取值
t := reflect.TypeOf(data)
newStruct := reflect.New(v.Type()).Elem()
newStruct.Set(v) // 复制原始值
for i := 0; i < newStruct.NumField(); i++ {
if t.Field(i).Name == callbackField {
newStruct.Field(i).SetBool(!newStruct.Field(i).Bool())
}
}
thisChat.MessageType = newStruct.Interface().(message_utils.Message)
_, err := opts.Thebot.EditMessageReplyMarkup(opts.Ctx, &bot.EditMessageReplyMarkupParams{
ChatID: opts.CallbackQuery.Message.Message.Chat.ID,
MessageID: opts.CallbackQuery.Message.Message.ID,
ReplyMarkup: buildMessageTypeKB(thisChat),
})
if err != nil {
logger.Error().
Err(err).
Str("content", "limit message type keyboard").
Msg(flaterr.EditMessageReplyMarkup.Str())
handlerErr.Addt(flaterr.EditMessageReplyMarkup, "limit message type keyboard", err)
}
} else if strings.HasPrefix(opts.CallbackQuery.Data, "limitmsg_attr_") {
needSavelimitMessageList = true
callbackField := strings.TrimPrefix(opts.CallbackQuery.Data, "limitmsg_attr_")
data := thisChat.MessageAttribute
v := reflect.ValueOf(data) // 解除指针获取值
t := reflect.TypeOf(data)
newStruct := reflect.New(v.Type()).Elem()
newStruct.Set(v) // 复制原始值
for i := 0; i < newStruct.NumField(); i++ {
if t.Field(i).Name == callbackField {
newStruct.Field(i).SetBool(!newStruct.Field(i).Bool())
}
}
thisChat.MessageAttribute = newStruct.Interface().(message_utils.Attribute)
_, err := opts.Thebot.EditMessageReplyMarkup(opts.Ctx, &bot.EditMessageReplyMarkupParams{
ChatID: opts.CallbackQuery.Message.Message.Chat.ID,
MessageID: opts.CallbackQuery.Message.Message.ID,
ReplyMarkup: buildMessageAttributeKB(thisChat),
})
if err != nil {
logger.Error().
Err(err).
Str("content", "limit message attribute keyboard").
Msg(flaterr.EditMessageReplyMarkup.Str())
handlerErr.Addt(flaterr.EditMessageReplyMarkup, "limit message attribute keyboard", err)
}
}
}
if needSavelimitMessageList {
LimitMessageList[opts.CallbackQuery.Message.Message.Chat.ID] = thisChat
err := SaveLimitMessageList(opts.Ctx)
if err != nil {
logger.Error().
Err(err).
Msg("Failed to save limit message list")
handlerErr.Addf("failed to save limit message list: %w", err)
_, err = opts.Thebot.AnswerCallbackQuery(opts.Ctx, &bot.AnswerCallbackQueryParams{
CallbackQueryID: opts.CallbackQuery.ID,
Text: "保存修改失败,请重试或联系机器人管理员\n" + err.Error(),
ShowAlert: true,
})
if err != nil {
logger.Error().
Err(err).
Str("content", "failed to save limit message list notice").
Msg(flaterr.AnswerCallbackQuery.Str())
handlerErr.Addt(flaterr.AnswerCallbackQuery, "failed to save limit message list notice", err)
}
}
}
if needRebuildGroupList {
buildLimitGroupList()
}
if needEditMainMenuMessage {
_, err := opts.Thebot.EditMessageText(opts.Ctx, &bot.EditMessageTextParams{
ChatID: opts.CallbackQuery.Message.Message.Chat.ID,
MessageID: opts.CallbackQuery.Message.Message.ID,
Text: "Limit Message 菜单",
ReplyMarkup: buildMessageAllKB(thisChat),
})
if err != nil {
logger.Error().
Err(err).
Str("content", "limit message main menu").
Msg(flaterr.EditMessageText.Str())
handlerErr.Addt(flaterr.EditMessageText, "limit message main menu", err)
}
}
}
return handlerErr.Flat()
}
func buildLimitGroupList() {
for chatID, n := range LimitMessageList {
if n.IsEnable || n.IsUnderTest {
plugin_utils.AddHandlerByMessageChatIDHandlers(plugin_utils.ByMessageChatIDHandler{
ForChatID: chatID,
PluginName: "limit_message",
MessageHandler: DeleteNotAllowMessage,
})
} else {
plugin_utils.RemoveHandlerByChatIDHandler(chatID, "limit_message")
}
}
}