Beautify and independently config

This commit is contained in:
iyear 2021-06-14 23:17:11 +08:00
parent b026671553
commit 9d6db79a33
3 changed files with 159 additions and 119 deletions

View File

@ -5,10 +5,8 @@ import (
"fmt" "fmt"
"github.com/iyear/E5SubBot/model" "github.com/iyear/E5SubBot/model"
"github.com/iyear/E5SubBot/util" "github.com/iyear/E5SubBot/util"
"github.com/spf13/viper"
"github.com/tidwall/gjson" "github.com/tidwall/gjson"
tb "gopkg.in/tucnak/telebot.v2" tb "gopkg.in/tucnak/telebot.v2"
"strconv"
"strings" "strings"
) )
@ -73,12 +71,3 @@ func MSAppIsExist(TgId int64, ClientId string) bool {
First(&model.Client{}) First(&model.Client{})
return util.IF(result.RowsAffected == 0, false, true).(bool) 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
}

View File

@ -2,10 +2,11 @@ package bots
import ( import (
"encoding/json" "encoding/json"
"github.com/fsnotify/fsnotify" "fmt"
"github.com/iyear/E5SubBot/core" "github.com/iyear/E5SubBot/config"
"github.com/iyear/E5SubBot/model"
"github.com/iyear/E5SubBot/task"
"github.com/iyear/E5SubBot/util" "github.com/iyear/E5SubBot/util"
"github.com/spf13/viper"
"go.uber.org/zap" "go.uber.org/zap"
tb "gopkg.in/tucnak/telebot.v2" tb "gopkg.in/tucnak/telebot.v2"
"io/ioutil" "io/ioutil"
@ -16,29 +17,10 @@ import (
"time" "time"
) )
const (
bLogBasePath string = "./log/"
bStartContent string = "欢迎使用E5SubBot!"
bHelpContent string = `
命令
/my 查看已绑定账户信息
/bind 绑定新账户
/unbind 解绑账户
/export 导出账户信息(JSON)
/help 帮助
源码及使用方法https://github.com/iyear/E5SubBot
`
)
var ( var (
UserStatus map[int64]int UserStatus map[int64]int
UserCid map[int64]string UserClientId map[int64]string
UserCSecret map[int64]string UserClientSecret map[int64]string
ErrorTimes map[string]int //错误次数
BindMaxNum int
ErrMaxTimes int
notice string
admin []int64
) )
const ( const (
@ -48,41 +30,19 @@ const (
) )
func init() { 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) UserStatus = make(map[int64]int)
UserCid = make(map[int64]string) UserClientId = make(map[int64]string)
UserCSecret = make(map[int64]string) UserClientSecret = make(map[int64]string)
ErrorTimes = make(map[string]int)
} }
func bStart(m *tb.Message) { func bStart(m *tb.Message) {
bot.Send(m.Sender, bStartContent) bot.Send(m.Sender, config.WelcomeContent)
bHelp(m) bHelp(m)
} }
func bMy(m *tb.Message) { 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 var inlineKeys [][]tb.InlineButton
for _, u := range data { for _, u := range data {
inlineBtn := tb.InlineButton{ inlineBtn := tb.InlineButton{
@ -93,20 +53,34 @@ func bMy(m *tb.Message) {
bot.Handle(&inlineBtn, bMyInlineBtn) bot.Handle(&inlineBtn, bMyInlineBtn)
inlineKeys = append(inlineKeys, []tb.InlineButton{inlineBtn}) 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) { func bMyInlineBtn(c *tb.Callback) {
r := core.QueryDataByMS(c.Data) var u *model.Client
u := r[0] model.DB.Where("ms_id = ?", c.Data).First(&u)
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")) 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) bot.Respond(c)
} }
func bBind1(m *tb.Message) { func bBind1(m *tb.Message) {
bot.Send(m.Chat, "应用注册: [点击直达]("+core.GetMSRegisterAppUrl()+")", tb.ModeMarkdown) bot.Send(m.Chat,
bot.Send(m.Chat, "请回复client_id+空格+client_secret", &tb.ReplyMarkup{ForceReply: true}) fmt.Sprintf("应用注册: [点击直达](%s)", model.GetMSRegisterAppUrl()),
tb.ModeMarkdown)
bot.Send(m.Chat,
"请回复client_id(空格)client_secret",
&tb.ReplyMarkup{ForceReply: true})
UserStatus[m.Chat.ID] = USBind1 UserStatus[m.Chat.ID] = USBind1
UserCid[m.Chat.ID] = m.Text UserClientId[m.Chat.ID] = m.Text
} }
func bBind2(m *tb.Message) { func bBind2(m *tb.Message) {
tmp := strings.Split(m.Text, " ") tmp := strings.Split(m.Text, " ")
@ -114,21 +88,22 @@ func bBind2(m *tb.Message) {
bot.Send(m.Chat, "错误的格式") bot.Send(m.Chat, "错误的格式")
return return
} }
cid := tmp[0] ClientId := tmp[0]
cse := tmp[1] ClientSecret := tmp[1]
bot.Send(m.Chat, "授权账户: [点击直达]("+core.GetMSAuthUrl(cid)+")", tb.ModeMarkdown) bot.Send(m.Chat, "授权账户: [点击直达]("+model.GetMSAuthUrl(ClientId)+")", tb.ModeMarkdown)
_, err := bot.Send(m.Chat, "请回复http://localhost/…… + 空格 + 别名(用于管理)", &tb.ReplyMarkup{ForceReply: true}) bot.Send(m.Chat,
if err != nil { "请回复http://localhost/…… + 空格 + 别名(用于管理)",
return &tb.ReplyMarkup{ForceReply: true})
}
UserStatus[m.Chat.ID] = USBind2 UserStatus[m.Chat.ID] = USBind2
UserCid[m.Chat.ID] = cid UserClientId[m.Chat.ID] = ClientId
UserCSecret[m.Chat.ID] = cse UserClientSecret[m.Chat.ID] = ClientSecret
} }
func bUnBind(m *tb.Message) { 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 var inlineKeys [][]tb.InlineButton
for _, u := range data { for _, u := range data {
inlineBtn := tb.InlineButton{ inlineBtn := tb.InlineButton{
Unique: "unbind" + u.MsId, Unique: "unbind" + u.MsId,
@ -138,13 +113,18 @@ func bUnBind(m *tb.Message) {
bot.Handle(&inlineBtn, bUnBindInlineBtn) bot.Handle(&inlineBtn, bUnBindInlineBtn)
inlineKeys = append(inlineKeys, []tb.InlineButton{inlineBtn}) 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) { func bUnBindInlineBtn(c *tb.Callback) {
r := core.QueryDataByMS(c.Data) if result := model.DB.Where("ms_id = ?", c.Data).Delete(&model.Client{}); result.Error != nil {
u := r[0] zap.S().Errorw("failed to delete db data",
if ok, err := core.DelData(u.MsId); !ok { "error", result.Error,
zap.S().Errorw("failed to delete db data","error",err,"ms_id",u.MsId) "ms_id", c.Data,
)
bot.Send(c.Message.Chat, "解绑失败!") bot.Send(c.Message.Chat, "解绑失败!")
return return
} }
@ -152,43 +132,49 @@ func bUnBindInlineBtn(c *tb.Callback) {
bot.Respond(c) bot.Respond(c)
} }
func bExport(m *tb.Message) { func bExport(m *tb.Message) {
type MsMiniData struct { type ClientExport struct {
Alias string Alias string
ClientId string ClientId string
ClientSecret string ClientSecret string
RefreshToken string RefreshToken string
Other string Other string
} }
var MsMini []MsMiniData var exports []ClientExport
data := core.QueryDataByTG(m.Chat.ID) var data []*model.Client
model.DB.Where("tg_id = ?", m.Chat.ID).Find(&data)
if len(data) == 0 { if len(data) == 0 {
bot.Send(m.Chat, "你还没有绑定过账户嗷~") bot.Send(m.Chat, "你还没有绑定过账户嗷~")
return return
} }
for _, u := range data { for _, u := range data {
var ms MsMiniData var cExport = ClientExport{
ms.RefreshToken = u.RefreshToken Alias: u.Alias,
ms.Alias = u.Alias ClientId: u.ClientId,
ms.ClientId = u.ClientId ClientSecret: u.ClientSecret,
ms.ClientSecret = u.ClientSecret RefreshToken: u.RefreshToken,
ms.Other = u.Other Other: u.Other,
MsMini = append(MsMini, ms) }
exports = append(exports, cExport)
} }
//MarshalIndent json美化,/t缩进 export, err := json.MarshalIndent(exports, "", "\t")
export, err := json.MarshalIndent(MsMini, "", "\t")
if err != nil { if err != nil {
zap.S().Errorw("failed to marshal json","error",err) zap.S().Errorw("failed to marshal json",
bot.Send(m.Chat, "获取JSON失败~\n"+err.Error()) "error", err)
bot.Send(m.Chat, fmt.Sprintf("获取JSON失败!\n\nERROR: %s", err.Error()))
return return
} }
//fmt.Println(string(export)) fileName := fmt.Sprintf("./%d_export_tmp.json", m.Chat.ID)
fileName := "./" + strconv.FormatInt(m.Chat.ID, 10) + "_export_tmp.json"
if err = ioutil.WriteFile(fileName, export, 0644); err != nil { 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()) bot.Send(m.Chat, "写入临时文件失败~\n"+err.Error())
return 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) bot.Send(m.Chat, exportFile)
//不遗留本地文件 //不遗留本地文件
if exportFile.InCloud() != true || os.Remove(fileName) != nil { if exportFile.InCloud() != true || os.Remove(fileName) != nil {
@ -196,7 +182,10 @@ func bExport(m *tb.Message) {
} }
} }
func bHelp(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) { func bOnText(m *tb.Message) {
switch UserStatus[m.Chat.ID] { switch UserStatus[m.Chat.ID] {
@ -219,12 +208,12 @@ func bOnText(m *tb.Message) {
bot.Send(m.Chat, "请通过回复方式绑定") bot.Send(m.Chat, "请通过回复方式绑定")
return return
} }
if GetBindNum(m.Chat.ID) == BindMaxNum { if GetBindNum(m.Chat.ID) == config.BindMaxNum {
bot.Send(m.Chat, "已经达到最大可绑定数") bot.Send(m.Chat, "已经达到最大可绑定数")
return return
} }
bot.Send(m.Chat, "正在绑定中……") 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 { if err != nil {
bot.Send(m.Chat, err.Error()) bot.Send(m.Chat, err.Error())
} else { } else {
@ -235,26 +224,26 @@ func bOnText(m *tb.Message) {
} }
} }
func bTask(m *tb.Message) { func bTask(m *tb.Message) {
for _, a := range admin { for _, a := range config.Admins {
if a == m.Chat.ID { if a == m.Chat.ID {
SignTask() task.SignTask()
return return
} }
} }
bot.Send(m.Chat, "您没有权限执行此操作~") bot.Send(m.Chat, "只有Bot管理员才有权限执行此操作")
} }
func bLog(m *tb.Message) { func bLog(m *tb.Message) {
flag := 0 flag := 0
for _, a := range admin { for _, a := range config.Admins {
if a == m.Chat.ID { if a == m.Chat.ID {
flag = 1 flag = 1
} }
} }
if flag == 0 { if flag == 0 {
bot.Send(m.Chat, "您没有权限执行此操作~") bot.Send(m.Chat, "只有Bot管理员才有权限执行此操作")
return return
} }
logs := util.GetRecentLogs(bLogBasePath, 5) logs := util.GetRecentLogs(config.LogBasePath, 5)
var inlineKeys [][]tb.InlineButton var inlineKeys [][]tb.InlineButton
for _, log := range logs { for _, log := range logs {
inlineBtn := tb.InlineButton{ inlineBtn := tb.InlineButton{
@ -265,15 +254,14 @@ func bLog(m *tb.Message) {
bot.Handle(&inlineBtn, bLogsInlineBtn) bot.Handle(&inlineBtn, bLogsInlineBtn)
inlineKeys = append(inlineKeys, []tb.InlineButton{inlineBtn}) 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) { func bLogsInlineBtn(c *tb.Callback) {
//fmt.Println(c.Data) logfile := &tb.Document{
//logger.Println(bLogBasePath + c.Data + ".log") File: tb.FromDisk(config.LogBasePath + c.Data),
logfile := &tb.Document{File: tb.FromDisk(bLogBasePath + c.Data), FileName: c.Data, MIME: "text/plain"} FileName: c.Data,
_, err := bot.Send(c.Message.Chat, logfile) MIME: "text/plain",
if err != nil {
return
} }
bot.Send(c.Message.Chat, logfile)
bot.Respond(c) bot.Respond(c)
} }

63
config/config.go Normal file
View File

@ -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
}