Compare commits
No commits in common. "89c504d019fec95d47d3f3cf1779ab24639aece1" and "454b5f0980e3b3ac17de8f1599f6aba6fabc19f9" have entirely different histories.
89c504d019
...
454b5f0980
@ -62,29 +62,6 @@ func ChangeEnableGroupRankStatus(ctx *gin.Context) {
|
|||||||
ctx.String(http.StatusOK, "操作成功")
|
ctx.String(http.StatusOK, "操作成功")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChangeEnableWelcomeStatus
|
|
||||||
// @description: 修改是否开启迎新
|
|
||||||
// @param ctx
|
|
||||||
func ChangeEnableWelcomeStatus(ctx *gin.Context) {
|
|
||||||
var p changeStatusParam
|
|
||||||
if err := ctx.ShouldBindJSON(&p); err != nil {
|
|
||||||
ctx.String(http.StatusBadRequest, "参数错误")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Printf("待修改的群Id:%s", p.WxId)
|
|
||||||
|
|
||||||
err := client.MySQL.Model(&entity.Friend{}).
|
|
||||||
Where("wxid = ?", p.WxId).
|
|
||||||
Update("`enable_welcome`", gorm.Expr(" !`enable_welcome`")).Error
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("修改开启迎新失败:%s", err)
|
|
||||||
ctx.String(http.StatusInternalServerError, "操作失败: %s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.String(http.StatusOK, "操作成功")
|
|
||||||
}
|
|
||||||
|
|
||||||
// ChangeSkipGroupRankStatus
|
// ChangeSkipGroupRankStatus
|
||||||
// @description: 修改是否跳过水群排行榜
|
// @description: 修改是否跳过水群排行榜
|
||||||
// @param ctx
|
// @param ctx
|
||||||
|
@ -14,7 +14,6 @@ type Friend struct {
|
|||||||
PinyinAll string `json:"pinyinAll"` // 昵称全拼
|
PinyinAll string `json:"pinyinAll"` // 昵称全拼
|
||||||
EnableAi bool `json:"enableAI" gorm:"type:tinyint(1) default 0 not null"` // 是否使用AI
|
EnableAi bool `json:"enableAI" gorm:"type:tinyint(1) default 0 not null"` // 是否使用AI
|
||||||
EnableChatRank bool `json:"enableChatRank" gorm:"type:tinyint(1) default 0 not null"` // 是否使用聊天排行
|
EnableChatRank bool `json:"enableChatRank" gorm:"type:tinyint(1) default 0 not null"` // 是否使用聊天排行
|
||||||
EnableWelcome bool `json:"enableWelcome" gorm:"type:tinyint(1) default 0 not null"` // 是否启用迎新
|
|
||||||
IsOk bool `json:"isOk" gorm:"type:tinyint(1) default 0 not null"` // 是否正常
|
IsOk bool `json:"isOk" gorm:"type:tinyint(1) default 0 not null"` // 是否正常
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,10 +4,9 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/sashabaranov/go-openai"
|
"github.com/sashabaranov/go-openai"
|
||||||
"go-wechat/client"
|
|
||||||
"go-wechat/config"
|
"go-wechat/config"
|
||||||
"go-wechat/entity"
|
"go-wechat/entity"
|
||||||
"go-wechat/model"
|
"go-wechat/service"
|
||||||
"go-wechat/utils"
|
"go-wechat/utils"
|
||||||
"log"
|
"log"
|
||||||
"regexp"
|
"regexp"
|
||||||
@ -17,15 +16,26 @@ import (
|
|||||||
// handleAtMessage
|
// handleAtMessage
|
||||||
// @description: 处理At机器人的消息
|
// @description: 处理At机器人的消息
|
||||||
// @param m
|
// @param m
|
||||||
func handleAtMessage(m model.Message) {
|
func handleAtMessage(m entity.Message) {
|
||||||
if !config.Conf.Ai.Enable {
|
if !config.Conf.Ai.Enable {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 取出所有启用了AI的好友或群组
|
// 取出所有启用了AI的好友或群组
|
||||||
var count int64
|
us, err := service.GetAllEnableAI()
|
||||||
client.MySQL.Model(&entity.Friend{}).Where("enable_ai IS TRUE").Where("wxid = ?", m.FromUser).Count(&count)
|
if err != nil {
|
||||||
if count < 1 {
|
utils.SendMessage(m.FromUser, m.GroupUser, "#系统异常\n"+err.Error(), 0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 判断是否启用,如果没有启用,直接返回
|
||||||
|
var canUse bool
|
||||||
|
for _, u := range us {
|
||||||
|
if u.Wxid == m.FromUser {
|
||||||
|
canUse = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !canUse {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,9 +63,9 @@ func handleAtMessage(m model.Message) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 配置模型
|
// 配置模型
|
||||||
chatModel := openai.GPT3Dot5Turbo0613
|
model := openai.GPT3Dot5Turbo0613
|
||||||
if config.Conf.Ai.Model != "" {
|
if config.Conf.Ai.Model != "" {
|
||||||
chatModel = config.Conf.Ai.Model
|
model = config.Conf.Ai.Model
|
||||||
}
|
}
|
||||||
|
|
||||||
// 默认使用AI回复
|
// 默认使用AI回复
|
||||||
@ -67,7 +77,7 @@ func handleAtMessage(m model.Message) {
|
|||||||
resp, err := client.CreateChatCompletion(
|
resp, err := client.CreateChatCompletion(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
openai.ChatCompletionRequest{
|
openai.ChatCompletionRequest{
|
||||||
Model: chatModel,
|
Model: model,
|
||||||
Messages: messages,
|
Messages: messages,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"go-wechat/model"
|
"go-wechat/model"
|
||||||
"go-wechat/service"
|
"go-wechat/service"
|
||||||
"go-wechat/types"
|
"go-wechat/types"
|
||||||
"go-wechat/utils"
|
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
@ -24,47 +23,43 @@ func Parse(remoteAddr net.Addr, msg []byte) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 提取出群成员信息
|
// 提取出群成员信息
|
||||||
//groupUser := ""
|
groupUser := ""
|
||||||
//msgStr := m.Content
|
msgStr := m.Content
|
||||||
if strings.Contains(m.FromUser, "@") {
|
if strings.Contains(m.FromUser, "@") {
|
||||||
// 群消息,处理一下消息和发信人
|
switch m.Type {
|
||||||
groupUser := strings.Split(m.Content, "\n")[0]
|
case types.MsgTypeRecalled:
|
||||||
groupUser = strings.ReplaceAll(groupUser, ":", "")
|
// 消息撤回
|
||||||
// 如果两个id一致,说明是系统发的
|
case types.MsgTypeSys:
|
||||||
if m.FromUser != groupUser {
|
// 系统消息
|
||||||
m.GroupUser = groupUser
|
go handleSysMessage(m)
|
||||||
}
|
default:
|
||||||
// 用户的操作单独提出来处理一下
|
// 默认消息处理
|
||||||
m.Content = strings.Join(strings.Split(m.Content, "\n")[1:], "\n")
|
groupUser = strings.Split(m.Content, "\n")[0]
|
||||||
}
|
groupUser = strings.ReplaceAll(groupUser, ":", "")
|
||||||
log.Printf("%s\n消息来源: %s\n群成员: %s\n消息类型: %v\n消息内容: %s", remoteAddr, m.FromUser, m.GroupUser, m.Type, m.Content)
|
|
||||||
|
|
||||||
// 异步处理消息
|
// 文字消息单独提出来处理一下
|
||||||
go func() {
|
msgStr = strings.Join(strings.Split(m.Content, "\n")[1:], "\n")
|
||||||
if m.IsNewUserJoin() {
|
|
||||||
// 欢迎新成员
|
|
||||||
go handleNewUserJoin(m)
|
|
||||||
} else if m.IsAt() {
|
|
||||||
// @机器人的消息
|
|
||||||
go handleAtMessage(m)
|
|
||||||
} else if !strings.Contains(m.FromUser, "@") && m.Type == types.MsgTypeText {
|
|
||||||
// 私聊消息处理
|
|
||||||
utils.SendMessage(m.FromUser, "", "暂未开启私聊AI", 0)
|
|
||||||
}
|
}
|
||||||
}()
|
}
|
||||||
|
log.Printf("%s\n消息来源: %s\n群成员: %s\n消息类型: %v\n消息内容: %s", remoteAddr, m.FromUser, groupUser, m.Type, msgStr)
|
||||||
|
|
||||||
// 转换为结构体之后入库
|
// 转换为结构体之后入库
|
||||||
var ent entity.Message
|
var ent entity.Message
|
||||||
ent.MsgId = m.MsgId
|
ent.MsgId = m.MsgId
|
||||||
ent.CreateTime = m.CreateTime
|
ent.CreateTime = m.CreateTime
|
||||||
ent.CreateAt = time.Unix(int64(m.CreateTime), 0)
|
ent.CreateAt = time.Unix(int64(m.CreateTime), 0)
|
||||||
ent.Content = m.Content
|
ent.Content = msgStr
|
||||||
ent.FromUser = m.FromUser
|
ent.FromUser = m.FromUser
|
||||||
ent.GroupUser = m.GroupUser
|
ent.GroupUser = groupUser
|
||||||
ent.ToUser = m.ToUser
|
ent.ToUser = m.ToUser
|
||||||
ent.Type = m.Type
|
ent.Type = m.Type
|
||||||
ent.DisplayFullContent = m.DisplayFullContent
|
ent.DisplayFullContent = m.DisplayFullContent
|
||||||
ent.Raw = string(msg)
|
ent.Raw = string(msg)
|
||||||
|
|
||||||
|
// 处理At机器人的消息
|
||||||
|
if strings.HasSuffix(m.DisplayFullContent, "在群聊中@了你") {
|
||||||
|
go handleAtMessage(ent)
|
||||||
|
}
|
||||||
|
|
||||||
go service.SaveMessage(ent)
|
go service.SaveMessage(ent)
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,19 @@
|
|||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go-wechat/client"
|
|
||||||
"go-wechat/entity"
|
|
||||||
"go-wechat/model"
|
"go-wechat/model"
|
||||||
"go-wechat/utils"
|
"go-wechat/utils"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// handleNewUserJoin
|
// handleSysMessage
|
||||||
// @description: 欢迎新成员
|
// @description: 系统消息处理
|
||||||
// @param m
|
// @param m
|
||||||
func handleNewUserJoin(m model.Message) {
|
func handleSysMessage(m model.Message) {
|
||||||
// 判断是否开启迎新
|
// 有人进群
|
||||||
var count int64
|
if strings.Contains(m.Content, "\"邀请\"") && strings.Contains(m.Content, "\"加入了群聊") {
|
||||||
client.MySQL.Model(&entity.Friend{}).Where("enable_welcome IS TRUE").Where("wxid = ?", m.FromUser).Count(&count)
|
// 发一张图乐呵乐呵
|
||||||
if count < 1 {
|
// 自己欢迎自己图片地址 D:\Share\emoticon\welcome-yourself.gif
|
||||||
return
|
utils.SendImage(m.FromUser, "D:\\Share\\emoticon\\welcome-yourself.gif", 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发一张图乐呵乐呵
|
|
||||||
|
|
||||||
// 自己欢迎自己图片地址 D:\Share\emoticon\welcome-yourself.gif
|
|
||||||
utils.SendImage(m.FromUser, "D:\\Share\\emoticon\\welcome-yourself.gif", 0)
|
|
||||||
}
|
}
|
||||||
|
@ -1,87 +1,18 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import "go-wechat/types"
|
||||||
"encoding/xml"
|
|
||||||
"go-wechat/types"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Message
|
// Message
|
||||||
// @description: 消息
|
// @description: 消息
|
||||||
type Message struct {
|
type Message struct {
|
||||||
MsgId int64 `json:"msgId"`
|
MsgId int64 `json:"msgId" gorm:"primarykey"`
|
||||||
CreateTime int `json:"createTime"`
|
CreateTime int `json:"createTime"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
DisplayFullContent string `json:"displayFullContent"`
|
DisplayFullContent string `json:"displayFullContent" gorm:"-"`
|
||||||
FromUser string `json:"fromUser"`
|
FromUser string `json:"fromUser"`
|
||||||
GroupUser string `json:"-"`
|
|
||||||
MsgSequence int `json:"msgSequence"`
|
MsgSequence int `json:"msgSequence"`
|
||||||
Pid int `json:"pid"`
|
Pid int `json:"pid"`
|
||||||
Signature string `json:"signature"`
|
Signature string `json:"signature"`
|
||||||
ToUser string `json:"toUser"`
|
ToUser string `json:"toUser"`
|
||||||
Type types.MessageType `json:"type"`
|
Type types.MessageType `json:"type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// systemMsgDataXml
|
|
||||||
// @description: 微信系统消息的xml结构
|
|
||||||
type systemMsgDataXml struct {
|
|
||||||
SysMsg sysMsg `xml:"sysmsg"`
|
|
||||||
Type string `xml:"type,attr"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// sysMsg
|
|
||||||
// @description: 消息主体
|
|
||||||
type sysMsg struct{}
|
|
||||||
|
|
||||||
// IsPat
|
|
||||||
// @description: 是否是拍一拍消息
|
|
||||||
// @receiver m
|
|
||||||
// @return bool
|
|
||||||
func (m Message) IsPat() bool {
|
|
||||||
// 解析xml
|
|
||||||
var d systemMsgDataXml
|
|
||||||
if err := xml.Unmarshal([]byte(m.Content), &d); err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return m.Type == types.MsgTypeRecalled && d.Type == "pat"
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsRevokeMsg
|
|
||||||
// @description: 是否是撤回消息
|
|
||||||
// @receiver m
|
|
||||||
// @return bool
|
|
||||||
func (m Message) IsRevokeMsg() bool {
|
|
||||||
// 解析xml
|
|
||||||
var d systemMsgDataXml
|
|
||||||
if err := xml.Unmarshal([]byte(m.Content), &d); err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return m.Type == types.MsgTypeRecalled && d.Type == "revokemsg"
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsNewUserJoin
|
|
||||||
// @description: 是否是新人入群
|
|
||||||
// @receiver m
|
|
||||||
// @return bool
|
|
||||||
func (m Message) IsNewUserJoin() bool {
|
|
||||||
sysFlag := m.Type == types.MsgTypeSys && strings.Contains(m.Content, "\"邀请\"") && strings.Contains(m.Content, "\"加入了群聊")
|
|
||||||
if sysFlag {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
// 解析另一种情况
|
|
||||||
var d systemMsgDataXml
|
|
||||||
if err := xml.Unmarshal([]byte(m.Content), &d); err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return m.Type == types.MsgTypeSys && d.Type == "delchatroommember"
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsAt
|
|
||||||
// @description: 是否是At机器人的消息
|
|
||||||
// @receiver m
|
|
||||||
// @return bool
|
|
||||||
func (m Message) IsAt() bool {
|
|
||||||
return strings.HasSuffix(m.DisplayFullContent, "在群聊中@了你")
|
|
||||||
}
|
|
||||||
|
@ -22,7 +22,6 @@ func Init(g *gin.Engine) {
|
|||||||
// 接口
|
// 接口
|
||||||
api := g.Group("/api")
|
api := g.Group("/api")
|
||||||
api.PUT("/ai/status", app.ChangeEnableAiStatus) // 修改是否开启AI状态
|
api.PUT("/ai/status", app.ChangeEnableAiStatus) // 修改是否开启AI状态
|
||||||
api.PUT("/welcome/status", app.ChangeEnableWelcomeStatus) // 修改是否开启迎新状态
|
|
||||||
api.PUT("/grouprank/status", app.ChangeEnableGroupRankStatus) // 修改是否开启水群排行榜状态
|
api.PUT("/grouprank/status", app.ChangeEnableGroupRankStatus) // 修改是否开启水群排行榜状态
|
||||||
api.PUT("/grouprank/skip", app.ChangeSkipGroupRankStatus) // 修改是否跳过水群排行榜状态
|
api.PUT("/grouprank/skip", app.ChangeSkipGroupRankStatus) // 修改是否跳过水群排行榜状态
|
||||||
api.GET("/group/users", app.GetGroupUsers) // 获取群成员列表
|
api.GET("/group/users", app.GetGroupUsers) // 获取群成员列表
|
||||||
|
@ -65,7 +65,6 @@ func Sync() {
|
|||||||
Pinyin: friend.Pinyin,
|
Pinyin: friend.Pinyin,
|
||||||
PinyinAll: friend.PinyinAll,
|
PinyinAll: friend.PinyinAll,
|
||||||
Wxid: friend.Wxid,
|
Wxid: friend.Wxid,
|
||||||
IsOk: true,
|
|
||||||
}).Error
|
}).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("新增好友失败: %s", err.Error())
|
log.Printf("新增好友失败: %s", err.Error())
|
||||||
|
@ -4,7 +4,6 @@ import "fmt"
|
|||||||
|
|
||||||
type MessageType int
|
type MessageType int
|
||||||
|
|
||||||
// 微信定义的消息类型
|
|
||||||
const (
|
const (
|
||||||
MsgTypeText MessageType = 1 // 文本消息
|
MsgTypeText MessageType = 1 // 文本消息
|
||||||
MsgTypeImage MessageType = 3 // 图片消息
|
MsgTypeImage MessageType = 3 // 图片消息
|
||||||
|
@ -90,7 +90,6 @@
|
|||||||
<th>是否在通讯录</th>
|
<th>是否在通讯录</th>
|
||||||
<th>是否启用AI</th>
|
<th>是否启用AI</th>
|
||||||
<th>是否启用水群排行榜</th>
|
<th>是否启用水群排行榜</th>
|
||||||
<th>是否启用迎新</th>
|
|
||||||
<th>操作</th>
|
<th>操作</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -135,14 +134,6 @@
|
|||||||
<div class="swap-off">❌已禁用</div>
|
<div class="swap-off">❌已禁用</div>
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
|
||||||
<label class="swap swap-flip {{ checkSwap .EnableWelcome }}">
|
|
||||||
<input type="checkbox" onclick="changeWelcomeEnableStatus({{.Wxid}})"/>
|
|
||||||
|
|
||||||
<div class="swap-on">✔️已启用</div>
|
|
||||||
<div class="swap-off">❌已禁用</div>
|
|
||||||
</label>
|
|
||||||
</td>
|
|
||||||
<td>
|
<td>
|
||||||
<button class="btn btn-link" onclick="getGroupUsers({{.Wxid}}, {{.Nickname}})">查看群成员</button>
|
<button class="btn btn-link" onclick="getGroupUsers({{.Wxid}}, {{.Nickname}})">查看群成员</button>
|
||||||
</td>
|
</td>
|
||||||
|
@ -35,22 +35,6 @@ function changeGroupRankEnableStatus(wxId) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 修改欢迎语开启状态
|
|
||||||
function changeWelcomeEnableStatus(wxId) {
|
|
||||||
axios({
|
|
||||||
method: 'put',
|
|
||||||
url: '/api/welcome/status',
|
|
||||||
data: {
|
|
||||||
wxId: wxId
|
|
||||||
}
|
|
||||||
}).then(function (response) {
|
|
||||||
console.log(`返回结果: ${JSON.stringify(response)}`);
|
|
||||||
}).catch(function (error) {
|
|
||||||
console.log(`错误信息: ${error}`);
|
|
||||||
alert("修改失败")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 修改群成员是否参与排行榜状态
|
// 修改群成员是否参与排行榜状态
|
||||||
function changeUserGroupRankSkipStatus(groupId, userId) {
|
function changeUserGroupRankSkipStatus(groupId, userId) {
|
||||||
console.log("修改水群排行榜开启状态: ", groupId, userId)
|
console.log("修改水群排行榜开启状态: ", groupId, userId)
|
||||||
|
@ -14,7 +14,6 @@ type FriendItem struct {
|
|||||||
Wxid string // 微信原始Id
|
Wxid string // 微信原始Id
|
||||||
EnableAi bool // 是否使用AI
|
EnableAi bool // 是否使用AI
|
||||||
EnableChatRank bool // 是否使用聊天排行
|
EnableChatRank bool // 是否使用聊天排行
|
||||||
EnableWelcome bool // 是否使用迎新
|
|
||||||
IsOk bool // 是否还在通讯库(群聊是要还在群里也算)
|
IsOk bool // 是否还在通讯库(群聊是要还在群里也算)
|
||||||
LastActiveTime types.DateTime // 最后活跃时间
|
LastActiveTime types.DateTime // 最后活跃时间
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user