This commit is contained in:
iyear 2021-03-11 12:57:30 +08:00
parent 95eb409a79
commit 5c670544a3
11 changed files with 325 additions and 252 deletions

1
.gitignore vendored
View File

@ -21,3 +21,4 @@ config.yml
/dist
#Logs
/log
/.idea

132
bots/bots.go Normal file
View File

@ -0,0 +1,132 @@
package bots
import (
"database/sql"
"fmt"
"github.com/robfig/cron/v3"
"github.com/spf13/viper"
"golang.org/x/net/proxy"
tb "gopkg.in/tucnak/telebot.v2"
"main/logger"
"net/http"
"strconv"
"strings"
"time"
)
var (
BotToken string
Socks5 string
bot *tb.Bot
//logger *log.Logger
)
const (
dbDriverName = "mysql"
logo = `
______ _____ _____ _ ____ _
| ____| ____/ ____| | | | _ \ | |
| |__ | |__| (___ _ _| |__ | |_) | ___ | |_
| __| |___ \\___ \| | | | '_ \| _ < / _ \| __|
| |____ ___) |___) | |_| | |_) | |_) | (_) | |_
|______|____/_____/ \__,_|_.__/|____/ \___/ \__|
`
)
var dbPath string
func BotStart() {
MakeHandle()
TaskLaunch()
logger.Println("Bot Start")
fmt.Println("------------")
bot.Start()
}
func MakeHandle() {
logger.Println("Make Handle……")
//所有用户
bot.Handle("/start", bStart)
bot.Handle("/my", bMy)
bot.Handle("/bind", bBind1)
bot.Handle("/unbind", bUnBind)
bot.Handle("/export", bExport)
bot.Handle("/help", bHelp)
bot.Handle(tb.OnText, bOnText)
//管理员
bot.Handle("/task", bTask)
bot.Handle("/log", bLog)
}
func TaskLaunch() {
task := cron.New()
//每三小时执行一次
task.AddFunc(viper.GetString("cron"), SignTask)
//log分为每天
//task.AddFunc(" 0 0 * * *", InitLogger)
// */1 * * * * 1 */3 * * *
logger.Println("Cron Task Start……")
task.Start()
}
func init() {
fmt.Println(logo)
//read config
logger.Println("Read Config……")
viper.SetConfigName("config")
viper.AddConfigPath(".")
err := viper.ReadInConfig()
if err != nil {
logger.Println(err)
}
host := viper.GetString("mysql.host")
user := viper.GetString("mysql.user")
port := viper.GetString("mysql.port")
pwd := viper.GetString("mysql.password")
database := viper.GetString("mysql.database")
dbPath = strings.Join([]string{user, ":", pwd, "@tcp(", host, ":", port, ")/", database, "?charset=utf8"}, "")
//fmt.Println(path)
db, err := sql.Open(dbDriverName, dbPath)
if err != nil {
logger.Println(err)
}
logger.Println("Connect MySQL Success!")
if ok, err := CreateTB(); !ok {
logger.Println(err)
}
defer db.Close()
BotToken = viper.GetString("bot_token")
Socks5 = viper.GetString("socks5")
//set bot
logger.Println("Bot Settings……")
Poller := &tb.LongPoller{Timeout: 15 * time.Second}
spamProtected := tb.NewMiddlewarePoller(Poller, func(upd *tb.Update) bool {
if upd.Message == nil {
return true
}
if !upd.Message.Private() {
return false
}
return true
})
botsettings := tb.Settings{
Token: BotToken,
Poller: spamProtected,
}
//set socks5
if Socks5 != "" {
logger.Println("Proxy:" + Socks5)
dialer, err := proxy.SOCKS5("tcp", Socks5, nil, proxy.Direct)
if err != nil {
logger.Println(err)
}
httpTransport := &http.Transport{}
httpClient := &http.Client{Transport: httpTransport}
httpTransport.Dial = dialer.Dial
botsettings.Client = httpClient
}
//create bot
bot, err = tb.NewBot(botsettings)
if err != nil {
logger.Println(err)
}
logger.Println("Bot: " + strconv.Itoa(bot.Me.ID) + " " + bot.Me.Username)
}

View File

@ -1,4 +1,4 @@
package main
package bots
import (
"errors"
@ -6,9 +6,10 @@ import (
"github.com/spf13/viper"
"github.com/tidwall/gjson"
tb "gopkg.in/tucnak/telebot.v2"
"io"
"log"
"os"
"main/db"
"main/logger"
"main/outlook"
"main/util"
"strconv"
"strings"
"time"
@ -18,69 +19,69 @@ var SignOk map[int64]int
//If Successfully return "",else return error information
func BindUser(m *tb.Message, cid, cse string) error {
logger.Printf("%d Begin Bind\n", m.Chat.ID)
logger.Println("%d Begin Bind\n", m.Chat.ID)
tmp := strings.Split(m.Text, " ")
if len(tmp) != 2 {
logger.Printf("%d Bind error:Wrong Bind Format\n", m.Chat.ID)
logger.Println("%d Bind error:Wrong Bind Format\n", m.Chat.ID)
return errors.New("绑定格式错误")
}
logger.Println("alias: " + tmp[1])
alias := tmp[1]
code := GetURLValue(tmp[0], "code")
logger.Println("Alias: " + tmp[1])
Alias := tmp[1]
code := util.GetURLValue(tmp[0], "code")
//fmt.Println(code)
access, refresh, err := MSFirGetToken(code, cid, cse)
access, refresh, err := outlook.MSFirGetToken(code, cid, cse)
if err != nil {
logger.Printf("%d Bind error:GetRefreshToken %s \n", m.Chat.ID, err.Error())
logger.Println("%d Bind error:GetRefreshToken %s \n", m.Chat.ID, err.Error())
return err
}
//token has gotten
bot.Send(m.Chat, "Token获取成功!")
info, err := MSGetUserInfo(access)
//fmt.Printf("TGID:%d Refresh Token: %s\n", m.Chat.ID, refresh)
info, err := outlook.MSGetUserInfo(access)
//fmt.Println("TgId:%d Refresh Token: %s\n", m.Chat.ID, refresh)
if err != nil {
logger.Printf("%d Bind error:Getinfo %s \n", m.Chat.ID, err.Error())
logger.Println("%d Bind error:Getinfo %s \n", m.Chat.ID, err.Error())
return err
}
var u MSData
u.tgId = m.Chat.ID
u.refreshToken = refresh
//TG的Data传递最高64bytes,一些msid超过了报错BUTTON_DATA_INVALID (0)采取md5
u.msId = Get16MD5Encode(gjson.Get(info, "id").String())
u.uptime = time.Now().Unix()
logger.Println(u.uptime)
u.alias = alias
u.clientId = cid
u.clientSecret = cse
u.other = ""
var u db.MSData
u.TgId = m.Chat.ID
u.RefreshToken = refresh
//TG的Data传递最高64bytes,一些MsId超过了报错BUTTON_DATA_INVALID (0)采取md5
u.MsId = util.Get16MD5Encode(gjson.Get(info, "id").String())
u.Uptime = time.Now().Unix()
logger.Println(u.Uptime)
u.Alias = Alias
u.ClientId = cid
u.ClientSecret = cse
u.Other = ""
//MS User Is Exist
if MSAppIsExist(u.tgId, u.clientId) {
logger.Printf("%d Bind error:MSUserHasExisted\n", m.Chat.ID)
if MSAppIsExist(u.TgId, u.ClientId) {
logger.Println("%d Bind error:MSUserHasExisted\n", m.Chat.ID)
return errors.New("该应用已经绑定过了,无需重复绑定")
}
//MS information has gotten
bot.Send(m.Chat, "MS_ID(MD5) "+u.msId+"\nuserPrincipalName "+gjson.Get(info, "userPrincipalName").String()+"\ndisplayName "+gjson.Get(info, "displayName").String()+"\n")
if ok, err := AddData(u); !ok {
logger.Printf("%d Bind error: %s\n", m.Chat.ID, err)
bot.Send(m.Chat, "MS_ID(MD5) "+u.MsId+"\nuserPrincipalName "+gjson.Get(info, "userPrincipalName").String()+"\ndisplayName "+gjson.Get(info, "displayName").String()+"\n")
if ok, err := db.AddData(u); !ok {
logger.Println("%d Bind error: %s\n", m.Chat.ID, err)
return err
}
logger.Printf("%d Bind Successfully!\n", m.Chat.ID)
logger.Println("%d Bind Successfully!\n", m.Chat.ID)
return nil
}
//get bind num
func GetBindNum(tgId int64) int {
data := QueryDataByTG(tgId)
func GetBindNum(TgId int64) int {
data := db.QueryDataByTG(TgId)
return len(data)
}
//return true => exist
func MSAppIsExist(tgId int64, clientId string) bool {
data := QueryDataByTG(tgId)
var res MSData
func MSAppIsExist(TgId int64, ClientId string) bool {
data := db.QueryDataByTG(TgId)
var res db.MSData
for _, res = range data {
if res.clientId == clientId {
if res.ClientId == ClientId {
return true
}
}
@ -98,52 +99,52 @@ func SignTask() {
SignOk = make(map[int64]int)
fmt.Println("----Task Begin----")
fmt.Println("Time:" + time.Now().Format("2006-01-02 15:04:05"))
data := QueryDataAll()
data := db.QueryDataAll()
num = len(data)
fmt.Println("Start Sign")
//签到任务
for _, u := range data {
pre := "您的账户: " + u.alias + "\n在任务执行时出现了错误!\n错误:"
chat, err := bot.ChatByID(strconv.FormatInt(u.tgId, 10))
pre := "您的账户: " + u.Alias + "\n在任务执行时出现了错误!\n错误:"
chat, err := bot.ChatByID(strconv.FormatInt(u.TgId, 10))
if err != nil {
logger.Println(err)
continue
}
//生成解绑按钮
var inlineKeys [][]tb.InlineButton
UnBindBtn := tb.InlineButton{Unique: "un" + u.msId, Text: "点击解绑该账户", Data: u.msId}
UnBindBtn := tb.InlineButton{Unique: "un" + u.MsId, Text: "点击解绑该账户", Data: u.MsId}
bot.Handle(&UnBindBtn, bUnBindInlineBtn)
inlineKeys = append(inlineKeys, []tb.InlineButton{UnBindBtn})
tmpBtn := &tb.ReplyMarkup{InlineKeyboard: inlineKeys}
se := u.msId + " ( @" + chat.Username + " )"
access, newRefreshToken, err := MSGetToken(u.refreshToken, u.clientId, u.clientSecret)
se := u.MsId + " ( @" + chat.Username + " )"
access, newRefreshToken, err := outlook.MSGetToken(u.RefreshToken, u.ClientId, u.ClientSecret)
if err != nil {
logger.Println(u.msId+" ", err)
logger.Println(u.MsId+" ", err)
bot.Send(chat, pre+gjson.Get(err.Error(), "error").String(), tmpBtn)
SignErr = append(SignErr, se)
ErrorTimes[u.msId]++
ErrorTimes[u.MsId]++
continue
}
if ok, err := OutLookGetMails(access); !ok {
logger.Println(u.msId+" ", err)
if ok, err := outlook.OutLookGetMails(access); !ok {
logger.Println(u.MsId+" ", err)
bot.Send(chat, pre+gjson.Get(err.Error(), "error").String(), tmpBtn)
ErrorTimes[u.msId]++
ErrorTimes[u.MsId]++
SignErr = append(SignErr, se)
continue
}
u.uptime = time.Now().Unix()
u.refreshToken = newRefreshToken
if ok, err := UpdateData(u); !ok {
logger.Println(u.msId+" ", err)
u.Uptime = time.Now().Unix()
u.RefreshToken = newRefreshToken
if ok, err := db.UpdateData(u); !ok {
logger.Println(u.MsId+" ", err)
bot.Send(chat, pre+err.Error(), tmpBtn)
SignErr = append(SignErr, se)
ErrorTimes[u.msId]++
ErrorTimes[u.MsId]++
continue
}
fmt.Println(u.msId + " Sign OK!")
SignOk[u.tgId]++
fmt.Println(u.MsId + " Sign OK!")
SignOk[u.TgId]++
signOk++
}
fmt.Println("Sign End,Start Send")
@ -151,32 +152,32 @@ func SignTask() {
isSend = make(map[int64]bool)
//用户任务反馈
for _, u := range data {
chat, err := bot.ChatByID(strconv.FormatInt(u.tgId, 10))
chat, err := bot.ChatByID(strconv.FormatInt(u.TgId, 10))
if err != nil {
logger.Println("Send Result ERROR: ", err)
continue
}
//错误上限账户清退
if ErrorTimes[u.msId] == ErrMaxTimes {
logger.Println(u.msId + " Error Limit")
if ok, err := DelData(u.msId); !ok {
if ErrorTimes[u.MsId] == ErrMaxTimes {
logger.Println(u.MsId + " Error Limit")
if ok, err := db.DelData(u.MsId); !ok {
logger.Println(err)
} else {
UnbindUser = append(UnbindUser, u.msId+" ( @"+chat.Username+" )")
_, err = bot.Send(chat, "您的账户因达到错误上限而被自动解绑\n后会有期!\n\n别名: "+u.alias+"\nclient_id: "+u.clientId+"\nclient_secret: "+u.clientSecret)
UnbindUser = append(UnbindUser, u.MsId+" ( @"+chat.Username+" )")
_, err = bot.Send(chat, "您的账户因达到错误上限而被自动解绑\n后会有期!\n\n别名: "+u.Alias+"\nclient_id: "+u.ClientId+"\nclient_secret: "+u.ClientSecret)
if err != nil {
logger.Println(err)
}
}
}
if !isSend[u.tgId] {
if !isSend[u.TgId] {
//静默发送,过多消息很烦
_, err = bot.Send(chat, "任务反馈\n时间: "+time.Now().Format("2006-01-02 15:04:05")+"\n结果: "+strconv.Itoa(SignOk[u.tgId])+"/"+strconv.Itoa(GetBindNum(u.tgId)), &tb.SendOptions{DisableNotification: true})
_, err = bot.Send(chat, "任务反馈\n时间: "+time.Now().Format("2006-01-02 15:04:05")+"\n结果: "+strconv.Itoa(SignOk[u.TgId])+"/"+strconv.Itoa(GetBindNum(u.TgId)), &tb.SendOptions{DisableNotification: true})
if err != nil {
logger.Println(err)
}
isSend[u.tgId] = true
isSend[u.TgId] = true
}
}
//管理员任务反馈
@ -207,19 +208,20 @@ func GetAdmin() []int64 {
}
return result
}
func InitLogger() {
if !PathExists(bLogBasePath) {
os.Mkdir(bLogBasePath, 0773)
}
path := bLogBasePath + time.Now().Format("2006-01-02") + ".log"
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0773)
if err != nil {
logger.Println(err)
}
writers := []io.Writer{
f,
os.Stdout}
faoWriter := io.MultiWriter(writers...)
logger = log.New(faoWriter, "【E5Sub】", log.Ldate|log.Ltime|log.Lshortfile)
}
//func InitLogger() {
// if !util.PathExists(bLogBasePath) {
// os.Mkdir(bLogBasePath, 0773)
// }
//
// path := bLogBasePath + time.Now().Format("2006-01-02") + ".log"
// f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0773)
// if err != nil {
// logger.Println(err)
// }
// writers := []io.Writer{
// f,
// os.Stdout}
// faoWriter := io.MultiWriter(writers...)
// //logger = log.New(faoWriter, "【E5Sub】", log.Ldate|log.Ltime|log.Lshortfile)
//}

View File

@ -1,4 +1,4 @@
package main
package bots
import (
"encoding/json"
@ -6,6 +6,10 @@ import (
"github.com/spf13/viper"
tb "gopkg.in/tucnak/telebot.v2"
"io/ioutil"
"main/db"
"main/logger"
"main/outlook"
"main/util"
"os"
"path/filepath"
"strconv"
@ -51,7 +55,7 @@ func init() {
viper.SetConfigName("config")
viper.AddConfigPath(".")
err := viper.ReadInConfig()
CheckErr(err)
util.CheckErr(err)
viper.SetDefault("errlimit", 5)
viper.SetDefault("bindmax", 5)
@ -82,13 +86,13 @@ func bStart(m *tb.Message) {
func bMy(m *tb.Message) {
logger.Println(strconv.FormatInt(m.Chat.ID, 10) + " Start Manager Users")
data := QueryDataByTG(m.Chat.ID)
data := db.QueryDataByTG(m.Chat.ID)
var inlineKeys [][]tb.InlineButton
for _, u := range data {
inlineBtn := tb.InlineButton{
Unique: "my" + u.msId,
Text: u.alias,
Data: u.msId,
Unique: "my" + u.MsId,
Text: u.Alias,
Data: u.MsId,
}
bot.Handle(&inlineBtn, bMyInlineBtn)
inlineKeys = append(inlineKeys, []tb.InlineButton{inlineBtn})
@ -97,16 +101,16 @@ func bMy(m *tb.Message) {
}
func bMyInlineBtn(c *tb.Callback) {
logger.Println(strconv.FormatInt(c.Message.Chat.ID, 10) + " Get User Info")
r := QueryDataByMS(c.Data)
r := db.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"))
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.Respond(c)
}
func bBind1(m *tb.Message) {
logger.Println(strconv.FormatInt(m.Chat.ID, 10) + " Start Bind")
logger.Println("ReApp: " + strconv.FormatInt(m.Chat.ID, 10))
bot.Send(m.Chat, "应用注册: [点击直达]("+MSGetReAppUrl()+")", tb.ModeMarkdown)
bot.Send(m.Chat, "应用注册: [点击直达]("+outlook.MSGetReAppUrl()+")", tb.ModeMarkdown)
_, err := bot.Send(m.Chat, "请回复client_id+空格+client_secret", &tb.ReplyMarkup{ForceReply: true})
if err != nil {
logger.Println(err)
@ -120,14 +124,14 @@ func bBind2(m *tb.Message) {
logger.Println("Auth: " + strconv.FormatInt(m.Chat.ID, 10))
tmp := strings.Split(m.Text, " ")
if len(tmp) != 2 {
logger.Printf("%d Bind error:Wrong Bind Format\n", m.Chat.ID)
logger.Println("%d Bind error:Wrong Bind Format\n", m.Chat.ID)
bot.Send(m.Chat, "错误的格式")
return
}
logger.Println("client_id: " + tmp[0] + " client_secret: " + tmp[1])
cid := tmp[0]
cse := tmp[1]
bot.Send(m.Chat, "授权账户: [点击直达]("+MSGetAuthUrl(cid)+")", tb.ModeMarkdown)
bot.Send(m.Chat, "授权账户: [点击直达]("+outlook.MSGetAuthUrl(cid)+")", tb.ModeMarkdown)
_, err := bot.Send(m.Chat, "请回复http://localhost/…… + 空格 + 别名(用于管理)", &tb.ReplyMarkup{ForceReply: true})
if err != nil {
logger.Println(err)
@ -140,13 +144,13 @@ func bBind2(m *tb.Message) {
func bUnBind(m *tb.Message) {
logger.Println(strconv.FormatInt(m.Chat.ID, 10) + " Start Unbind")
data := QueryDataByTG(m.Chat.ID)
data := db.QueryDataByTG(m.Chat.ID)
var inlineKeys [][]tb.InlineButton
for _, u := range data {
inlineBtn := tb.InlineButton{
Unique: "unbind" + u.msId,
Text: u.alias,
Data: u.msId,
Unique: "unbind" + u.MsId,
Text: u.Alias,
Data: u.MsId,
}
bot.Handle(&inlineBtn, bUnBindInlineBtn)
inlineKeys = append(inlineKeys, []tb.InlineButton{inlineBtn})
@ -155,14 +159,14 @@ func bUnBind(m *tb.Message) {
}
func bUnBindInlineBtn(c *tb.Callback) {
logger.Println(strconv.FormatInt(c.Message.Chat.ID, 10) + " Unbind: " + c.Data)
r := QueryDataByMS(c.Data)
r := db.QueryDataByMS(c.Data)
u := r[0]
if ok, _ := DelData(u.msId); !ok {
logger.Println(u.msId + " UnBind ERROR")
if ok, _ := db.DelData(u.MsId); !ok {
logger.Println(u.MsId + " UnBind ERROR")
bot.Send(c.Message.Chat, "解绑失败!")
return
}
logger.Println(u.msId + " UnBind Success")
logger.Println(u.MsId + " UnBind Success")
bot.Send(c.Message.Chat, "解绑成功!")
bot.Respond(c)
}
@ -176,18 +180,18 @@ func bExport(m *tb.Message) {
Other string
}
var MsMini []MsMiniData
data := QueryDataByTG(m.Chat.ID)
data := db.QueryDataByTG(m.Chat.ID)
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
ms.RefreshToken = u.RefreshToken
ms.Alias = u.Alias
ms.ClientId = u.ClientId
ms.ClientSecret = u.ClientSecret
ms.Other = u.Other
MsMini = append(MsMini, ms)
}
//MarshalIndent是为json+美化,/t表缩进
@ -278,7 +282,7 @@ func bLog(m *tb.Message) {
bot.Send(m.Chat, "您没有权限执行此操作~")
return
}
logs := GetRecentLogs(bLogBasePath, 5)
logs := util.GetRecentLogs(bLogBasePath, 5)
var inlineKeys [][]tb.InlineButton
for _, log := range logs {
inlineBtn := tb.InlineButton{

View File

@ -1,19 +1,21 @@
package main
package db
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
"main/logger"
"main/util"
)
type MSData struct {
tgId int64
refreshToken string
msId string
uptime int64
alias string
clientId string
clientSecret string
other string
TgId int64
RefreshToken string
MsId string
Uptime int64
Alias string
ClientId string
ClientSecret string
Other string
}
//update data by msId
@ -28,7 +30,7 @@ func UpdateData(u MSData) (bool, error) {
if err != nil {
return false, err
}
_, err = stmt.Exec(u.tgId, u.refreshToken, u.uptime, u.alias, u.clientId, u.clientSecret, u.other, u.msId)
_, err = stmt.Exec(u.TgId, u.RefreshToken, u.Uptime, u.Alias, u.ClientId, u.ClientSecret, u.Other, u.MsId)
if err != nil {
return false, err
}
@ -49,7 +51,7 @@ func AddData(u MSData) (bool, error) {
if err != nil {
return false, err
}
_, err = stmt.Exec(u.tgId, u.refreshToken, u.msId, u.uptime, u.alias, u.clientId, u.clientSecret, u.other)
_, err = stmt.Exec(u.TgId, u.RefreshToken, u.MsId, u.Uptime, u.Alias, u.ClientId, u.ClientSecret, u.Other)
if err != nil {
return false, err
}
@ -100,7 +102,7 @@ func QueryDataByMS(msId string) []MSData {
}
defer db.Close()
rows, err := db.Query("select * from users where ms_id = ?", msId)
CheckErr(err)
util.CheckErr(err)
return QueryData(rows)
}
@ -111,7 +113,7 @@ func QueryDataAll() []MSData {
}
defer db.Close()
rows, err := db.Query("select * from users ")
CheckErr(err)
util.CheckErr(err)
return QueryData(rows)
}
@ -123,7 +125,7 @@ func QueryDataByTG(tgId int64) []MSData {
}
defer db.Close()
rows, err := db.Query("select * from users where tg_id = ?", tgId)
CheckErr(err)
util.CheckErr(err)
return QueryData(rows)
}
func CreateTB() (bool, error) {

2
go.mod
View File

@ -9,6 +9,8 @@ require (
github.com/spf13/viper v1.6.2
github.com/tidwall/gjson v1.6.0
github.com/tidwall/pretty v1.0.1 // indirect
go.uber.org/zap v1.10.0
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e
gopkg.in/natefinch/lumberjack.v2 v2.0.0
gopkg.in/tucnak/telebot.v2 v2.0.0-20200328014118-dd123e949ee1
)

16
go.sum
View File

@ -20,6 +20,7 @@ github.com/Azure/azure-sdk-for-go v30.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9mo
github.com/Azure/azure-service-bus-go v0.9.1/go.mod h1:yzBx6/BUGfjfeqbRZny9AQIbIe3AcV9WZbAdpkoXOa0=
github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0=
github.com/Azure/go-autorest v12.0.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20191009163259-e802c2cb94ae/go.mod h1:mjwGPas4yKduTyubHvD1Atl9r1rUq8DfVy+gkVvZ+oo=
@ -63,6 +64,7 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
@ -119,6 +121,7 @@ github.com/google/wire v0.3.0/go.mod h1:i1DMg/Lu8Sz5yYl25iOdmc5CT5qusaa+zmRWs167
github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/goreleaser/goreleaser v0.129.0 h1:hJHsgxxNck3oe/MU4K+yznH2qgAVGNcxARTRP8ODSRk=
github.com/goreleaser/goreleaser v0.129.0/go.mod h1:tzHV+xcU9AJMYNby0QS0lHm1DRrTCBkJXW9ic2reepY=
@ -148,6 +151,7 @@ github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqx
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kamilsk/retry/v4 v4.7.2 h1:8C33aqTQtTSvPf7MpLZ4xSY4JZK2YCvY+hTlsbiHNq8=
@ -156,8 +160,10 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
@ -197,6 +203,7 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
@ -216,9 +223,11 @@ github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L
github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4SauJk4cUOwJs=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
@ -236,6 +245,7 @@ github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfD
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@ -270,8 +280,11 @@ go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
gocloud.dev v0.19.0 h1:EDRyaRAnMGSq/QBto486gWFxMLczAfIYUmusV7XLNBM=
gocloud.dev v0.19.0/go.mod h1:SmKwiR8YwIMMJvQBKLsC3fHNyMwXLw3PMDO+VVteJMI=
@ -393,11 +406,14 @@ google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/tucnak/telebot.v2 v2.0.0-20200301001213-9852df39ae6c h1:+7l/yyky9hchNME0hDMl+cA+wVlHQGte/5EwKHeSqoc=

41
logger/logger.go Normal file
View File

@ -0,0 +1,41 @@
package logger
import (
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
"os"
)
func Println(a ...interface{}) {
return
}
// 日志切割设置
func getLogWriter() zapcore.WriteSyncer {
lumberJackLogger := &lumberjack.Logger{
Filename: "./log/latest.log", // 日志文件位置
MaxSize: 1, // 日志文件最大大小(MB)
MaxBackups: 5, // 保留旧文件最大数量
MaxAge: 30, // 保留旧文件最长天数
Compress: true, // 是否压缩旧文件
}
return zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(lumberJackLogger))
}
// 编码器
func getEncoder() zapcore.Encoder {
// 使用默认的JSON编码
encoderConfig := zap.NewDevelopmentEncoderConfig()
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
return zapcore.NewJSONEncoder(encoderConfig)
}
// InitLogger 初始化Logger
func InitLogger() {
writeSyncer := getLogWriter()
encoder := getEncoder()
core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)
zap.ReplaceGlobals(zap.New(core, zap.AddCaller()))
}

132
main.go
View File

@ -1,135 +1,7 @@
package main
import (
"database/sql"
"fmt"
"github.com/robfig/cron/v3"
"github.com/spf13/viper"
"golang.org/x/net/proxy"
tb "gopkg.in/tucnak/telebot.v2"
"log"
"net/http"
"strconv"
"strings"
"time"
)
var (
BotToken string
Socks5 string
bot *tb.Bot
logger *log.Logger
)
const (
dbDriverName = "mysql"
logo = `
______ _____ _____ _ ____ _
| ____| ____/ ____| | | | _ \ | |
| |__ | |__| (___ _ _| |__ | |_) | ___ | |_
| __| |___ \\___ \| | | | '_ \| _ < / _ \| __|
| |____ ___) |___) | |_| | |_) | |_) | (_) | |_
|______|____/_____/ \__,_|_.__/|____/ \___/ \__|
`
)
var dbPath string
import "main/bots"
func main() {
BotStart()
}
func BotStart() {
MakeHandle()
TaskLaunch()
logger.Println("Bot Start")
fmt.Println("------------")
bot.Start()
}
func MakeHandle() {
logger.Println("Make Handle……")
//所有用户
bot.Handle("/start", bStart)
bot.Handle("/my", bMy)
bot.Handle("/bind", bBind1)
bot.Handle("/unbind", bUnBind)
bot.Handle("/export", bExport)
bot.Handle("/help", bHelp)
bot.Handle(tb.OnText, bOnText)
//管理员
bot.Handle("/task", bTask)
bot.Handle("/log", bLog)
}
func TaskLaunch() {
task := cron.New()
//每三小时执行一次
task.AddFunc(viper.GetString("cron"), SignTask)
//log分为每天
task.AddFunc(" 0 0 * * *", InitLogger)
// */1 * * * * 1 */3 * * *
logger.Println("Cron Task Start……")
task.Start()
}
func init() {
fmt.Println(logo)
InitLogger()
//read config
logger.Println("Read Config……")
viper.SetConfigName("config")
viper.AddConfigPath(".")
err := viper.ReadInConfig()
if err != nil {
logger.Fatal(err)
}
host := viper.GetString("mysql.host")
user := viper.GetString("mysql.user")
port := viper.GetString("mysql.port")
pwd := viper.GetString("mysql.password")
database := viper.GetString("mysql.database")
dbPath = strings.Join([]string{user, ":", pwd, "@tcp(", host, ":", port, ")/", database, "?charset=utf8"}, "")
//fmt.Println(path)
db, err := sql.Open(dbDriverName, dbPath)
if err != nil {
logger.Fatal(err)
}
logger.Println("Connect MySQL Success!")
if ok, err := CreateTB(); !ok {
logger.Fatal(err)
}
defer db.Close()
BotToken = viper.GetString("bot_token")
Socks5 = viper.GetString("socks5")
//set bot
logger.Println("Bot Settings……")
Poller := &tb.LongPoller{Timeout: 15 * time.Second}
spamProtected := tb.NewMiddlewarePoller(Poller, func(upd *tb.Update) bool {
if upd.Message == nil {
return true
}
if !upd.Message.Private() {
return false
}
return true
})
botsettings := tb.Settings{
Token: BotToken,
Poller: spamProtected,
}
//set socks5
if Socks5 != "" {
logger.Println("Proxy:" + Socks5)
dialer, err := proxy.SOCKS5("tcp", Socks5, nil, proxy.Direct)
if err != nil {
logger.Println(err)
}
httpTransport := &http.Transport{}
httpClient := &http.Client{Transport: httpTransport}
httpTransport.Dial = dialer.Dial
botsettings.Client = httpClient
}
//create bot
bot, err = tb.NewBot(botsettings)
if err != nil {
logger.Fatal(err)
}
logger.Println("Bot: " + strconv.Itoa(bot.Me.ID) + " " + bot.Me.Username)
bots.BotStart()
}

View File

@ -1,9 +1,10 @@
package main
package outlook
import (
"errors"
"github.com/tidwall/gjson"
"io/ioutil"
"main/logger"
"net/http"
"net/url"
"strings"

View File

@ -1,4 +1,4 @@
package main
package util
import (
"crypto/md5"