tg交互支持群组,支持白名单配置

This commit is contained in:
johlanse 2022-08-12 15:14:26 +08:00
parent 57e2aef0c2
commit 66f1204889
4 changed files with 91 additions and 58 deletions

View File

@ -28,11 +28,12 @@ type Config struct {
} `json:"push_plus" yaml:"push_plus"` } `json:"push_plus" yaml:"push_plus"`
} `json:"push" yaml:"push"` } `json:"push" yaml:"push"`
TG struct { TG struct {
Enable bool `json:"enable" yaml:"enable"` Enable bool `json:"enable" yaml:"enable"`
Token string `json:"token" yaml:"token"` Token string `json:"token" yaml:"token"`
ChatID int64 `json:"chat_id" yaml:"chat_id"` ChatID int64 `json:"chat_id" yaml:"chat_id"`
Proxy string `json:"proxy" yaml:"proxy"` Proxy string `json:"proxy" yaml:"proxy"`
CustomApi string `json:"custom_api" yaml:"custom_api"` CustomApi string `json:"custom_api" yaml:"custom_api"`
WhiteList []int64 `json:"white_list" yaml:"white_list"`
} `json:"tg" yaml:"tg"` } `json:"tg" yaml:"tg"`
QQ struct { QQ struct {
} }

View File

@ -41,7 +41,9 @@ tg:
proxy: "" proxy: ""
# 自定义tg的api,可通过cloudflare搭建需自备域名 # 自定义tg的api,可通过cloudflare搭建需自备域名
custom_api: "https://api.telegram.org" custom_api: "https://api.telegram.org"
# 白名单id,包括群id或者用户id,若为空则允许所有群所有用户使用若仅用于单人直接配置上面的chat_id就可以
white_list:
- 123
# 网页端配置 # 网页端配置
web: web:
# 是否启用网页 # 是否启用网页

View File

@ -46,7 +46,9 @@ tg:
proxy: "" proxy: ""
# 自定义tg的api,可通过cloudflare搭建需自备域名 # 自定义tg的api,可通过cloudflare搭建需自备域名
custom_api: "https://api.telegram.org" custom_api: "https://api.telegram.org"
# 白名单id,包括群id或者用户id,若为空则允许所有群所有用户使用若仅用于单人直接配置上面的chat_id就可以
white_list:
- 123
# 网页端配置 # 网页端配置
web: web:
# 是否启用网页 # 是否启用网页

130
lib/tg.go
View File

@ -2,6 +2,7 @@ package lib
import ( import (
"encoding/base64" "encoding/base64"
"encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"net/url" "net/url"
@ -40,18 +41,18 @@ type Handle interface {
type Mather struct { type Mather struct {
command string command string
handle func(bot *Telegram, args []string) handle func(bot *Telegram, from int64, args []string)
} }
func (m Mather) getCommand() string { func (m Mather) getCommand() string {
return m.command return m.command
} }
func (m Mather) execute(bot *Telegram, args []string) { func (m Mather) execute(bot *Telegram, from int64, args []string) {
m.handle(bot, args) m.handle(bot, from, args)
} }
func newPlugin(command string, handle func(bot *Telegram, args []string)) { func newPlugin(command string, handle func(bot *Telegram, from int64, args []string)) {
handles.Store(command, handle) handles.Store(command, handle)
} }
@ -95,17 +96,39 @@ func (t *Telegram) Init() {
} }
channel := t.bot.GetUpdatesChan(tgbotapi.NewUpdate(1)) channel := t.bot.GetUpdatesChan(tgbotapi.NewUpdate(1))
t.SendMsg("你的学习强国小助手上线了!") t.SendMsg(0, "你的学习强国小助手上线了!")
go func() { go func() {
for { for {
update := <-channel update := <-channel
if update.Message == nil { if update.Message == nil {
update.Message = &tgbotapi.Message{Text: update.CallbackQuery.Data} if update.CallbackQuery != nil {
t.bot.Send(tgbotapi.NewDeleteMessage(conf.GetConfig().TG.ChatID, update.CallbackQuery.Message.MessageID)) update.Message = &tgbotapi.Message{Text: update.CallbackQuery.Data}
log.Infoln(update.CallbackQuery.Data) t.bot.Send(tgbotapi.NewDeleteMessage(conf.GetConfig().TG.ChatID, update.CallbackQuery.Message.MessageID))
log.Infoln(update.CallbackQuery.Data)
} else {
data, _ := json.Marshal(update)
log.Infoln(string(data))
return
}
} }
log.Infoln("收到tg消息 ", update)
if update.Message.Chat.Type == "group" || update.Message.Chat.Type == "supergroup" {
update.Message.Text = strings.ReplaceAll(update.Message.Text, "@"+t.bot.Self.UserName, "")
}
log.Infoln(fmt.Sprintf("收到tg消息,来自%v,内容 ==》 %v", update.Message.Chat.ID, update.Message.Text))
if len(conf.GetConfig().TG.WhiteList) > 0 {
inWhiteList := false
for _, id := range conf.GetConfig().TG.WhiteList {
if id == update.Message.Chat.ID {
inWhiteList = true
break
}
}
if !inWhiteList {
log.Infoln("已过滤非白名单的消息")
continue
}
}
handles.Range(func(key, value interface{}) bool { handles.Range(func(key, value interface{}) bool {
if strings.Split(update.Message.Text, " ")[0] == key.(string) { if strings.Split(update.Message.Text, " ")[0] == key.(string) {
go func() { go func() {
@ -116,7 +139,7 @@ func (t *Telegram) Init() {
log.Errorln("handle执行出现了不可挽回的错误") log.Errorln("handle执行出现了不可挽回的错误")
} }
}() }()
(value.(func(bot *Telegram, args []string)))(t, strings.Split(update.Message.Text, " ")[1:]) (value.(func(bot *Telegram, from int64, args []string)))(t, update.Message.Chat.ID, strings.Split(update.Message.Text, " ")[1:])
}() }()
} }
return true return true
@ -137,8 +160,8 @@ func (t *Telegram) Init() {
} }
} }
func (t *Telegram) SendPhoto(image []byte) { func (t *Telegram) SendPhoto(id int64, image []byte) {
photo := tgbotapi.NewPhoto(t.ChatId, tgbotapi.FileBytes{ photo := tgbotapi.NewPhoto(id, tgbotapi.FileBytes{
Name: "login code", Name: "login code",
Bytes: image, Bytes: image,
}) })
@ -150,8 +173,11 @@ func (t *Telegram) SendPhoto(image []byte) {
} }
} }
func (t *Telegram) SendMsg(message string) int { func (t *Telegram) SendMsg(id int64, message string) int {
msg := tgbotapi.NewMessage(t.ChatId, message) if id == 0 {
id = t.ChatId
}
msg := tgbotapi.NewMessage(id, message)
messa, err := t.bot.Send(msg) messa, err := t.bot.Send(msg)
if err != nil { if err != nil {
return 0 return 0
@ -159,7 +185,7 @@ func (t *Telegram) SendMsg(message string) int {
return messa.MessageID return messa.MessageID
} }
func login(bot *Telegram, args []string) { func login(bot *Telegram, from int64, args []string) {
config := conf.GetConfig() config := conf.GetConfig()
go func() { go func() {
defer func() { defer func() {
@ -176,17 +202,17 @@ func login(bot *Telegram, args []string) {
switch { switch {
case kind == "image": case kind == "image":
bytes, _ := base64.StdEncoding.DecodeString(message) bytes, _ := base64.StdEncoding.DecodeString(message)
bot.SendPhoto(bytes) bot.SendPhoto(from, bytes)
case kind == "markdown": case kind == "markdown":
newMessage := tgbotapi.NewMessage(bot.ChatId, message) newMessage := tgbotapi.NewMessage(bot.ChatId, message)
newMessage.ParseMode = tgbotapi.ModeMarkdownV2 newMessage.ParseMode = tgbotapi.ModeMarkdownV2
bot.bot.Send(newMessage) bot.bot.Send(newMessage)
case kind == "text": case kind == "text":
if log.GetLevel() == log.DebugLevel { if log.GetLevel() == log.DebugLevel {
bot.SendMsg(message) bot.SendMsg(from, message)
} }
case kind == "flush": case kind == "flush":
bot.SendMsg(message) bot.SendMsg(from, message)
} }
}, },
} }
@ -194,17 +220,17 @@ func login(bot *Telegram, args []string) {
defer core.Quit() defer core.Quit()
_, err := core.L(config.Retry.Times, "") _, err := core.L(config.Retry.Times, "")
if err != nil { if err != nil {
bot.SendMsg(err.Error()) bot.SendMsg(from, err.Error())
return return
} }
bot.SendMsg("登录成功") bot.SendMsg(from, "登录成功")
}() }()
} }
func getAllUser(bot *Telegram, args []string) { func getAllUser(bot *Telegram, from int64, args []string) {
users, err := model.Query() users, err := model.Query()
if err != nil { if err != nil {
bot.SendMsg("获取用户失败" + err.Error()) bot.SendMsg(from, "获取用户失败"+err.Error())
return return
} }
message := fmt.Sprintf("共获取到%v个有效用户信息\n", len(users)) message := fmt.Sprintf("共获取到%v个有效用户信息\n", len(users))
@ -212,21 +238,21 @@ func getAllUser(bot *Telegram, args []string) {
message += fmt.Sprintf("%v %v", i, user.Nick) message += fmt.Sprintf("%v %v", i, user.Nick)
message += "\n" message += "\n"
} }
bot.SendMsg(message) bot.SendMsg(from, message)
} }
func studyAll(bot *Telegram, args []string) { func studyAll(bot *Telegram, from int64, args []string) {
config := conf.GetConfig() config := conf.GetConfig()
users, err := model.Query() users, err := model.Query()
if err != nil { if err != nil {
bot.SendMsg(err.Error()) bot.SendMsg(from, err.Error())
return return
} }
if len(users) == 0 { if len(users) == 0 {
bot.SendMsg("未发现用户信息,请输入/login进行用户登录") bot.SendMsg(from, "未发现用户信息,请输入/login进行用户登录")
return return
} }
getAllUser(bot, args) getAllUser(bot, from, args)
for _, user := range users { for _, user := range users {
s := func() { s := func() {
core := Core{ core := Core{
@ -237,7 +263,7 @@ func studyAll(bot *Telegram, args []string) {
switch { switch {
case kind == "image": case kind == "image":
bytes, _ := base64.StdEncoding.DecodeString(message) bytes, _ := base64.StdEncoding.DecodeString(message)
bot.SendPhoto(bytes) bot.SendPhoto(from, bytes)
case kind == "markdown": case kind == "markdown":
newMessage := tgbotapi.NewMessage(bot.ChatId, message) newMessage := tgbotapi.NewMessage(bot.ChatId, message)
newMessage.ParseMode = tgbotapi.ModeMarkdownV2 newMessage.ParseMode = tgbotapi.ModeMarkdownV2
@ -245,10 +271,10 @@ func studyAll(bot *Telegram, args []string) {
case kind == "text": case kind == "text":
if log.GetLevel() == log.DebugLevel { if log.GetLevel() == log.DebugLevel {
bot.SendMsg(message) bot.SendMsg(from, message)
} }
case kind == "flush": case kind == "flush":
bot.SendMsg(message) bot.SendMsg(from, message)
} }
}, },
} }
@ -257,7 +283,7 @@ func studyAll(bot *Telegram, args []string) {
c := make(chan int, 1) c := make(chan int, 1)
go func() { go func() {
u := uuid.New().String() u := uuid.New().String()
bot.SendMsg("已创建运行实例:" + u) bot.SendMsg(from, "已创建运行实例:"+u)
datas.Store(u, &core) datas.Store(u, &core)
defer datas.Delete(u) defer datas.Delete(u)
core.Init() core.Init()
@ -273,7 +299,7 @@ func studyAll(bot *Telegram, args []string) {
select { select {
case <-timer: case <-timer:
{ {
bot.SendMsg("学习超时,请重新学习或检查日志") bot.SendMsg(from, "学习超时,请重新学习或检查日志")
log.Errorln("学习超时,已自动退出") log.Errorln("学习超时,已自动退出")
core.Quit() core.Quit()
} }
@ -282,37 +308,37 @@ func studyAll(bot *Telegram, args []string) {
} }
} }
score, _ := GetUserScore(user.ToCookies()) score, _ := GetUserScore(user.ToCookies())
bot.SendMsg(fmt.Sprintf("%v已学习完成\n%v", user.Nick, PrintScore(score))) bot.SendMsg(from, fmt.Sprintf("%v已学习完成\n%v", user.Nick, PrintScore(score)))
} }
s() s()
} }
} }
func study(bot *Telegram, args []string) { func study(bot *Telegram, from int64, args []string) {
config := conf.GetConfig() config := conf.GetConfig()
users, err := model.Query() users, err := model.Query()
if err != nil { if err != nil {
bot.SendMsg(err.Error()) bot.SendMsg(from, err.Error())
return return
} }
var user *model.User var user *model.User
switch { switch {
case len(users) == 1: case len(users) == 1:
bot.SendMsg("仅存在一名用户信息,自动进行学习") bot.SendMsg(from, "仅存在一名用户信息,自动进行学习")
user = users[0] user = users[0]
case len(users) == 0: case len(users) == 0:
bot.SendMsg("未发现用户信息,请输入/login进行用户登录") bot.SendMsg(from, "未发现用户信息,请输入/login进行用户登录")
return return
default: default:
if 0 < len(args) { if 0 < len(args) {
i, err := strconv.Atoi(args[0]) i, err := strconv.Atoi(args[0])
if err != nil { if err != nil {
bot.SendMsg(err.Error()) bot.SendMsg(from, err.Error())
return return
} }
user = users[i] user = users[i]
} else { } else {
msgID := bot.SendMsg("存在多名用户,未输入用户序号") msgID := bot.SendMsg(from, "存在多名用户,未输入用户序号")
markup := tgbotapi.InlineKeyboardMarkup{} markup := tgbotapi.InlineKeyboardMarkup{}
for i, user := range users { for i, user := range users {
markup.InlineKeyboard = append(markup.InlineKeyboard, append([]tgbotapi.InlineKeyboardButton{}, tgbotapi.NewInlineKeyboardButtonData(user.Nick, "/study "+strconv.Itoa(i)))) markup.InlineKeyboard = append(markup.InlineKeyboard, append([]tgbotapi.InlineKeyboardButton{}, tgbotapi.NewInlineKeyboardButtonData(user.Nick, "/study "+strconv.Itoa(i))))
@ -334,7 +360,7 @@ func study(bot *Telegram, args []string) {
switch { switch {
case kind == "image": case kind == "image":
bytes, _ := base64.StdEncoding.DecodeString(message) bytes, _ := base64.StdEncoding.DecodeString(message)
bot.SendPhoto(bytes) bot.SendPhoto(from, bytes)
case kind == "markdown": case kind == "markdown":
newMessage := tgbotapi.NewMessage(bot.ChatId, message) newMessage := tgbotapi.NewMessage(bot.ChatId, message)
newMessage.ParseMode = tgbotapi.ModeMarkdownV2 newMessage.ParseMode = tgbotapi.ModeMarkdownV2
@ -342,10 +368,10 @@ func study(bot *Telegram, args []string) {
case kind == "text": case kind == "text":
if log.GetLevel() == log.DebugLevel { if log.GetLevel() == log.DebugLevel {
bot.SendMsg(message) bot.SendMsg(from, message)
} }
case kind == "flush": case kind == "flush":
bot.SendMsg(message) bot.SendMsg(from, message)
} }
}, },
} }
@ -353,7 +379,7 @@ func study(bot *Telegram, args []string) {
c := make(chan int, 1) c := make(chan int, 1)
go func() { go func() {
u := uuid.New().String() u := uuid.New().String()
bot.SendMsg("已创建运行实例:" + u) bot.SendMsg(from, "已创建运行实例:"+u)
datas.Store(u, &core) datas.Store(u, &core)
defer datas.Delete(u) defer datas.Delete(u)
core.Init() core.Init()
@ -370,7 +396,7 @@ func study(bot *Telegram, args []string) {
case <-timer: case <-timer:
{ {
log.Errorln("学习超时,已自动退出") log.Errorln("学习超时,已自动退出")
bot.SendMsg("学习超时,请重新登录或检查日志") bot.SendMsg(from, "学习超时,请重新登录或检查日志")
core.Quit() core.Quit()
} }
case <-c: case <-c:
@ -379,32 +405,34 @@ func study(bot *Telegram, args []string) {
} }
} }
score, _ := GetUserScore(user.ToCookies()) score, _ := GetUserScore(user.ToCookies())
bot.SendMsg(fmt.Sprintf("%v已学习完成\n%v", user.Nick, PrintScore(score))) bot.SendMsg(from, fmt.Sprintf("%v已学习完成\n%v", user.Nick, PrintScore(score)))
} }
func getScores(bot *Telegram, args []string) { func getScores(bot *Telegram, from int64, args []string) {
users, err := model.Query() users, err := model.Query()
if err != nil { if err != nil {
log.Errorln(err.Error()) log.Errorln(err.Error())
bot.SendMsg("获取用户信息失败" + err.Error()) bot.SendMsg(from, "获取用户信息失败"+err.Error())
return return
} }
message := fmt.Sprintf("共获取到%v个有效用户信息\n", len(users)) message := ""
for _, user := range users { for _, user := range users {
message += user.Nick + "\n" message += user.Nick + "\n"
score, err := GetUserScore(user.ToCookies()) score, err := GetUserScore(user.ToCookies())
if err != nil { if err != nil {
message += err.Error() + "\n" message += err.Error() + "\n"
continue
} }
message += FormatScore(score) + "\n" message += FormatScore(score) + "\n"
bot.SendMsg(from, message)
message = ""
} }
bot.SendMsg(message)
} }
func quit(bot *Telegram, args []string) { func quit(bot *Telegram, from int64, args []string) {
if len(args) < 1 { if len(args) < 1 {
datas.Range(func(key, value interface{}) bool { datas.Range(func(key, value interface{}) bool {
bot.SendMsg("已退出运行实例" + key.(string)) bot.SendMsg(from, "已退出运行实例"+key.(string))
core := value.(*Core) core := value.(*Core)
core.Quit() core.Quit()
return true return true