feat: 添加telegram交互模式

This commit is contained in:
johlanse 2021-11-27 16:24:24 +08:00
parent ac07a680d8
commit d732df275b
11 changed files with 322 additions and 113 deletions

View File

@ -42,17 +42,19 @@ push:
enable: false
access_token: ""
secret: ""
tg:
enable: false
chat_id: ""
token: ""
# 目前仅支持pushplus推送二维码默认建议使用pushplus推送
# pushplus使用方法见http://www.pushplus.plus/
push_plus:
enable: true
token: ""
tg:
enable: false
chat_id: 0
token: ""
proxy: ""
# 设置是否定时执行学习程序格式为cron格式
# "9 19 * * *" 每天19点9分执行一次
# "* 10 * * *” 每天早上十点执行一次

View File

@ -18,16 +18,17 @@ type Config struct {
AccessToken string `json:"access_token" yaml:"access_token"`
Secret string `json:"secret" yaml:"secret"`
} `json:"ding" yaml:"ding"`
TG struct {
Enable bool `json:"enable" yaml:"enable"`
Token string `json:"token" yaml:"token"`
ChatID string `json:"chat_id" yaml:"chat_id"`
} `json:"tg" yaml:"tg"`
PushPlus struct {
Enable bool `json:"enable" yaml:"enable"`
Token string `json:"token" yaml:"token"`
} `json:"push_plus" yaml:"push_plus"`
} `json:"push" yaml:"push"`
TG struct {
Enable bool `json:"enable" yaml:"enable"`
Token string `json:"token" yaml:"token"`
ChatID int64 `json:"chat_id" yaml:"chat_id"`
Proxy string `json:"proxy" yaml:"proxy"`
} `json:"tg" yaml:"tg"`
Cron string `json:"cron"`
}

View File

@ -23,17 +23,19 @@ push:
enable: false
access_token: ""
secret: ""
tg:
enable: false
chat_id: ""
token: ""
# 目前仅支持pushplus推送二维码默认建议使用pushplus推送
# pushplus使用方法见http://www.pushplus.plus/
push_plus:
enable: true
token: ""
# telegram交互模式配置
tg:
enable: false
chat_id: 0
token: ""
proxy: ""
# 设置是否定时执行学习程序格式为cron格式
# "9 19 * * *" 每天19点9分执行一次
# "* 10 * * *” 每天早上十点执行一次

View File

@ -107,6 +107,13 @@ func (c *Core) Quit() {
}
func (c *Core) Login() ([]Cookie, error) {
defer func() {
i := recover()
if i != nil {
log.Errorln("登录模块出现无法挽救的错误")
log.Errorln(i)
}
}()
page, err := (*c.context).NewPage()
if err != nil {

View File

@ -25,7 +25,7 @@ func (c *Core) RespondDaily(cookies []Cookie, model string) {
defer func() {
err := recover()
if err != nil {
log.Errorln("答题模块异常结束")
log.Errorln("答题模块异常结束或答题已完成")
time.Sleep(5 * time.Second)
log.Errorln(err)
}
@ -51,7 +51,7 @@ func (c *Core) RespondDaily(cookies []Cookie, model string) {
return
}
log.Infoln("已加载每日答题模块")
log.Infoln("已加载答题模块")
_, err = page.Goto(MyPointsUri, playwright.PageGotoOptions{
Referer: playwright.String(MyPointsUri),
@ -171,6 +171,7 @@ func (c *Core) RespondDaily(cookies []Cookie, model string) {
return
}
_ = category.WaitForElementState(`visible`)
time.Sleep(1 * time.Second)
// 获取题目

View File

@ -3,6 +3,7 @@ package lib
import (
"errors"
"fmt"
"time"
"github.com/guonaihong/gout"
log "github.com/sirupsen/logrus"
@ -97,6 +98,24 @@ func GetUserScore(cookies []Cookie) (Score, error) {
}
func PrintScore(score Score) string {
result := ""
result += fmt.Sprintf("当前学习总积分:%d 今日得分:%d\n", score.TodayScore, score.TodayScore)
result += fmt.Sprintf("[%v] [INFO]: 登录:%v/%v 文章学习:%v/%v 视频学习:%v/%v 视频时长:%v/%v\n[%v] [INFO]: 每日答题:%v/%v 每周答题:%v/%v 专项答题:%v/%v",
time.Now().Format("2006-01-02 15:04:05"),
score.Content["login"].CurrentScore, score.Content["login"].MaxScore,
score.Content["article"].CurrentScore, score.Content["article"].MaxScore,
score.Content["video"].CurrentScore, score.Content["video"].MaxScore,
score.Content["video_time"].CurrentScore, score.Content["video_time"].MaxScore,
time.Now().Format("2006-01-02 15:04:05"),
score.Content["daily"].CurrentScore, score.Content["daily"].MaxScore,
score.Content["weekly"].CurrentScore, score.Content["weekly"].MaxScore,
score.Content["special"].CurrentScore, score.Content["special"].MaxScore,
)
log.Infoln(result)
return result
}
func foramet_score(score Score) string {
result := ""
result += fmt.Sprintf("当前学习总积分:%d 今日得分:%d\n", score.TodayScore, score.TodayScore)
result += fmt.Sprintf("登录:%v/%v 文章学习:%v/%v 视频学习:%v/%v 视频时长:%v/%v\n每日答题%v/%v 每周答题:%v/%v 专项答题:%v/%v",
@ -108,6 +127,5 @@ func PrintScore(score Score) string {
score.Content["weekly"].CurrentScore, score.Content["weekly"].MaxScore,
score.Content["special"].CurrentScore, score.Content["special"].MaxScore,
)
log.Infoln(result)
return result
}

View File

@ -201,13 +201,6 @@ func (c *Core) LearnVideo(cookies []Cookie) {
return
}
tryCount := 0
networkCookies, err := (*c.context).Cookies()
if err != nil {
return
}
for _, networkCookie := range networkCookies {
fmt.Println(networkCookie.Name)
}
for {
if tryCount < 20 {

252
lib/tg.go Normal file
View File

@ -0,0 +1,252 @@
package lib
import (
"encoding/base64"
"fmt"
"net/http"
"net/url"
"strconv"
"strings"
"sync"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
log "github.com/sirupsen/logrus"
)
var (
handles sync.Map
)
func init() {
newPlugin("/login", login)
newPlugin("/get_users", getAllUser)
newPlugin("/study", study)
newPlugin("/get_scores", getScores)
}
//Telegram
// @Description:
//
type Telegram struct {
Token string
ChatId int64
bot *tgbotapi.BotAPI
Proxy string
}
type Handle interface {
getCommand() string
execute(bot *Telegram, args []string)
}
type Mather struct {
command string
handle func(bot *Telegram, args []string)
}
func (m Mather) getCommand() string {
return m.command
}
func (m Mather) execute(bot *Telegram, args []string) {
m.handle(bot, args)
}
func newPlugin(command string, handle func(bot *Telegram, args []string)) {
handles.Store(command, handle)
}
//Init
/**
* @Description:
* @receiver t
* @return func(kind string, message string)
*/
func (t *Telegram) Init() {
uri, err := url.Parse(t.Proxy)
t.bot, err = tgbotapi.NewBotAPIWithClient(t.Token, tgbotapi.APIEndpoint, &http.Client{Transport: &http.Transport{
// 设置代理
Proxy: http.ProxyURL(uri),
}})
if err != nil {
log.Errorln("telegram token鉴权失败或代理使用失败")
log.Errorln(err.Error())
}
channel := t.bot.GetUpdatesChan(tgbotapi.NewUpdate(1))
go func() {
for {
update := <-channel
handles.Range(func(key, value interface{}) bool {
if strings.Split(update.Message.Text, " ")[0] == key.(string) {
go func() {
defer func() {
err := recover()
if err != nil {
}
}()
(value.(func(bot *Telegram, args []string)))(t, strings.Split(update.Message.Text, " ")[1:])
}()
}
return true
})
}
}()
_, err = t.bot.Request(tgbotapi.NewSetMyCommands(
tgbotapi.BotCommand{Command: "login", Description: "登录一个账号"},
tgbotapi.BotCommand{Command: "get_users", Description: "获取所有cookie有效的用户"},
tgbotapi.BotCommand{Command: "study", Description: "对一个账户进行学习"},
tgbotapi.BotCommand{Command: "get_scores", Description: "获取用户成绩"},
))
if err != nil {
return
}
}
func (t *Telegram) SendPhoto(image []byte) {
photo := tgbotapi.NewPhoto(t.ChatId, tgbotapi.FileBytes{
Name: "login code",
Bytes: image,
})
_, err := t.bot.Send(photo)
if err != nil {
log.Errorln("发送图片信息失败")
log.Errorln(err.Error())
return
}
}
func (t *Telegram) SendMsg(message string) {
msg := tgbotapi.NewMessage(t.ChatId, message)
t.bot.Send(msg)
}
func login(bot *Telegram, args []string) {
log.Infoln(args)
go func() {
defer func() {
err := recover()
if err != nil {
log.Errorln(err)
}
}()
core := Core{
pw: nil,
browser: nil,
context: nil,
ShowBrowser: false,
Push: func(kind string, message string) {
if kind == "image" {
bytes, _ := base64.StdEncoding.DecodeString(message)
bot.SendPhoto(bytes)
} else if kind == "markdown" {
newMessage := tgbotapi.NewMessage(bot.ChatId, message)
newMessage.ParseMode = tgbotapi.ModeMarkdownV2
bot.bot.Send(newMessage)
} else {
bot.SendMsg(message)
}
},
}
core.Init()
defer core.Quit()
_, err := core.Login()
if err != nil {
bot.SendMsg(err.Error())
return
}
bot.SendMsg("登录成功")
}()
}
func getAllUser(bot *Telegram, args []string) {
users, err := GetUsers()
if err != nil {
bot.SendMsg("获取用户失败" + err.Error())
return
}
message := fmt.Sprintf("共获取到%v个有效用户信息\n", len(users))
for i, user := range users {
message += fmt.Sprintf("%v %v", i, user.Nick)
message += "\n"
}
bot.SendMsg(message)
}
func study(bot *Telegram, args []string) {
users, err := GetUsers()
if err != nil {
bot.SendMsg(err.Error())
return
}
var cookies []Cookie
if len(users) == 1 {
bot.SendMsg("仅存在一名用户信息,自动进行学习")
cookies = users[0].Cookies
} else if len(users) == 0 {
bot.SendMsg("未发现用户信息,请输入/login进行用户登录")
return
} else {
if len(args) < 0 {
bot.SendMsg("存在多名用户,未输入用户序号")
return
} else {
i, err := strconv.Atoi(args[0])
if err != nil {
bot.SendMsg(err.Error())
return
}
cookies = users[i].Cookies
}
}
core := Core{
pw: nil,
browser: nil,
context: nil,
ShowBrowser: false,
Push: func(kind string, message string) {
switch {
case kind == "image":
bytes, _ := base64.StdEncoding.DecodeString(message)
bot.SendPhoto(bytes)
case kind == "markdown":
newMessage := tgbotapi.NewMessage(bot.ChatId, message)
newMessage.ParseMode = tgbotapi.ModeMarkdownV2
_, _ = bot.bot.Send(newMessage)
default:
bot.SendMsg(message)
}
},
}
defer core.Quit()
core.LearnArticle(cookies)
core.LearnVideo(cookies)
core.RespondDaily(cookies, "daily")
core.RespondDaily(cookies, "daily")
core.RespondDaily(cookies, "weekly")
core.RespondDaily(cookies, "special")
}
func getScores(bot *Telegram, args []string) {
users, err := GetUsers()
if err != nil {
log.Errorln(err.Error())
bot.SendMsg("获取用户信息失败" + err.Error())
return
}
message := fmt.Sprintf("共获取到%v个有效用户信息\n", len(users))
for _, user := range users {
message += user.Nick + "\n"
score, err := GetUserScore(user.Cookies)
if err != nil {
message += err.Error() + "\n"
}
message += PrintScore(score) + "\n"
}
bot.SendMsg(message)
}

25
main.go
View File

@ -48,7 +48,9 @@ func init() {
}
func main() {
if config.Cron != "" {
switch {
case config.Cron != "":
log.Infoln("已采用定时执行模式")
c := cron.New()
_, err := c.AddFunc(config.Cron, func() {
defer func() {
@ -66,30 +68,43 @@ func main() {
}
c.Start()
select {}
case config.TG.Enable:
log.Infoln("已采用tg交互模式")
telegram := lib.Telegram{
Token: config.TG.Token,
ChatId: config.TG.ChatID,
Proxy: config.TG.Proxy,
}
telegram.Init()
select {}
default:
log.Infoln("已采用普通学习模式")
do()
}
}
func do() {
log.Infoln(`// 刷课模式默认为1
log.Infoln(` 刷课模式默认为1
1只刷文章何视频
2只刷文章和视频和每日答题
3刷文章和视频和每日答题每周答题和专项答题`)
log.Infoln("检测到模式", config.Model)
getPush := push.GetPush(config)
core := lib.Core{ShowBrowser: config.ShowBrowser, Push: getPush}
defer core.Quit()
core.Init()
var cookies []lib.Cookie
users, _ := lib.GetUsers()
if len(users) < 1 {
switch {
case len(users) < 1:
log.Infoln("未检测到有效用户信息,将采用登录模式")
cookies, _ = core.Login()
} else if len(users) == 1 {
case len(users) == 1:
log.Infoln("检测到1位有效用户信息采用默认用户")
cookies = users[0].Cookies
log.Infoln("已选择用户: ", users[0].Nick)
} else {
default:
for i, user := range users {
log.Infoln("序号:", i+1, " ===> ", user.Nick)
}

View File

@ -14,13 +14,6 @@ func GetPush(config lib.Config) func(kind string, message string) {
}
log.Infoln("已配置钉钉推送")
return ding.Send()
} else if config.Push.TG.Enable {
t := &Telegram{
Token: config.Push.TG.Token,
ChatId: config.Push.TG.ChatID,
}
log.Infoln("已配置telegram推送")
return t.Init()
} else if config.Push.PushPlus.Enable {
log.Infoln("已配置pushplus推送")
return (&PushPlus{Token: config.Push.PushPlus.Token}).Init()

View File

@ -1,75 +0,0 @@
package push
import (
"encoding/base64"
"net/http"
"net/url"
"strconv"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
log "github.com/sirupsen/logrus"
)
//Telegram
// @Description:
//
type Telegram struct {
Token string
ChatId string
}
//TGMsg
// @Description:
//
type TGMsg struct {
ChatID string `json:"chat_id"`
Text string `json:"text"`
ParseMode string `json:"parse_mode"`
}
//Init
/**
* @Description:
* @receiver t
* @return func(kind string, message string)
*/
func (t *Telegram) Init() func(kind string, message string) {
uri, err := url.Parse("http://127.0.0.1:7890")
bot, err := tgbotapi.NewBotAPIWithClient(t.Token, tgbotapi.APIEndpoint, &http.Client{Transport: &http.Transport{
// 设置代理
Proxy: http.ProxyURL(uri),
}})
if err != nil {
log.Errorln("telegram token鉴权失败")
return func(kind string, message string) {}
}
chatId, err := strconv.ParseInt(t.ChatId, 10, 64)
if err != nil {
return func(kind string, message string) {}
}
return func(kind string, message string) {
if kind == "image" {
bytes, _ := base64.StdEncoding.DecodeString(message)
photo := tgbotapi.NewPhoto(chatId, tgbotapi.FileBytes{
Name: "123",
Bytes: bytes,
})
_, err := bot.Send(photo)
if err != nil {
log.Errorln("发送图片信息失败")
log.Errorln(err.Error())
return
}
}
mess := tgbotapi.NewMessage(chatId, message)
mess.ParseMode = tgbotapi.ModeMarkdownV2
_, err := bot.Send(mess)
if err != nil {
log.Errorln("发送消息失败")
log.Errorln(err.Error())
return
}
}
}