支持qq推送与交互
This commit is contained in:
parent
a2b3bc14a9
commit
ffff6a9992
|
@ -49,6 +49,12 @@ type Config struct {
|
|||
Port int `json:"port" yaml:"port" mapstructure:"port"`
|
||||
CommonUser map[string]string `json:"common_user" yaml:"common_user" mapstructure:"common_user"`
|
||||
} `json:"web" yaml:"web" mapstructure:"web"`
|
||||
QQ struct {
|
||||
Enable bool `json:"enable" mapstructure:"enable"`
|
||||
PostAddr string `json:"post_addr" mapstructure:"post_addr"`
|
||||
SuperUser int64 `json:"super_user" mapstructure:"super_user"`
|
||||
WhiteList []int64 `json:"white_list" mapstructure:"white_list"`
|
||||
}
|
||||
Cron string `json:"cron" yaml:"cron" mapstructure:"cron"`
|
||||
CronRandomWait int `json:"cron_random_wait" yaml:"cron_random_wait" mapstructure:"cron_random_wait"`
|
||||
EdgePath string `json:"edge_path" yaml:"edge_path" mapstructure:"edge_path"`
|
||||
|
|
|
@ -81,6 +81,15 @@ wechat:
|
|||
# 微信管理员的openid,可点击关于按钮获得,配置后请重启程序
|
||||
super_open_id: ""
|
||||
|
||||
# gocq推送配置
|
||||
qq:
|
||||
# 是否启用qq推送
|
||||
enable: false
|
||||
# gocq的监听地址
|
||||
post_addr: "http://127.0.0.1:5700"
|
||||
super_user: 123
|
||||
white_list:
|
||||
- 123
|
||||
|
||||
# pushDeer推送配置,详情参考psuhDeer官网:http://www.pushdeer.com/official.html
|
||||
push_deer:
|
||||
|
|
4
main.go
4
main.go
|
@ -149,6 +149,10 @@ func main() {
|
|||
engine := web.RouterInit()
|
||||
go func() {
|
||||
h := http.NewServeMux()
|
||||
if config.QQ.Enable {
|
||||
h.Handle("/qq", push.InitQQ())
|
||||
log.Infoln(fmt.Sprintf("已开启qq配置,监听地址: ==》 %v:%v", config.Web.Host, config.Web.Port))
|
||||
}
|
||||
if config.Web.Enable {
|
||||
log.Infoln(fmt.Sprintf("已开启web配置,web监听地址 ==> %v:%v", config.Web.Host, config.Web.Port))
|
||||
h.Handle("/", engine)
|
||||
|
|
|
@ -69,7 +69,7 @@ func changeStatus(uid string, status int) {
|
|||
func QueryFailUser() ([]*User, error) {
|
||||
var users []*User
|
||||
_ = engine.Ping()
|
||||
err := engine.Where("status=", 0).Find(users)
|
||||
err := engine.Where("status=?", 0).Find(&users)
|
||||
if err != nil {
|
||||
return users, err
|
||||
}
|
||||
|
|
|
@ -49,6 +49,13 @@ func GetPush(config conf.Config) func(id string, kind string, message string) {
|
|||
log.Infoln("已配置pushDeer推送")
|
||||
pushs = append(pushs, InitPushDeer())
|
||||
}
|
||||
if config.QQ.Enable {
|
||||
log.Infoln("已配置qq推送")
|
||||
pushs = append(pushs, func(id, kind, message string) {
|
||||
e := &Event{qq: qq}
|
||||
e.sendPrivateMsg(conf.GetConfig().QQ.SuperUser, message)
|
||||
})
|
||||
}
|
||||
pushs = append(pushs, func(id, kind, message string) {
|
||||
log.Debugln(fmt.Sprintf("消息id: %v,消息类型:%v,消息内容:%v", id, kind, message))
|
||||
})
|
||||
|
|
|
@ -0,0 +1,333 @@
|
|||
package push
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/tidwall/gjson"
|
||||
|
||||
"github.com/johlanse/study_xxqg/conf"
|
||||
"github.com/johlanse/study_xxqg/lib"
|
||||
"github.com/johlanse/study_xxqg/lib/state"
|
||||
"github.com/johlanse/study_xxqg/model"
|
||||
"github.com/johlanse/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, args []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(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().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().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())
|
||||
}
|
Loading…
Reference in New Issue