Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3fbaf7aeb6 | ||
|
|
3bc95e1317 | ||
|
|
cab6b2633e |
@@ -4,7 +4,7 @@ wechat:
|
|||||||
host: 10.0.0.73:19088
|
host: 10.0.0.73:19088
|
||||||
# 是否在启动的时候自动设置hook服务的回调
|
# 是否在启动的时候自动设置hook服务的回调
|
||||||
autoSetCallback: false
|
autoSetCallback: false
|
||||||
# 回调IP,如果是Docker运行,本参数必填,如果Docker修改了映射,格式为 ip:port
|
# 回调IP,如果是Docker运行,本参数必填(填auto表示自动,不适用于 docker 环境),如果Docker修改了映射,格式为 ip:port
|
||||||
callback: 10.0.0.51
|
callback: 10.0.0.51
|
||||||
# 转发到其他地址
|
# 转发到其他地址
|
||||||
forward:
|
forward:
|
||||||
|
|||||||
@@ -3,15 +3,20 @@ package handler
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
"github.com/sashabaranov/go-openai"
|
"github.com/sashabaranov/go-openai"
|
||||||
"go-wechat/client"
|
"go-wechat/client"
|
||||||
|
"go-wechat/common/current"
|
||||||
"go-wechat/config"
|
"go-wechat/config"
|
||||||
"go-wechat/entity"
|
"go-wechat/entity"
|
||||||
"go-wechat/model"
|
"go-wechat/model"
|
||||||
|
"go-wechat/service"
|
||||||
|
"go-wechat/types"
|
||||||
"go-wechat/utils"
|
"go-wechat/utils"
|
||||||
"log"
|
"log"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// handleAtMessage
|
// handleAtMessage
|
||||||
@@ -30,7 +35,7 @@ func handleAtMessage(m model.Message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 预处理一下发送的消息,用正则去掉@机器人的内容
|
// 预处理一下发送的消息,用正则去掉@机器人的内容
|
||||||
re := regexp.MustCompile(`@([^ ]+)`)
|
re := regexp.MustCompile(`@([^ | ]+)`)
|
||||||
matches := re.FindStringSubmatch(m.Content)
|
matches := re.FindStringSubmatch(m.Content)
|
||||||
if len(matches) > 0 {
|
if len(matches) > 0 {
|
||||||
// 过滤掉第一个匹配到的
|
// 过滤掉第一个匹配到的
|
||||||
@@ -46,6 +51,39 @@ func handleAtMessage(m model.Message) {
|
|||||||
Content: config.Conf.Ai.Personality,
|
Content: config.Conf.Ai.Personality,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 查询发信人前面几条文字信息,组装进来
|
||||||
|
var oldMessages []entity.Message
|
||||||
|
client.MySQL.Model(&entity.Message{}).
|
||||||
|
Where("msg_id != ?", m.MsgId).
|
||||||
|
Where("create_at >= DATE_SUB(NOW(),INTERVAL 30 MINUTE)").
|
||||||
|
Where("from_user = ? AND group_user = ? AND display_full_content LIKE ?", m.FromUser, m.GroupUser, "%在群聊中@了你").
|
||||||
|
Or("to_user = ? AND group_user = ?", m.FromUser, m.GroupUser).
|
||||||
|
Order("create_at desc").
|
||||||
|
Limit(4).Find(&oldMessages)
|
||||||
|
// 翻转数组
|
||||||
|
slice.Reverse(oldMessages)
|
||||||
|
// 循环填充消息
|
||||||
|
for _, message := range oldMessages {
|
||||||
|
// 剔除@机器人的内容
|
||||||
|
msgStr := message.Content
|
||||||
|
matches = re.FindStringSubmatch(msgStr)
|
||||||
|
if len(matches) > 0 {
|
||||||
|
// 过滤掉第一个匹配到的
|
||||||
|
msgStr = strings.Replace(msgStr, matches[0], "", 1)
|
||||||
|
}
|
||||||
|
// 填充消息
|
||||||
|
role := openai.ChatMessageRoleUser
|
||||||
|
if message.ToUser != current.GetRobotInfo().WxId {
|
||||||
|
// 如果收信人不是机器人,表示这条消息是 AI 发的
|
||||||
|
role = openai.ChatMessageRoleAssistant
|
||||||
|
}
|
||||||
|
messages = append(messages, openai.ChatCompletionMessage{
|
||||||
|
Role: role,
|
||||||
|
Content: msgStr,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 填充用户消息
|
// 填充用户消息
|
||||||
messages = append(messages, openai.ChatCompletionMessage{
|
messages = append(messages, openai.ChatCompletionMessage{
|
||||||
Role: openai.ChatMessageRoleUser,
|
Role: openai.ChatMessageRoleUser,
|
||||||
@@ -63,8 +101,8 @@ func handleAtMessage(m model.Message) {
|
|||||||
if config.Conf.Ai.BaseUrl != "" {
|
if config.Conf.Ai.BaseUrl != "" {
|
||||||
conf.BaseURL = fmt.Sprintf("%s/v1", config.Conf.Ai.BaseUrl)
|
conf.BaseURL = fmt.Sprintf("%s/v1", config.Conf.Ai.BaseUrl)
|
||||||
}
|
}
|
||||||
client := openai.NewClientWithConfig(conf)
|
ai := openai.NewClientWithConfig(conf)
|
||||||
resp, err := client.CreateChatCompletion(
|
resp, err := ai.CreateChatCompletion(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
openai.ChatCompletionRequest{
|
openai.ChatCompletionRequest{
|
||||||
Model: chatModel,
|
Model: chatModel,
|
||||||
@@ -78,6 +116,18 @@ func handleAtMessage(m model.Message) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 保存一下AI 返回的消息,消息 Id 使用传入 Id 的负数
|
||||||
|
var replyMessage entity.Message
|
||||||
|
replyMessage.MsgId = -m.MsgId
|
||||||
|
replyMessage.CreateTime = int(time.Now().Local().Unix())
|
||||||
|
replyMessage.CreateAt = time.Now().Local()
|
||||||
|
replyMessage.Content = resp.Choices[0].Message.Content
|
||||||
|
replyMessage.FromUser = current.GetRobotInfo().WxId // 发信人是机器人
|
||||||
|
replyMessage.GroupUser = m.GroupUser // 群成员
|
||||||
|
replyMessage.ToUser = m.FromUser // 收信人是发信人
|
||||||
|
replyMessage.Type = types.MsgTypeText
|
||||||
|
service.SaveMessage(replyMessage) // 保存消息
|
||||||
|
|
||||||
// 发送消息
|
// 发送消息
|
||||||
utils.SendMessage(m.FromUser, m.GroupUser, "\n"+resp.Choices[0].Message.Content, 0)
|
utils.SendMessage(m.FromUser, m.GroupUser, "\n"+resp.Choices[0].Message.Content, 0)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ wechat:
|
|||||||
host: wechat:19088
|
host: wechat:19088
|
||||||
# 是否在启动的时候自动设置hook服务的回调
|
# 是否在启动的时候自动设置hook服务的回调
|
||||||
autoSetCallback: true
|
autoSetCallback: true
|
||||||
# 回调IP,如果是Docker运行,本参数必填,如果Docker修改了映射,格式为 ip:port,如果使用项目提供的docker-compsoe.yaml文件启动,可以不写
|
# 回调IP,如果是Docker运行,本参数必填,如果Docker修改了映射,格式为 ip:port,如果使用项目提供的docker-compsoe.yaml文件启动,可以填`auto`
|
||||||
callback:
|
callback: auto
|
||||||
|
|
||||||
# 数据库
|
# 数据库
|
||||||
mysql:
|
mysql:
|
||||||
|
|||||||
@@ -4,12 +4,18 @@ import (
|
|||||||
"go-wechat/client"
|
"go-wechat/client"
|
||||||
"go-wechat/entity"
|
"go-wechat/entity"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SaveMessage
|
// SaveMessage
|
||||||
// @description: 消息入库
|
// @description: 消息入库
|
||||||
// @param msg
|
// @param msg
|
||||||
func SaveMessage(msg entity.Message) {
|
func SaveMessage(msg entity.Message) {
|
||||||
|
if flag, _ := strconv.ParseBool(os.Getenv("DONT_SAVE")); flag {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 检查消息是否存在,存在就跳过
|
// 检查消息是否存在,存在就跳过
|
||||||
var count int64
|
var count int64
|
||||||
err := client.MySQL.Model(&entity.Message{}).Where("msg_id = ?", msg.MsgId).Count(&count).Error
|
err := client.MySQL.Model(&entity.Message{}).Where("msg_id = ?", msg.MsgId).Count(&count).Error
|
||||||
@@ -18,6 +24,7 @@ func SaveMessage(msg entity.Message) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
|
//log.Printf("消息已存在,消息Id: %d", msg.MsgId)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = client.MySQL.Create(&msg).Error
|
err = client.MySQL.Create(&msg).Error
|
||||||
|
|||||||
@@ -29,7 +29,11 @@ func ClearCallback() {
|
|||||||
// @param host
|
// @param host
|
||||||
func SetCallback(userHost string) {
|
func SetCallback(userHost string) {
|
||||||
// 获取本机IP地址
|
// 获取本机IP地址
|
||||||
host := net.ParseIP(netutil.GetInternalIp()).String()
|
host := userHost
|
||||||
|
if userHost == "auto" {
|
||||||
|
host = net.ParseIP(netutil.GetInternalIp()).String()
|
||||||
|
}
|
||||||
|
|
||||||
port := 19099
|
port := 19099
|
||||||
if userHost != "" {
|
if userHost != "" {
|
||||||
uh := strings.Split(strings.TrimSpace(userHost), ":")
|
uh := strings.Split(strings.TrimSpace(userHost), ":")
|
||||||
|
|||||||
Reference in New Issue
Block a user