diff --git a/bots/control.go b/bots/control.go index 65b14aa..566f458 100644 --- a/bots/control.go +++ b/bots/control.go @@ -5,10 +5,8 @@ import ( "fmt" "github.com/iyear/E5SubBot/model" "github.com/iyear/E5SubBot/util" - "github.com/spf13/viper" "github.com/tidwall/gjson" tb "gopkg.in/tucnak/telebot.v2" - "strconv" "strings" ) @@ -73,12 +71,3 @@ func MSAppIsExist(TgId int64, ClientId string) bool { First(&model.Client{}) return util.IF(result.RowsAffected == 0, false, true).(bool) } -func GetAdmins() []int64 { - var result []int64 - admins := strings.Split(viper.GetString("admin"), ",") - for _, v := range admins { - id, _ := strconv.ParseInt(v, 10, 64) - result = append(result, id) - } - return result -} diff --git a/bots/handle.go b/bots/handle.go index 37af50a..92216a2 100644 --- a/bots/handle.go +++ b/bots/handle.go @@ -2,10 +2,11 @@ package bots import ( "encoding/json" - "github.com/fsnotify/fsnotify" - "github.com/iyear/E5SubBot/core" + "fmt" + "github.com/iyear/E5SubBot/config" + "github.com/iyear/E5SubBot/model" + "github.com/iyear/E5SubBot/task" "github.com/iyear/E5SubBot/util" - "github.com/spf13/viper" "go.uber.org/zap" tb "gopkg.in/tucnak/telebot.v2" "io/ioutil" @@ -16,29 +17,10 @@ import ( "time" ) -const ( - bLogBasePath string = "./log/" - bStartContent string = "欢迎使用E5SubBot!" - bHelpContent string = ` - 命令: - /my 查看已绑定账户信息 - /bind 绑定新账户 - /unbind 解绑账户 - /export 导出账户信息(JSON) - /help 帮助 - 源码及使用方法:https://github.com/iyear/E5SubBot -` -) - var ( - UserStatus map[int64]int - UserCid map[int64]string - UserCSecret map[int64]string - ErrorTimes map[string]int //错误次数 - BindMaxNum int - ErrMaxTimes int - notice string - admin []int64 + UserStatus map[int64]int + UserClientId map[int64]string + UserClientSecret map[int64]string ) const ( @@ -48,41 +30,19 @@ const ( ) func init() { - //read config - viper.SetConfigName("config") - viper.AddConfigPath(".") - err := viper.ReadInConfig() - util.CheckErr(err) - - viper.SetDefault("errlimit", 5) - viper.SetDefault("bindmax", 5) - - BindMaxNum = viper.GetInt("bindmax") - ErrMaxTimes = viper.GetInt("errlimit") - notice = viper.GetString("notice") - admin = GetAdmin() - - viper.WatchConfig() - viper.OnConfigChange(func(e fsnotify.Event) { - BindMaxNum = viper.GetInt("bindmax") - ErrMaxTimes = viper.GetInt("errlimit") - notice = viper.GetString("notice") - admin = GetAdmin() - }) - UserStatus = make(map[int64]int) - UserCid = make(map[int64]string) - UserCSecret = make(map[int64]string) - ErrorTimes = make(map[string]int) + UserClientId = make(map[int64]string) + UserClientSecret = make(map[int64]string) } func bStart(m *tb.Message) { - bot.Send(m.Sender, bStartContent) + bot.Send(m.Sender, config.WelcomeContent) bHelp(m) } func bMy(m *tb.Message) { - data := core.QueryDataByTG(m.Chat.ID) + var data []*model.Client + model.DB.Where("tg_id = ?", m.Chat.ID).Find(&data) var inlineKeys [][]tb.InlineButton for _, u := range data { inlineBtn := tb.InlineButton{ @@ -93,20 +53,34 @@ func bMy(m *tb.Message) { bot.Handle(&inlineBtn, bMyInlineBtn) inlineKeys = append(inlineKeys, []tb.InlineButton{inlineBtn}) } - bot.Send(m.Chat, "选择一个账户查看具体信息\n\n绑定数: "+strconv.Itoa(GetBindNum(m.Chat.ID))+"/"+strconv.Itoa(BindMaxNum), &tb.ReplyMarkup{InlineKeyboard: inlineKeys}) + + bot.Send(m.Chat, + fmt.Sprintf("选择一个账户查看具体信息\n\n绑定数: %d/%d", GetBindNum(m.Chat.ID), config.BindMaxNum), + &tb.ReplyMarkup{InlineKeyboard: inlineKeys}) } func bMyInlineBtn(c *tb.Callback) { - r := core.QueryDataByMS(c.Data) - u := r[0] - bot.Send(c.Message.Chat, "信息\n别名:"+u.Alias+"\nMS_ID(MD5): "+u.MsId+"\nclient_id: "+u.ClientId+"\nclient_secret: "+u.ClientSecret+"\n最近更新时间: "+time.Unix(u.Uptime, 0).Format("2006-01-02 15:04:05")) + var u *model.Client + model.DB.Where("ms_id = ?", c.Data).First(&u) + bot.Send(c.Message.Chat, + fmt.Sprintf("信息\n别名:%s\nMS_ID(MD5): %s\nclient_id: %s\nclient_secret: %s\n最近更新时间: %s", + u.Alias, + u.MsId, + u.ClientId, + u.ClientSecret, + time.Unix(u.Uptime, 0).Format("2006-01-02 15:04:05")), + ) bot.Respond(c) } func bBind1(m *tb.Message) { - bot.Send(m.Chat, "应用注册: [点击直达]("+core.GetMSRegisterAppUrl()+")", tb.ModeMarkdown) - bot.Send(m.Chat, "请回复client_id+空格+client_secret", &tb.ReplyMarkup{ForceReply: true}) + bot.Send(m.Chat, + fmt.Sprintf("应用注册: [点击直达](%s)", model.GetMSRegisterAppUrl()), + tb.ModeMarkdown) + bot.Send(m.Chat, + "请回复client_id(空格)client_secret", + &tb.ReplyMarkup{ForceReply: true}) UserStatus[m.Chat.ID] = USBind1 - UserCid[m.Chat.ID] = m.Text + UserClientId[m.Chat.ID] = m.Text } func bBind2(m *tb.Message) { tmp := strings.Split(m.Text, " ") @@ -114,21 +88,22 @@ func bBind2(m *tb.Message) { bot.Send(m.Chat, "错误的格式") return } - cid := tmp[0] - cse := tmp[1] - bot.Send(m.Chat, "授权账户: [点击直达]("+core.GetMSAuthUrl(cid)+")", tb.ModeMarkdown) - _, err := bot.Send(m.Chat, "请回复http://localhost/…… + 空格 + 别名(用于管理)", &tb.ReplyMarkup{ForceReply: true}) - if err != nil { - return - } + ClientId := tmp[0] + ClientSecret := tmp[1] + bot.Send(m.Chat, "授权账户: [点击直达]("+model.GetMSAuthUrl(ClientId)+")", tb.ModeMarkdown) + bot.Send(m.Chat, + "请回复http://localhost/…… + 空格 + 别名(用于管理)", + &tb.ReplyMarkup{ForceReply: true}) UserStatus[m.Chat.ID] = USBind2 - UserCid[m.Chat.ID] = cid - UserCSecret[m.Chat.ID] = cse + UserClientId[m.Chat.ID] = ClientId + UserClientSecret[m.Chat.ID] = ClientSecret } func bUnBind(m *tb.Message) { - data := core.QueryDataByTG(m.Chat.ID) + var data []*model.Client + model.DB.Where("tg_id = ?", m.Chat.ID).Find(&data) var inlineKeys [][]tb.InlineButton + for _, u := range data { inlineBtn := tb.InlineButton{ Unique: "unbind" + u.MsId, @@ -138,13 +113,18 @@ func bUnBind(m *tb.Message) { bot.Handle(&inlineBtn, bUnBindInlineBtn) inlineKeys = append(inlineKeys, []tb.InlineButton{inlineBtn}) } - bot.Send(m.Chat, "选择一个账户将其解绑\n\n当前绑定数: "+strconv.Itoa(GetBindNum(m.Chat.ID))+"/"+strconv.Itoa(BindMaxNum), &tb.ReplyMarkup{InlineKeyboard: inlineKeys}) + + bot.Send(m.Chat, + fmt.Sprintf("选择一个账户将其解绑\n\n当前绑定数: %d/%d", GetBindNum(m.Chat.ID), config.BindMaxNum), + &tb.ReplyMarkup{InlineKeyboard: inlineKeys}, + ) } func bUnBindInlineBtn(c *tb.Callback) { - r := core.QueryDataByMS(c.Data) - u := r[0] - if ok, err := core.DelData(u.MsId); !ok { - zap.S().Errorw("failed to delete db data","error",err,"ms_id",u.MsId) + if result := model.DB.Where("ms_id = ?", c.Data).Delete(&model.Client{}); result.Error != nil { + zap.S().Errorw("failed to delete db data", + "error", result.Error, + "ms_id", c.Data, + ) bot.Send(c.Message.Chat, "解绑失败!") return } @@ -152,43 +132,49 @@ func bUnBindInlineBtn(c *tb.Callback) { bot.Respond(c) } func bExport(m *tb.Message) { - type MsMiniData struct { + type ClientExport struct { Alias string ClientId string ClientSecret string RefreshToken string Other string } - var MsMini []MsMiniData - data := core.QueryDataByTG(m.Chat.ID) + var exports []ClientExport + var data []*model.Client + model.DB.Where("tg_id = ?", m.Chat.ID).Find(&data) if len(data) == 0 { bot.Send(m.Chat, "你还没有绑定过账户嗷~") return } for _, u := range data { - var ms MsMiniData - ms.RefreshToken = u.RefreshToken - ms.Alias = u.Alias - ms.ClientId = u.ClientId - ms.ClientSecret = u.ClientSecret - ms.Other = u.Other - MsMini = append(MsMini, ms) + var cExport = ClientExport{ + Alias: u.Alias, + ClientId: u.ClientId, + ClientSecret: u.ClientSecret, + RefreshToken: u.RefreshToken, + Other: u.Other, + } + exports = append(exports, cExport) } - //MarshalIndent json美化,/t缩进 - export, err := json.MarshalIndent(MsMini, "", "\t") + export, err := json.MarshalIndent(exports, "", "\t") if err != nil { - zap.S().Errorw("failed to marshal json","error",err) - bot.Send(m.Chat, "获取JSON失败~\n"+err.Error()) + zap.S().Errorw("failed to marshal json", + "error", err) + bot.Send(m.Chat, fmt.Sprintf("获取JSON失败!\n\nERROR: %s", err.Error())) return } - //fmt.Println(string(export)) - fileName := "./" + strconv.FormatInt(m.Chat.ID, 10) + "_export_tmp.json" + fileName := fmt.Sprintf("./%d_export_tmp.json", m.Chat.ID) if err = ioutil.WriteFile(fileName, export, 0644); err != nil { - zap.S().Errorw("failed to write file","error",err) + zap.S().Errorw("failed to write file", + "error", err) bot.Send(m.Chat, "写入临时文件失败~\n"+err.Error()) return } - exportFile := &tb.Document{File: tb.FromDisk(fileName), FileName: strconv.FormatInt(m.Chat.ID, 10) + ".json", MIME: "text/plain"} + exportFile := &tb.Document{ + File: tb.FromDisk(fileName), + FileName: strconv.FormatInt(m.Chat.ID, 10) + ".json", + MIME: "text/plain", + } bot.Send(m.Chat, exportFile) //不遗留本地文件 if exportFile.InCloud() != true || os.Remove(fileName) != nil { @@ -196,7 +182,10 @@ func bExport(m *tb.Message) { } } func bHelp(m *tb.Message) { - bot.Send(m.Sender, bHelpContent+"\n"+notice, &tb.SendOptions{DisableWebPagePreview: false}) + bot.Send( + m.Sender, + config.HelpContent+"\n"+config.Notice, + &tb.SendOptions{DisableWebPagePreview: false}) } func bOnText(m *tb.Message) { switch UserStatus[m.Chat.ID] { @@ -219,12 +208,12 @@ func bOnText(m *tb.Message) { bot.Send(m.Chat, "请通过回复方式绑定") return } - if GetBindNum(m.Chat.ID) == BindMaxNum { + if GetBindNum(m.Chat.ID) == config.BindMaxNum { bot.Send(m.Chat, "已经达到最大可绑定数") return } bot.Send(m.Chat, "正在绑定中……") - err := BindUser(m, UserCid[m.Chat.ID], UserCSecret[m.Chat.ID]) + err := BindUser(m, UserClientId[m.Chat.ID], UserClientSecret[m.Chat.ID]) if err != nil { bot.Send(m.Chat, err.Error()) } else { @@ -235,26 +224,26 @@ func bOnText(m *tb.Message) { } } func bTask(m *tb.Message) { - for _, a := range admin { + for _, a := range config.Admins { if a == m.Chat.ID { - SignTask() + task.SignTask() return } } - bot.Send(m.Chat, "您没有权限执行此操作~") + bot.Send(m.Chat, "只有Bot管理员才有权限执行此操作") } func bLog(m *tb.Message) { flag := 0 - for _, a := range admin { + for _, a := range config.Admins { if a == m.Chat.ID { flag = 1 } } if flag == 0 { - bot.Send(m.Chat, "您没有权限执行此操作~") + bot.Send(m.Chat, "只有Bot管理员才有权限执行此操作") return } - logs := util.GetRecentLogs(bLogBasePath, 5) + logs := util.GetRecentLogs(config.LogBasePath, 5) var inlineKeys [][]tb.InlineButton for _, log := range logs { inlineBtn := tb.InlineButton{ @@ -265,15 +254,14 @@ func bLog(m *tb.Message) { bot.Handle(&inlineBtn, bLogsInlineBtn) inlineKeys = append(inlineKeys, []tb.InlineButton{inlineBtn}) } - bot.Send(m.Chat, "选择一个日志", &tb.ReplyMarkup{InlineKeyboard: inlineKeys}) + bot.Send(m.Chat, "请选择日志", &tb.ReplyMarkup{InlineKeyboard: inlineKeys}) } func bLogsInlineBtn(c *tb.Callback) { - //fmt.Println(c.Data) - //logger.Println(bLogBasePath + c.Data + ".log") - logfile := &tb.Document{File: tb.FromDisk(bLogBasePath + c.Data), FileName: c.Data, MIME: "text/plain"} - _, err := bot.Send(c.Message.Chat, logfile) - if err != nil { - return + logfile := &tb.Document{ + File: tb.FromDisk(config.LogBasePath + c.Data), + FileName: c.Data, + MIME: "text/plain", } + bot.Send(c.Message.Chat, logfile) bot.Respond(c) } diff --git a/config/config.go b/config/config.go new file mode 100644 index 0000000..5e8ea2b --- /dev/null +++ b/config/config.go @@ -0,0 +1,63 @@ +package config + +import ( + "github.com/fsnotify/fsnotify" + "github.com/spf13/viper" + "strconv" + "strings" +) + +const ( + LogBasePath string = "./log/" + WelcomeContent string = "欢迎使用E5SubBot!" + HelpContent string = ` + 命令: + /my 查看已绑定账户信息 + /bind 绑定新账户 + /unbind 解绑账户 + /export 导出账户信息(JSON) + /help 帮助 + 源码及使用方法:https://github.com/iyear/E5SubBot +` +) + +var ( + ErrorTimes map[string]int //错误次数 + BindMaxNum int + ErrMaxTimes int + Notice string + Admins []int64 +) + +func InitConfig() { + viper.SetConfigName("config") + viper.AddConfigPath(".") + err := viper.ReadInConfig() + if err != nil { + + } + viper.SetDefault("errlimit", 5) + viper.SetDefault("bindmax", 5) + + BindMaxNum = viper.GetInt("bindmax") + ErrMaxTimes = viper.GetInt("errlimit") + Notice = viper.GetString("notice") + Admins = getAdmins() + + viper.WatchConfig() + viper.OnConfigChange(func(e fsnotify.Event) { + BindMaxNum = viper.GetInt("bindmax") + ErrMaxTimes = viper.GetInt("errlimit") + Notice = viper.GetString("notice") + Admins = getAdmins() + }) +} +func getAdmins() []int64 { + var result []int64 + admins := strings.Split(viper.GetString("admin"), ",") + for _, v := range admins { + id, _ := strconv.ParseInt(v, 10, 64) + result = append(result, id) + } + return result +}