study_xxqg/push/qq.go

334 lines
8.0 KiB
Go

package push
import (
"encoding/json"
"fmt"
"io"
"net/http"
"strconv"
"strings"
log "github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
"github.com/sjkhsl/study_xxqg/conf"
"github.com/sjkhsl/study_xxqg/lib"
"github.com/sjkhsl/study_xxqg/lib/state"
"github.com/sjkhsl/study_xxqg/model"
"github.com/sjkhsl/study_xxqg/utils"
)
var (
qq *QQ
)
type qqPlugin func(event *Event, args []string)
type QQ struct {
postAdd string
plugins map[string]qqPlugin
}
func InitQQ() *QQ {
config := conf.GetConfig()
q := new(QQ)
qq = q
q.postAdd = config.QQ.PostAddr
q.plugins = make(map[string]qqPlugin, 1)
q.newPlugin("user", qqGetUser)
q.newPlugin("score", qqGetScore)
q.newPlugin("fail", qqGetFailUser)
q.newPlugin("study", qqStudy)
q.newPlugin("login", qqLogin)
q.newPlugin("help", qqHelp)
return q
}
func (q *QQ) newPlugin(text string, plugin qqPlugin) {
q.plugins[text] = plugin
}
func (q *QQ) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
data, _ := io.ReadAll(request.Body)
go q.handle(data)
writer.WriteHeader(204)
}
func (q *QQ) handle(data []byte) {
defer func() {
err := recover()
if err != nil {
log.Errorln("qq消息处理错误")
}
}()
config := conf.GetConfig()
e := new(Event)
err := json.Unmarshal(data, e)
if err != nil {
log.Errorln(err.Error())
return
}
e.qq = q
if e.PostType == "message" {
log.Infoln("收到qq消息 ==》 " + e.Message)
// 遍历白名单列表
for _, id := range config.QQ.WhiteList {
if e.GroupId == id || e.UserId == id {
for text, plugin := range q.plugins {
messages := strings.Split(e.Message, " ")
if messages[0] == "."+text {
plugin(e, messages[1:])
return
}
}
}
}
log.Infoln("消息来源不在白名单中!")
}
}
func qqHelp(event *Event, _ []string) {
help := ".user 查询用户\n.fail 查询过期用户\n.study 对一个用户进行学习\n.score 查询用户分数\n.login 登录一个用户"
event.Send(help)
}
func qqLogin(event *Event, _ []string) {
core := &lib.Core{ShowBrowser: conf.GetConfig().ShowBrowser, Push: func(id string, kind string, message string) {
if kind == "flush" {
event.Send(message)
} else {
if conf.GetConfig().LogLevel == "debug" {
event.Send(message)
}
}
}}
_, err := core.L(conf.GetConfig().Retry.Times, "")
if err != nil {
event.Send(err.Error())
}
}
func qqStudy(event *Event, args []string) {
users, err := model.Query()
if err != nil {
event.Send(err.Error())
return
}
var user *model.User
if len(users) == 1 {
user = users[0]
} else {
if len(args) <= 0 {
event.Send("缺少序号参数,请输入 .study 序号")
return
} else {
index, err := strconv.Atoi(args[0])
if err != nil {
event.Send(err.Error())
return
}
user = users[index]
}
}
core := &lib.Core{ShowBrowser: conf.GetConfig().ShowBrowser, Push: func(id string, kind string, message string) {
if kind == "flush" {
event.Send(message)
} else {
if conf.GetConfig().LogLevel == "debug" {
event.Send(message)
}
}
}}
core.Init()
state.Add(user.Uid, core)
defer state.Delete(user.Uid)
defer core.Quit()
lib.Study(core, user)
}
func qqGetScore(event *Event, _ []string) {
users, err := model.Query()
if err != nil {
event.Send(err.Error())
return
}
for _, user := range users {
score, err := lib.GetUserScore(user.ToCookies())
if err != nil {
event.Send(err.Error())
continue
}
event.Send(user.Nick + "\n" + lib.FormatScore(score))
}
}
func qqGetFailUser(event *Event, _ []string) {
user, err := model.QueryFailUser()
if err != nil {
event.Send(err.Error())
return
}
result := ""
for i, user := range user {
result += fmt.Sprintf("%d %v %v\n", i, user.Nick, utils.Stamp2Str(user.LoginTime))
}
event.Send(result)
}
func qqGetUser(event *Event, _ []string) {
users, err := model.Query()
if err != nil {
event.Send(err.Error())
return
}
result := ""
for i, user := range users {
result += fmt.Sprintf("%d %v %v\n", i, user.Nick, utils.Stamp2Str(user.LoginTime))
}
event.Send(result)
}
type (
anonymous struct {
Id int `json:"id"`
Name string `json:"name"`
Flag string `json:"flag"`
}
Files struct {
Id string `json:"id"`
Name string `json:"name"`
Size int64 `json:"size"`
Busid int64 `json:"busid"`
FileUrl string `json:"url"`
}
Status struct {
AppEnabled bool `json:"app_enabled"`
AppGood bool `json:"app_good"`
AppInitialized bool `json:"app_initialized"`
Good bool `json:"good"`
Online bool `json:"online"`
PluginsGood interface{} `json:"plugins_good"`
Stat struct {
PacketReceived int `json:"packet_received"`
PacketSent int `json:"packet_sent"`
PacketLost int `json:"packet_lost"`
MessageReceived int `json:"message_received"`
MessageSent int `json:"message_sent"`
DisconnectTimes int `json:"disconnect_times"`
LostTimes int `json:"lost_times"`
LastMessageTime int `json:"last_message_time"`
} `json:"stat"`
}
MessageIds struct {
MessageID int32 `json:"message_id"`
}
Senders struct {
Age int `json:"age"`
Area string `json:"area"`
Card string `json:"card"`
Level string `json:"level"`
NickName string `json:"nickname"`
Role string `json:"role"`
Sex string `json:"sex"`
Title string `json:"title"`
UserId int `json:"user_id"`
}
// Event
/*
* 事件
*
*/
Event struct {
qq *QQ
Anonymous anonymous `json:"anonymous"`
Font int `json:"font"`
GroupId int64 `json:"group_id"`
Message string `json:"message"`
MessageType string `json:"message_type"`
PostType string `json:"post_type"`
RawMessage string `json:"raw_message"`
SelfId int64 `json:"self_id"`
Sender Senders `json:"sender"`
SubType string `json:"sub_type"`
UserId int64 `json:"user_id"`
Time int `json:"time"`
NoticeType string `json:"notice_type"`
RequestType string `json:"request_type"`
Comment string `json:"comment"`
Flag string `json:"flag"`
OperatorID int `json:"operator_id"`
File Files `json:"file"`
Duration int64 `json:"duration"`
TargetId int64 `json:"target_id"` // 运气王id
HonorType string `json:"honor_type"`
MetaEventType string `json:"meta_event_type"`
Status Status `json:"status"`
Interval int `json:"interval"`
CardNew string `json:"card_new"` // 新名片
CardOld string `json:"card_old"` // 旧名片
MessageIds
GuildID int64 `json:"guild_id"`
ChannelID int64 `json:"channel_id"`
}
)
func (e *Event) sendGroupMsg(groupId int64, message any) int {
if _, ok := message.(string); ok {
message = map[string]any{
"type": "text",
"data": map[string]any{
"text": message,
},
}
}
response, err := utils.GetClient().R().SetHeader("Authorization", conf.GetConfig().QQ.AccessToken).SetBodyJsonMarshal(map[string]any{
"action": "send_group_msg",
"params": map[string]any{
"group_id": groupId,
"message": message,
},
}).Post(e.qq.postAdd)
if err != nil {
return 0
}
return int(gjson.GetBytes(response.Bytes(), "data").Int())
}
func (e *Event) Send(message any) {
if e.MessageType == "group" {
e.sendGroupMsg(e.GroupId, message)
} else {
e.sendPrivateMsg(e.UserId, message)
}
}
func (e *Event) sendPrivateMsg(userId int64, message any) int {
if _, ok := message.(string); ok {
message = map[string]any{
"type": "text",
"data": map[string]any{
"text": message,
},
}
}
response, err := utils.GetClient().R().SetHeader("Authorization", conf.GetConfig().QQ.AccessToken).SetBodyJsonMarshal(map[string]any{
"action": "send_private_msg",
"params": map[string]any{
"user_id": userId,
"message": message,
},
}).Post(e.qq.postAdd)
if err != nil {
return 0
}
return int(gjson.GetBytes(response.Bytes(), "data").Int())
}