This commit is contained in:
iyear 2020-04-03 13:19:53 +08:00
parent 92f18f29af
commit 077b7533dc
6 changed files with 127 additions and 95 deletions

View File

@ -5,6 +5,9 @@ import (
"github.com/spf13/viper"
"github.com/tidwall/gjson"
tb "gopkg.in/tucnak/telebot.v2"
"io"
"log"
"os"
"strconv"
"strings"
"time"
@ -14,19 +17,19 @@ var SignOk map[int64]int
//If Successfully return "",else return error information
func BindUser(m *tb.Message, cid, cse string) string {
fmt.Printf("%d Begin Bind\n", m.Chat.ID)
logger.Printf("%d Begin Bind\n", m.Chat.ID)
tmp := strings.Split(m.Text, " ")
if len(tmp) != 2 {
fmt.Printf("%d Bind error:Wrong Bind Format\n", m.Chat.ID)
logger.Printf("%d Bind error:Wrong Bind Format\n", m.Chat.ID)
return "授权格式错误"
}
fmt.Println("alias: " + tmp[1])
logger.Println("alias: " + tmp[1])
alias := tmp[1]
code := GetURLValue(tmp[0], "code")
//fmt.Println(code)
access, refresh := MSFirGetToken(code, cid, cse)
if refresh == "" {
fmt.Printf("%d Bind error:GetRefreshToken\n", m.Chat.ID)
logger.Printf("%d Bind error:GetRefreshToken\n", m.Chat.ID)
return "获取RefreshToken失败"
}
@ -35,7 +38,7 @@ func BindUser(m *tb.Message, cid, cse string) string {
info := MSGetUserInfo(access)
//fmt.Printf("TGID:%d Refresh Token: %s\n", m.Chat.ID, refresh)
if info == "" {
fmt.Printf("%d Bind error:Getinfo\n", m.Chat.ID)
logger.Printf("%d Bind error:Getinfo\n", m.Chat.ID)
return "获取用户信息错误"
}
@ -45,23 +48,23 @@ func BindUser(m *tb.Message, cid, cse string) string {
//TG的Data传递最高64bytes,一些msid超过了报错BUTTON_DATA_INVALID (0)采取md5
u.msId = Get16MD5Encode(gjson.Get(info, "id").String())
u.uptime = time.Now().Unix()
fmt.Println(u.uptime)
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) {
fmt.Printf("%d Bind error:MSUserHasExisted\n", m.Chat.ID)
logger.Printf("%d Bind error:MSUserHasExisted\n", m.Chat.ID)
return "该应用已经绑定过了,无需重复绑定"
}
//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(db, u); !ok {
fmt.Printf("%d Bind error: %s\n", m.Chat.ID, err)
logger.Printf("%d Bind error: %s\n", m.Chat.ID, err)
return "数据库写入错误"
}
fmt.Printf("%d Bind Successfully!\n", m.Chat.ID)
logger.Printf("%d Bind Successfully!\n", m.Chat.ID)
return ""
}
@ -109,14 +112,14 @@ func SignTask() {
se := u.msId + " ( @" + chat.Username + " )"
if access == "" {
e = "Sign ERROR:GetAccessToken"
fmt.Println(u.msId + e)
logger.Println(u.msId + e)
bot.Send(chat, pre+e, tmpBtn)
SignErr = append(SignErr, se)
continue
}
if !OutLookGetMails(access) {
e = "Sign ERROR:ReadMails"
fmt.Println(u.msId + " Sign ERROR:ReadMails")
logger.Println(u.msId + " Sign ERROR:ReadMails")
bot.Send(chat, pre+e, tmpBtn)
SignErr = append(SignErr, se)
continue
@ -124,7 +127,7 @@ func SignTask() {
u.uptime = time.Now().Unix()
if ok, err := UpdateData(db, u); !ok {
e = "Update Data ERROR:"
fmt.Printf("%s Update Data ERROR: %s\n", u.msId, err)
logger.Printf("%s Update Data ERROR: %s\n", u.msId, err)
bot.Send(chat, pre+e, tmpBtn)
SignErr = append(SignErr, se)
continue
@ -141,11 +144,14 @@ func SignTask() {
if !isSend[u.tgId] {
chat, err := bot.ChatByID(strconv.FormatInt(u.tgId, 10))
if err != nil {
fmt.Println("Send Result ERROR")
logger.Println("Send Result ERROR", err)
continue
}
//静默发送,过多消息很烦
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
}
}
@ -169,3 +175,19 @@ func GetAdmin() []int64 {
}
return result
}
func InitLogger() {
if !PathExists("./log/") {
os.Mkdir("./log/", 0773)
}
path := "./log/" + 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,7 +1,6 @@
package main
import (
"fmt"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
tb "gopkg.in/tucnak/telebot.v2"
@ -85,7 +84,7 @@ func bMyInlineBtn(c *tb.Callback) {
bot.Respond(c)
}
func bBind1(m *tb.Message) {
fmt.Println("ReApp: " + strconv.FormatInt(m.Chat.ID, 10))
logger.Println("ReApp: " + strconv.FormatInt(m.Chat.ID, 10))
bot.Send(m.Chat, "应用注册: [点击直达]("+MSGetReAppUrl()+")", tb.ModeMarkdown)
_, err := bot.Send(m.Chat, "请回复client_id+空格+client_secret", &tb.ReplyMarkup{ForceReply: true})
if err == nil {
@ -95,14 +94,14 @@ func bBind1(m *tb.Message) {
}
func bBind2(m *tb.Message) {
fmt.Println("Auth: " + strconv.FormatInt(m.Chat.ID, 10))
logger.Println("Auth: " + strconv.FormatInt(m.Chat.ID, 10))
tmp := strings.Split(m.Text, " ")
if len(tmp) != 2 {
fmt.Printf("%d Bind error:Wrong Bind Format\n", m.Chat.ID)
logger.Printf("%d Bind error:Wrong Bind Format\n", m.Chat.ID)
bot.Send(m.Chat, "错误的格式")
return
}
fmt.Println("client_id: " + tmp[0] + " client_secret: " + tmp[1])
logger.Println("client_id: " + tmp[0] + " client_secret: " + tmp[1])
cid := tmp[0]
cse := tmp[1]
bot.Send(m.Chat, "授权账户: [点击直达]("+MSGetAuthUrl(cid)+")", tb.ModeMarkdown)
@ -131,11 +130,11 @@ func bUnBindInlineBtn(c *tb.Callback) {
r := QueryDataByMS(db, c.Data)
u := r[0]
if ok, _ := DelData(db, u.msId); !ok {
fmt.Println(u.msId + " UnBind ERROR")
logger.Println(u.msId + " UnBind ERROR")
bot.Send(c.Message.Chat, "解绑失败!")
return
}
fmt.Println(u.msId + " UnBind Success")
logger.Println(u.msId + " UnBind Success")
bot.Send(c.Message.Chat, "解绑成功!")
bot.Respond(c)
}

97
main.go
View File

@ -7,8 +7,10 @@ import (
"github.com/spf13/viper"
"golang.org/x/net/proxy"
tb "gopkg.in/tucnak/telebot.v2"
"log"
"net/http"
"strconv"
"strings"
"time"
)
@ -17,6 +19,7 @@ var (
Socks5 string
bot *tb.Bot
db *sql.DB
logger *log.Logger
)
const (
@ -31,18 +34,67 @@ const (
`
)
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("/task", bTask)
bot.Handle("/bind", bBind1)
bot.Handle("/unbind", bUnBind)
bot.Handle("/help", bHelp)
bot.Handle(tb.OnText, bOnText)
}
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
fmt.Println("Read Config……")
logger.Println("Read Config……")
viper.SetConfigName("config")
viper.AddConfigPath(".")
err := viper.ReadInConfig()
CheckErr(err)
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")
path := strings.Join([]string{user, ":", pwd, "@tcp(", host, ":", port, ")/", database, "?charset=utf8"}, "")
//fmt.Println(path)
db, err = sql.Open(dbDriverName, path)
if err != nil {
logger.Fatal(err)
}
logger.Println("Connect MySQL Success!")
if ok, err := CreateTB(db); !ok {
logger.Fatal(err)
}
BotToken = viper.GetString("bot_token")
Socks5 = viper.GetString("socks5")
//set bot
fmt.Println("Bot Settings……")
logger.Println("Bot Settings……")
Poller := &tb.LongPoller{Timeout: 15 * time.Second}
spamProtected := tb.NewMiddlewarePoller(Poller, func(upd *tb.Update) bool {
if upd.Message == nil {
@ -59,9 +111,11 @@ func init() {
}
//set socks5
if Socks5 != "" {
fmt.Println("Proxy:" + Socks5)
logger.Println("Proxy:" + Socks5)
dialer, err := proxy.SOCKS5("tcp", Socks5, nil, proxy.Direct)
CheckErr(err)
if err != nil {
logger.Println(err)
}
httpTransport := &http.Transport{}
httpClient := &http.Client{Transport: httpTransport}
httpTransport.Dial = dialer.Dial
@ -70,36 +124,7 @@ func init() {
//create bot
bot, err = tb.NewBot(botsettings)
if err != nil {
fmt.Println("Create Bot ERROR!")
return
logger.Fatal(err)
}
fmt.Println("Bot: " + strconv.Itoa(bot.Me.ID) + " " + bot.Me.Username)
}
func main() {
BotStart()
}
func BotStart() {
MakeHandle()
TaskLaunch()
fmt.Println("Bot Start")
fmt.Println("------------")
bot.Start()
}
func MakeHandle() {
fmt.Println("Make Handle……")
bot.Handle("/start", bStart)
bot.Handle("/my", bMy)
bot.Handle("/task", bTask)
bot.Handle("/bind", bBind1)
bot.Handle("/unbind", bUnBind)
bot.Handle("/help", bHelp)
bot.Handle(tb.OnText, bOnText)
}
func TaskLaunch() {
task := cron.New()
//每三小时执行一次
task.AddFunc(viper.GetString("cron"), SignTask)
// */1 * * * * 1 */3 * * *
fmt.Println("Cron Task Start……")
task.Start()
logger.Println("Bot: " + strconv.Itoa(bot.Me.ID) + " " + bot.Me.Username)
}

View File

@ -2,10 +2,7 @@ package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/spf13/viper"
"strings"
)
type MSData struct {
@ -19,28 +16,6 @@ type MSData struct {
other string
}
func init() {
var err error
viper.SetConfigName("config")
viper.AddConfigPath(".")
err = viper.ReadInConfig()
CheckErr(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")
path := strings.Join([]string{user, ":", pwd, "@tcp(", host, ":", port, ")/", database, "?charset=utf8"}, "")
//fmt.Println(path)
db, err = sql.Open(dbDriverName, path)
if !CheckErr(err) {
fmt.Println("Connect MySQL ERROR:")
return
}
fmt.Println("Connect MySQL Success!")
CreateTB(db)
}
//update data by msId
func UpdateData(db *sql.DB, u MSData) (bool, error) {
sqlString := `UPDATE users set tg_id=?,refresh_token=?,uptime=?,alias=?,client_id=?,client_secret=?,other=? where ms_id=?`

View File

@ -1,7 +1,6 @@
package main
import (
"fmt"
"github.com/tidwall/gjson"
"io/ioutil"
"net/http"
@ -39,11 +38,17 @@ func MSFirGetToken(code, cid, cse string) (access string, refresh string) {
r.Form.Add("redirect_uri", redirectUri)
body := strings.NewReader(r.Form.Encode())
req, err := http.NewRequest("POST", MsApiUrl+"/common/oauth2/v2.0/token", body)
if err != nil {
logger.Println(err)
}
resp, err := client.Do(req)
if err != nil {
logger.Println(err)
}
defer resp.Body.Close()
content, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Fatal error ")
logger.Println(err)
}
if gjson.Get(string(content), "token_type").String() == "Bearer" {
return gjson.Get(string(content), "access_token").String(), gjson.Get(string(content), "refresh_token").String()
@ -67,11 +72,17 @@ func MSGetToken(refreshtoken, cid, cse string) (access string) {
body := strings.NewReader(r.Form.Encode())
//fmt.Println(body)
req, err := http.NewRequest("POST", MsApiUrl+"/common/oauth2/v2.0/token", body)
if err != nil {
logger.Println(err)
}
resp, err := client.Do(req)
if err != nil {
logger.Println(err)
}
defer resp.Body.Close()
content, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Fatal error ")
logger.Println(err)
}
//fmt.Println(string(content))
//fmt.Println(gjson.Get(string(content), "access_token").String())
@ -88,7 +99,7 @@ func MSGetUserInfo(accesstoken string) (json string) {
client := http.Client{}
req, err := http.NewRequest("GET", MsGraUrl+"/v1.0/me", nil)
if err != nil {
fmt.Println("MSGetUserInfo ERROR ")
logger.Println(err)
return ""
}
req.Header.Set("Authorization", accesstoken)
@ -106,7 +117,7 @@ func OutLookGetMails(accesstoken string) bool {
client := http.Client{}
req, err := http.NewRequest("GET", MsGraUrl+"/v1.0/me/messages", nil)
if err != nil {
fmt.Println("MSGetMils ERROR ")
logger.Println(err)
return false
}
req.Header.Set("Authorization", accesstoken)

16
util.go
View File

@ -20,15 +20,15 @@ func CheckErr(err error) bool {
}
return true
}
func FileExist(Path string) bool {
if _, err := os.Stat(Path); err != nil {
if os.IsNotExist(err) {
return false
} else {
CheckErr(err)
}
func PathExists(path string) bool {
_, err := os.Stat(path)
if err == nil {
return true
}
return true
if os.IsNotExist(err) {
return false
}
return false
}
func GetBetweenStr(str, start, end string) string {
n := strings.Index(str, start)