Compare commits
11 Commits
f9921d2ba0
...
1d62e95910
Author | SHA1 | Date | |
---|---|---|---|
1d62e95910 | |||
980880533c | |||
58eb0d0b52 | |||
cee0d67de1 | |||
55c74ea17c | |||
31d401e213 | |||
c1dc0821e9 | |||
eb99e251bf | |||
cde4488548 | |||
aac5d05d13 | |||
d415621631 |
@ -45,7 +45,7 @@ const (
|
||||
MsgType_ImageMsgType MsgType = 2 //图片
|
||||
MsgType_AudioMsgType MsgType = 3 //音频
|
||||
MsgType_VideoMsgType MsgType = 4 //视频
|
||||
MsgType_FileType MsgType = 5 //文件
|
||||
MsgType_CardType MsgType = 5 //卡片
|
||||
)
|
||||
|
||||
// Enum value maps for MsgType.
|
||||
@ -56,7 +56,7 @@ var (
|
||||
2: "ImageMsgType",
|
||||
3: "AudioMsgType",
|
||||
4: "VideoMsgType",
|
||||
5: "FileType",
|
||||
5: "CardType",
|
||||
}
|
||||
MsgType_value = map[string]int32{
|
||||
"UnknownMsgType": 0,
|
||||
@ -64,7 +64,7 @@ var (
|
||||
"ImageMsgType": 2,
|
||||
"AudioMsgType": 3,
|
||||
"VideoMsgType": 4,
|
||||
"FileType": 5,
|
||||
"CardType": 5,
|
||||
}
|
||||
)
|
||||
|
||||
@ -11421,7 +11421,7 @@ var file_accountFiee_proto_rawDesc = []byte{
|
||||
0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4d, 0x73, 0x67, 0x54, 0x79, 0x70,
|
||||
0x65, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x41, 0x75, 0x64, 0x69, 0x6f, 0x4d, 0x73, 0x67, 0x54,
|
||||
0x79, 0x70, 0x65, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x4d, 0x73,
|
||||
0x67, 0x54, 0x79, 0x70, 0x65, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x54,
|
||||
0x67, 0x54, 0x79, 0x70, 0x65, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x61, 0x72, 0x64, 0x54,
|
||||
0x79, 0x70, 0x65, 0x10, 0x05, 0x32, 0xeb, 0x2b, 0x0a, 0x0b, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x46, 0x69, 0x65, 0x65, 0x12, 0x3c, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x19,
|
||||
0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x46, 0x69, 0x65, 0x65, 0x2e, 0x4c, 0x6f, 0x67,
|
||||
|
@ -869,7 +869,7 @@ enum MsgType{
|
||||
ImageMsgType = 2 ;//图片
|
||||
AudioMsgType = 3 ;//音频
|
||||
VideoMsgType = 4 ;//视频
|
||||
FileType = 5 ;//文件
|
||||
CardType = 5 ;//卡片
|
||||
}
|
||||
message ChatRecordData{
|
||||
int64 ID=1;
|
||||
|
@ -1,5 +1,5 @@
|
||||
[system]
|
||||
Domain = "fiee"
|
||||
Domain = "app"
|
||||
AppMode = "debug"
|
||||
HttpPort = ":8085"
|
||||
Host = "http://127.0.0.1:8085"
|
||||
@ -14,12 +14,12 @@ BosBaseDir = "fonchain-main"
|
||||
BosHttp = "https://"
|
||||
BosDomain = "cdns.fontree.cn"
|
||||
[oss]
|
||||
AccessKeyId = "LTAI5tLz1fSK53FQAEC9uNSb"
|
||||
AccessKeySecret = "oGB9chrQzQzITXR2IGv37Ji5WxZh4j"
|
||||
Endpoint = "oss-cn-hangzhou.aliyuncs.com"
|
||||
BucketName = "fontree-test"
|
||||
BaseDir = "fonchain-main"
|
||||
CdnHost = "https://cdn-test.szjixun.cn"
|
||||
AccessKeyId = "LTAI5tHfjSmWXHqfWgaL7Uo5"
|
||||
AccessKeySecret = "kOPctFZ3DHsbdSSym1fLyDK39hkzPI"
|
||||
Endpoint = "oss-cn-hangzhou-internal.aliyuncs.com"
|
||||
BucketName = "erp-k8s-store"
|
||||
BaseDir = "fiee"
|
||||
CdnHost = "https://e-cdn.fontree.cn"
|
||||
[redis]
|
||||
RedisDB = "2"
|
||||
RedisAddr = "127.0.0.1:6379"
|
||||
|
@ -27,7 +27,7 @@ Password = "Gy.123456"
|
||||
[oss]
|
||||
AccessKeyId = "LTAI5tHfjSmWXHqfWgaL7Uo5"
|
||||
AccessKeySecret = "kOPctFZ3DHsbdSSym1fLyDK39hkzPI"
|
||||
Endpoint = "oss-cn-hangzhou.aliyuncs.com"
|
||||
Endpoint = "oss-cn-hangzhou-internal.aliyuncs.com"
|
||||
BucketName = "erp-k8s-store"
|
||||
BaseDir = "fiee"
|
||||
CdnHost = "https://e-cdn.fontree.cn"
|
||||
|
@ -12,7 +12,13 @@ BucketName = "dci-file-new"
|
||||
BosUrl = ".bj.bcebos.com"
|
||||
BosBaseDir = "fonchain-main"
|
||||
BosHttp = "https://"
|
||||
|
||||
[oss]
|
||||
AccessKeyId = "LTAI5tHfjSmWXHqfWgaL7Uo5"
|
||||
AccessKeySecret = "kOPctFZ3DHsbdSSym1fLyDK39hkzPI"
|
||||
Endpoint = "oss-cn-hangzhou-internal.aliyuncs.com"
|
||||
BucketName = "erp-k8s-store"
|
||||
BaseDir = "fiee"
|
||||
CdnHost = "https://e-cdn.fontree.cn"
|
||||
[redis]
|
||||
RedisDB = "2"
|
||||
RedisAddr = "redis:6379"
|
||||
|
@ -136,11 +136,11 @@ func (o *ChatRoom) Run() {
|
||||
}
|
||||
}
|
||||
}
|
||||
o.clientsRwLocker.Unlock()
|
||||
//再把自己的客户端加入会话
|
||||
o.Session[newClient.SessionId] = append(o.Session[newClient.SessionId], newClient)
|
||||
}
|
||||
o.pushEvent(EventUserJoin, EventProgressAfter, nil, newClient)
|
||||
o.clientsRwLocker.Unlock()
|
||||
//注销事件
|
||||
case client := <-o.UnRegister:
|
||||
o.pushEvent(EventUserLeave, EventProgressBefore, nil, client)
|
||||
@ -190,10 +190,10 @@ func (o *ChatRoom) Register(c *Client) (sessionId string) {
|
||||
// sessionId: 会话id
|
||||
// msgType: 消息类型
|
||||
// message: 消息内容
|
||||
func (o *ChatRoom) SendSessionMessage(chatUser *accountFiee.ChatUserData, sessionId string, msgType WsType, message any) (userIdInSession []int64, err error) {
|
||||
func (o *ChatRoom) SendSessionMessage(sender *accountFiee.ChatUserData, sessionId string, msgType WsType, message any) (userIdInSession []int64, err error) {
|
||||
fmt.Println("ChatRoom.SendSessionMessage ------------------1")
|
||||
o.clientsRwLocker.Lock()
|
||||
defer o.clientsRwLocker.Unlock()
|
||||
//o.clientsRwLocker.Lock()
|
||||
//defer o.clientsRwLocker.Unlock()
|
||||
var msg = WsSessionInfo{
|
||||
Type: msgType,
|
||||
Content: message,
|
||||
@ -204,7 +204,7 @@ func (o *ChatRoom) SendSessionMessage(chatUser *accountFiee.ChatUserData, sessio
|
||||
err = fmt.Errorf("该会话不存在或已失效")
|
||||
return
|
||||
}
|
||||
fmt.Println("ChatRoom.SendSessionMessage - 1")
|
||||
fmt.Println("ChatRoom.SendSessionMessage ------------------3")
|
||||
usableClients := []*Client{}
|
||||
fmt.Printf("sessionId:[%s],客户端数量%d\n", sessionId, len(o.Session[sessionId]))
|
||||
for i, client := range o.Session[sessionId] {
|
||||
@ -212,13 +212,13 @@ func (o *ChatRoom) SendSessionMessage(chatUser *accountFiee.ChatUserData, sessio
|
||||
_, exist := o.clients[client.UserId][client.ClientId]
|
||||
if exist {
|
||||
usableClients = append(usableClients, o.Session[sessionId][i])
|
||||
o.pushEvent(EventChatMessage, EventProgressBefore, chatUser, o.Session[sessionId][i], message)
|
||||
go o.pushEvent(EventChatMessage, EventProgressBefore, sender, o.Session[sessionId][i], message)
|
||||
}
|
||||
}
|
||||
fmt.Printf("client:%+v\n", client)
|
||||
if client != nil && client.UserId != chatUser.ID {
|
||||
if client != nil && (client.UserId != sender.ID || sender.Role == 3) {
|
||||
client.Send <- msgBytes
|
||||
o.pushEvent(EventChatMessage, EventProgressAfter, chatUser, o.Session[sessionId][i], message)
|
||||
go o.pushEvent(EventChatMessage, EventProgressAfter, sender, o.Session[sessionId][i], message)
|
||||
userIdInSession = append(userIdInSession, client.UserId)
|
||||
}
|
||||
//client.Send <- msgBytes
|
||||
@ -230,8 +230,6 @@ func (o *ChatRoom) SendSessionMessage(chatUser *accountFiee.ChatUserData, sessio
|
||||
}
|
||||
func (o *ChatRoom) GetUserIdInSession(sessionId string, withoutUserId ...int64) (userIds []int64) {
|
||||
fmt.Printf("sessionId:%s withoutUserId:%d\n", sessionId, withoutUserId)
|
||||
//o.clientsRwLocker.RLock()
|
||||
//defer o.clientsRwLocker.RUnlock()
|
||||
fmt.Println("GetUserIdInSession 1")
|
||||
if o.Session[sessionId] != nil {
|
||||
fmt.Printf("GetUserIdInSession 2,o.Session[sessionId]:%+v", o.Session[sessionId])
|
||||
@ -345,8 +343,8 @@ func (o *ChatRoom) UnRegisterEventListener(listenerChan *EventListener) {
|
||||
|
||||
// pushEvent 推送聊天室事件
|
||||
func (o *ChatRoom) pushEvent(eventType EventType, progress EventProgress, chatUser *accountFiee.ChatUserData, client *Client, data ...any) {
|
||||
o.EventRwLocker.Lock()
|
||||
defer o.EventRwLocker.Unlock()
|
||||
//o.EventRwLocker.Lock()
|
||||
//defer o.EventRwLocker.Unlock()
|
||||
for _, listener := range o.eventBus {
|
||||
hit := false
|
||||
for _, need := range listener.ListenEvents {
|
||||
@ -358,13 +356,20 @@ func (o *ChatRoom) pushEvent(eventType EventType, progress EventProgress, chatUs
|
||||
if hit == false {
|
||||
continue
|
||||
}
|
||||
msg := ""
|
||||
if data != nil {
|
||||
msg = fmt.Sprintf("%v", data[0])
|
||||
}
|
||||
listener.Chan <- ListenEventData{
|
||||
ListenEvent: ListenEvent{
|
||||
EventType: eventType,
|
||||
ProgressType: progress,
|
||||
},
|
||||
Client: client,
|
||||
Data: data,
|
||||
ChatUser: chatUser,
|
||||
Client: client,
|
||||
Msg: msg,
|
||||
Data: data,
|
||||
}
|
||||
fmt.Printf("chatRooom 推送事件给%s eventType:%v progress:%v", listener.Name, eventType, progress)
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,8 @@
|
||||
// -------------------------------------------
|
||||
package ws
|
||||
|
||||
import "fonchain-fiee/api/accountFiee"
|
||||
|
||||
// websocket 消息类型
|
||||
type WsType int
|
||||
|
||||
@ -42,8 +44,10 @@ type ListenEvent struct {
|
||||
}
|
||||
type ListenEventData struct {
|
||||
ListenEvent
|
||||
Client *Client
|
||||
Data any
|
||||
Client *Client
|
||||
ChatUser *accountFiee.ChatUserData
|
||||
Msg string
|
||||
Data any
|
||||
}
|
||||
type ListenEventChan chan ListenEventData
|
||||
type EventListener struct {
|
||||
|
@ -80,6 +80,7 @@ func AuthorizationVerify(sourceData []byte) (userInfo *accountFiee.ChatUserData,
|
||||
if err != nil || fontreeJwtInfo.IsOffline {
|
||||
check = false
|
||||
} else {
|
||||
check = true
|
||||
fmt.Printf("fontreeJwtInfo is %#v\n", fontreeJwtInfo)
|
||||
accountInfo.Origin = e.ErpDomain
|
||||
accountInfo.OriginId = int64(fontreeJwtInfo.ID)
|
||||
@ -147,6 +148,7 @@ func HandleMessage(sourceData []byte, cli *Client) {
|
||||
switch msg.Type {
|
||||
default:
|
||||
cli.Send <- WsErrorUnknownMessageType(msg.From)
|
||||
//fmt.Printf("不支持的ws业务消息:%#v\n", msg)
|
||||
case TestType:
|
||||
var newMsg = WsInfo{
|
||||
Type: TestType,
|
||||
|
@ -55,19 +55,37 @@ type MessageListType struct {
|
||||
ID int64 `json:"ID"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
UserId int64 `json:"userId"`
|
||||
Role int32 `json:"role,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Message Message `json:"message"`
|
||||
}
|
||||
|
||||
func (m *MessageListType) BuildMessage(data *accountFiee.ChatRecordData) {
|
||||
func (m *MessageListType) BuildMessage(data *accountFiee.ChatRecordData, role int32) {
|
||||
m.ID = data.ID
|
||||
m.CreatedAt = data.CreatedAt
|
||||
m.UserId = data.UserId
|
||||
m.Name = data.Name
|
||||
m.Role = role
|
||||
switch data.MsgType {
|
||||
default:
|
||||
m.Message.MsgType = data.MsgType
|
||||
m.Message.Text = data.Content
|
||||
m.Message.LocalStamp = data.LocalStamp
|
||||
if data.Medias != nil {
|
||||
for _, media := range data.Medias {
|
||||
m.Message.Media = append(m.Message.Media, MessageMedia{
|
||||
MediaId: media.ID,
|
||||
MediaSize: media.Size,
|
||||
Ext: media.Ext,
|
||||
Url: media.Url,
|
||||
ConvText: media.ConvText,
|
||||
Duration: media.Duration,
|
||||
})
|
||||
}
|
||||
}
|
||||
case accountFiee.MsgType_TextMsgType:
|
||||
m.Message = Message{
|
||||
MsgType: accountFiee.MsgType_TextMsgType,
|
||||
MsgType: data.MsgType,
|
||||
Text: data.Content,
|
||||
Media: []MessageMedia{},
|
||||
LocalStamp: data.LocalStamp,
|
||||
|
@ -42,9 +42,14 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var ChatHandlerIns = ChatHandler{
|
||||
cache: chatCache.ChatCache{NewMessageStatExpireAfter: 10 * time.Minute},
|
||||
robot: robot.NewRobot(),
|
||||
var ChatHandlerIns = NewChatHandler()
|
||||
|
||||
func NewChatHandler() ChatHandler {
|
||||
c := ChatHandler{
|
||||
cache: chatCache.ChatCache{NewMessageStatExpireAfter: 10 * time.Minute},
|
||||
}
|
||||
c.robot = robot.NewRobot(&c.cache)
|
||||
return c
|
||||
}
|
||||
|
||||
type ChatHandler struct {
|
||||
@ -317,7 +322,7 @@ func (cr ChatHandler) MessageList(c *gin.Context) {
|
||||
}
|
||||
returnDataIdList = append(returnDataIdList, message.ID)
|
||||
var msg = &dto.MessageListType{}
|
||||
msg.BuildMessage(message)
|
||||
msg.BuildMessage(message, 0)
|
||||
resp = append(resp, msg)
|
||||
}
|
||||
} else {
|
||||
@ -349,7 +354,7 @@ func (cr ChatHandler) MessageList(c *gin.Context) {
|
||||
total++
|
||||
returnDataIdList = append(returnDataIdList, message.ID)
|
||||
var msg = &dto.MessageListType{}
|
||||
msg.BuildMessage(message)
|
||||
msg.BuildMessage(message, 0)
|
||||
resp = append(resp, msg)
|
||||
}
|
||||
}
|
||||
@ -429,7 +434,7 @@ func (cr ChatHandler) Upload(c *gin.Context) {
|
||||
defer tmp.Close()
|
||||
fileBuffer := bytes.NewBuffer(fileContent)
|
||||
var bosUrl string
|
||||
bosUrl, err = upload.UploadWithBuffer(fileBuffer, fmt.Sprintf("fiee/%d/%v%v", chatUser.ID, filename, fileExt))
|
||||
bosUrl, err = upload.UploadWithBuffer(fileBuffer, fmt.Sprintf("%d/%v%v", chatUser.ID, filename, fileExt))
|
||||
if err != nil {
|
||||
service.Error(c, err)
|
||||
return
|
||||
|
@ -75,7 +75,7 @@ func NewMessage(ctx context.Context, cache *chatCache.ChatCache, chatUser *accou
|
||||
fmt.Println("NewMessage 6")
|
||||
//发送websocket消息提醒通知
|
||||
var notice = dto.MessageListType{}
|
||||
notice.BuildMessage(resp.Data)
|
||||
notice.BuildMessage(resp.Data, chatUser.Role)
|
||||
fmt.Printf("ws消息提醒:%+v\n", notice)
|
||||
_, err = consts.ChatRoom.SendSessionMessage(chatUser, request.SessionId, ws.NewChatMsgType, notice)
|
||||
if err != nil {
|
||||
|
@ -11,20 +11,22 @@ import (
|
||||
"fonchain-fiee/api/accountFiee"
|
||||
"fonchain-fiee/pkg/common/ws"
|
||||
"fonchain-fiee/pkg/service"
|
||||
"fonchain-fiee/pkg/service/asChat/consts"
|
||||
"fonchain-fiee/pkg/service/asChat/chatCache"
|
||||
"fonchain-fiee/pkg/service/asChat/dto"
|
||||
"fonchain-fiee/pkg/service/asChat/logic"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 回复规则
|
||||
type Reply struct {
|
||||
Response string
|
||||
Rules []IRule
|
||||
}
|
||||
|
||||
func (r *Reply) Hit(eventType ws.EventType, chatUser *accountFiee.ChatUserData, wsClient *ws.Client, msg *accountFiee.ChatRecordData, robotInfo *accountFiee.ChatUserData) (hit bool, runTime time.Time, logic func(msg string) error) {
|
||||
func (r *Reply) Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserData) (hit bool, task RobotTask) {
|
||||
for _, rule := range r.Rules {
|
||||
hit, runTime, logic = rule.Hit(eventType, chatUser, wsClient, msg, robotInfo)
|
||||
hit, task = rule.Hit(event, robotInfo)
|
||||
if hit {
|
||||
return
|
||||
}
|
||||
@ -32,12 +34,9 @@ func (r *Reply) Hit(eventType ws.EventType, chatUser *accountFiee.ChatUserData,
|
||||
return
|
||||
}
|
||||
|
||||
// 规则接口
|
||||
type IRule interface {
|
||||
Hit(eventType ws.EventType, chatUser *accountFiee.ChatUserData, wsClient *ws.Client, msg *accountFiee.ChatRecordData, robotInfo *accountFiee.ChatUserData) (hit bool, runTime time.Time, logic func(msg string) error)
|
||||
}
|
||||
|
||||
func NewReplyWhenHitKeywords(keywords []string) IRule {
|
||||
return &ReplyWhenHitKeywords{Keywords: keywords}
|
||||
Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserData) (hit bool, task RobotTask)
|
||||
}
|
||||
|
||||
// KeywordsRuleChecker 关键字回复
|
||||
@ -45,44 +44,80 @@ type ReplyWhenHitKeywords struct {
|
||||
Keywords []string `json:"keywords"`
|
||||
}
|
||||
|
||||
func (k ReplyWhenHitKeywords) Hit(eventType ws.EventType, chatUser *accountFiee.ChatUserData, wsClient *ws.Client, record *accountFiee.ChatRecordData, robotInfo *accountFiee.ChatUserData) (hit bool, runTime time.Time, logic func(msg string) error) {
|
||||
if record == nil {
|
||||
func NewReplyWhenHitKeywords(keywords []string) IRule {
|
||||
return &ReplyWhenHitKeywords{Keywords: keywords}
|
||||
}
|
||||
func (k ReplyWhenHitKeywords) Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserData) (hit bool, task RobotTask) {
|
||||
if event.EventType != ws.EventChatMessage || event.Msg == "" || event.Client == nil || event.ChatUser == nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, v := range k.Keywords {
|
||||
if strings.Contains(record.Content, v) {
|
||||
if strings.Contains(event.Msg, v) {
|
||||
hit = true
|
||||
break
|
||||
}
|
||||
}
|
||||
logic = func(msg string) error {
|
||||
var notice = dto.MessageListType{}
|
||||
notice.BuildMessage(record)
|
||||
_, err := consts.ChatRoom.SendSessionMessage(robotInfo, record.SessionId, ws.NewChatMsgType, notice)
|
||||
return err
|
||||
task = RobotTask{
|
||||
ChatUser: event.ChatUser,
|
||||
Run: func(msg string, cache *chatCache.ChatCache, Sender *accountFiee.ChatUserData) error {
|
||||
return logic.NewMessage(context.Background(), cache, Sender, dto.NewMessageRequest{
|
||||
Waiter: true,
|
||||
SessionId: event.Client.SessionId,
|
||||
Message: dto.Message{
|
||||
MsgType: 1,
|
||||
Text: msg,
|
||||
LocalStamp: time.Now().Unix(),
|
||||
},
|
||||
})
|
||||
},
|
||||
}
|
||||
//logicFunc = func(content string, cache *chatCache.ChatCache, chatUser *accountFiee.ChatUserData) error {
|
||||
// //var notice = dto.MessageListType{}
|
||||
// //newRecord := &accountFiee.ChatRecordData{
|
||||
// // SessionId: wsClient.SessionId,
|
||||
// // UserId: wsClient.UserId,
|
||||
// // Name: chatUser.NickName,
|
||||
// // Avatar: robotInfo.Avatar,
|
||||
// // MsgType: 1,
|
||||
// // Content: content,
|
||||
// //}
|
||||
// //notice.BuildMessage(newRecord)
|
||||
// //_, err := consts.ChatRoom.SendSessionMessage(robotInfo, wsClient.SessionId, ws.NewChatMsgType, notice)
|
||||
// //return err
|
||||
// err := logic.NewMessage(context.Background(), cache, chatUser, dto.NewMessageRequest{
|
||||
// Waiter: true,
|
||||
// SessionId: wsClient.SessionId,
|
||||
// Message: dto.Message{
|
||||
// MsgType: 1,
|
||||
// Text: msg,
|
||||
// LocalStamp: time.Now().Unix(),
|
||||
// },
|
||||
// })
|
||||
// return err
|
||||
//}
|
||||
return
|
||||
}
|
||||
|
||||
// 用户打开聊天会话直接发送
|
||||
type ReplyWhenUserJoinSession struct {
|
||||
}
|
||||
|
||||
func NewReplyWhenUserJoinSession() IRule {
|
||||
return &ReplyWhenUserJoinSession{}
|
||||
}
|
||||
|
||||
type ReplyWhenUserJoinSession struct {
|
||||
}
|
||||
|
||||
func (k ReplyWhenUserJoinSession) Hit(eventType ws.EventType, chatUser *accountFiee.ChatUserData, wsClient *ws.Client, record *accountFiee.ChatRecordData, robotInfo *accountFiee.ChatUserData) (hit bool, runTime time.Time, logic func(msg string) error) {
|
||||
if eventType != ws.EventUserJoin {
|
||||
func (k ReplyWhenUserJoinSession) Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserData) (hit bool, task RobotTask) {
|
||||
if event.EventType != ws.EventUserJoin {
|
||||
return
|
||||
}
|
||||
if wsClient == nil {
|
||||
if event.Client == nil {
|
||||
return
|
||||
}
|
||||
ctx := context.Background()
|
||||
queryRes, err := service.AccountFieeProvider.GetChatRecordList(ctx, &accountFiee.GetChatRecordListRequest{
|
||||
Query: &accountFiee.ChatRecordData{
|
||||
SessionId: wsClient.SessionId,
|
||||
SessionId: event.Client.SessionId,
|
||||
},
|
||||
Page: 1,
|
||||
PageSize: 1,
|
||||
@ -102,41 +137,115 @@ func (k ReplyWhenUserJoinSession) Hit(eventType ws.EventType, chatUser *accountF
|
||||
}
|
||||
}
|
||||
hit = true
|
||||
logic = func(msg string) error {
|
||||
var notice = dto.MessageListType{}
|
||||
newRecord := &accountFiee.ChatRecordData{
|
||||
SessionId: wsClient.SessionId,
|
||||
UserId: wsClient.UserId,
|
||||
Name: wsClient.SessionId,
|
||||
Avatar: robotInfo.Avatar,
|
||||
MsgType: 1,
|
||||
Content: msg,
|
||||
if event.ChatUser == nil {
|
||||
event.ChatUser, err = service.AccountFieeProvider.GetChatUserDetail(context.Background(), &accountFiee.GetChatUserByIdRequest{Id: event.Client.UserId})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
notice.BuildMessage(newRecord)
|
||||
_, err = consts.ChatRoom.SendSessionMessage(robotInfo, wsClient.SessionId, ws.NewChatMsgType, notice)
|
||||
return err
|
||||
}
|
||||
task = RobotTask{
|
||||
ChatUser: event.ChatUser,
|
||||
Run: func(msg string, cache *chatCache.ChatCache, Sender *accountFiee.ChatUserData) error {
|
||||
return logic.NewMessage(ctx, cache, Sender, dto.NewMessageRequest{
|
||||
Waiter: true,
|
||||
SessionId: event.Client.SessionId,
|
||||
Message: dto.Message{
|
||||
MsgType: 1,
|
||||
Text: msg,
|
||||
LocalStamp: time.Now().Unix(),
|
||||
},
|
||||
})
|
||||
},
|
||||
}
|
||||
//logicFunc = func(msg string, cache *chatCache.ChatCache, chatUser *accountFiee.ChatUserData) error {
|
||||
// //var notice = dto.MessageListType{}
|
||||
// //newRecord := &accountFiee.ChatRecordData{
|
||||
// // SessionId: wsClient.SessionId,
|
||||
// // UserId: wsClient.UserId,
|
||||
// // Name: wsClient.SessionId,
|
||||
// // Avatar: robotInfo.Avatar,
|
||||
// // MsgType: 1,
|
||||
// // Content: msg,
|
||||
// //}
|
||||
// //notice.BuildMessage(newRecord)
|
||||
// //_, err = consts.ChatRoom.SendSessionMessage(robotInfo, wsClient.SessionId, ws.NewChatMsgType, notice)
|
||||
// err = logic.NewMessage(ctx, cache, chatUser, dto.NewMessageRequest{
|
||||
// Waiter: true,
|
||||
// SessionId: wsClient.SessionId,
|
||||
// Message: dto.Message{
|
||||
// MsgType: 1,
|
||||
// Text: msg,
|
||||
// LocalStamp: time.Now().Unix(),
|
||||
// },
|
||||
// })
|
||||
// return err
|
||||
//}
|
||||
return
|
||||
}
|
||||
|
||||
// 客服
|
||||
// 客服指定时间不回复则自动回复
|
||||
|
||||
type ReplyWhenWaiterNoAction struct {
|
||||
DelaySecond time.Duration
|
||||
}
|
||||
|
||||
func NewReplyWhenWaiterNoAction(delaySecond time.Duration) *ReplyWhenWaiterNoAction {
|
||||
return &ReplyWhenWaiterNoAction{
|
||||
DelaySecond: delaySecond,
|
||||
}
|
||||
}
|
||||
|
||||
type ReplyWhenWaiterNoAction struct {
|
||||
DelaySecond time.Duration
|
||||
}
|
||||
func (k *ReplyWhenWaiterNoAction) Hit(event ws.ListenEventData, chatUser *accountFiee.ChatUserData) (hit bool, task RobotTask) {
|
||||
if event.Client == nil || event.EventType != ws.EventChatMessage {
|
||||
return
|
||||
}
|
||||
task = RobotTask{
|
||||
RunTime: time.Now().Add(k.DelaySecond * time.Second),
|
||||
Run: func(content string, cache *chatCache.ChatCache, Sender *accountFiee.ChatUserData) error {
|
||||
//如果客服已经回复则不发送消息
|
||||
chatRecordListRes, err := service.AccountFieeProvider.GetChatRecordList(context.Background(), &accountFiee.GetChatRecordListRequest{
|
||||
Query: &accountFiee.ChatRecordData{
|
||||
SessionId: event.Client.SessionId,
|
||||
},
|
||||
Page: 1,
|
||||
PageSize: 1,
|
||||
Order: "created_at desc",
|
||||
})
|
||||
if err != nil || chatRecordListRes.Total == 0 {
|
||||
return err
|
||||
}
|
||||
checkUserId := chatRecordListRes.List[0].UserId
|
||||
checkChatUser, err := service.AccountFieeProvider.GetChatUserDetail(context.Background(), &accountFiee.GetChatUserByIdRequest{Id: checkUserId})
|
||||
if err != nil || checkChatUser.Role != 1 {
|
||||
return err
|
||||
}
|
||||
|
||||
func (k *ReplyWhenWaiterNoAction) Hit(eventType ws.EventType, chatUser *accountFiee.ChatUserData, wsClient *ws.Client, record *accountFiee.ChatRecordData, robotInfo *accountFiee.ChatUserData) (hit bool, runTime time.Time, logic func(msg string) error) {
|
||||
runTime = time.Now().Add(k.DelaySecond * time.Second)
|
||||
logic = func(msg string) error {
|
||||
var notice = dto.MessageListType{}
|
||||
notice.BuildMessage(record)
|
||||
_, err := consts.ChatRoom.SendSessionMessage(robotInfo, record.SessionId, ws.NewChatMsgType, notice)
|
||||
return err
|
||||
//var notice = dto.MessageListType{}
|
||||
//newRecord := &accountFiee.ChatRecordData{
|
||||
// SessionId: wsClient.SessionId,
|
||||
// UserId: wsClient.UserId,
|
||||
// Name: chatUser.NickName,
|
||||
// Avatar: robotInfo.Avatar,
|
||||
// MsgType: 1,
|
||||
// Content: content,
|
||||
//}
|
||||
//notice.BuildMessage(newRecord)
|
||||
//_, err = consts.ChatRoom.SendSessionMessage(robotInfo, wsClient.SessionId, ws.NewChatMsgType, notice)
|
||||
//return err
|
||||
|
||||
err = logic.NewMessage(context.Background(), cache, chatUser, dto.NewMessageRequest{
|
||||
Waiter: true,
|
||||
SessionId: event.Client.SessionId,
|
||||
Message: dto.Message{
|
||||
MsgType: 1,
|
||||
Text: event.Msg,
|
||||
LocalStamp: time.Now().Unix(),
|
||||
},
|
||||
})
|
||||
return err
|
||||
},
|
||||
Response: "",
|
||||
ChatUser: event.ChatUser,
|
||||
}
|
||||
return
|
||||
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"fonchain-fiee/api/accountFiee"
|
||||
"fonchain-fiee/pkg/common/ws"
|
||||
"fonchain-fiee/pkg/service"
|
||||
"fonchain-fiee/pkg/service/asChat/chatCache"
|
||||
"fonchain-fiee/pkg/service/asChat/consts"
|
||||
"fonchain-fiee/pkg/service/asChat/dto"
|
||||
"log"
|
||||
@ -19,7 +20,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func NewRobot() *Robot {
|
||||
func NewRobot(cache *chatCache.ChatCache) *Robot {
|
||||
ctx := context.Background()
|
||||
robotQuery, err := service.AccountFieeProvider.GetChatUserList(ctx, &accountFiee.GetChatUserListRequest{
|
||||
Query: &accountFiee.ChatUserData{Role: 3},
|
||||
@ -49,10 +50,11 @@ func NewRobot() *Robot {
|
||||
Name: "robot1",
|
||||
ListenEvents: []ws.ListenEvent{ //只监听消息推送事件
|
||||
{ws.EventUserJoin, ws.EventProgressAfter},
|
||||
{ws.EventChatMessage, ws.EventProgressAfter},
|
||||
{ws.EventChatMessage, ws.EventProgressBefore},
|
||||
},
|
||||
Chan: make(ws.ListenEventChan),
|
||||
},
|
||||
cache: cache,
|
||||
}
|
||||
ruleListRes, err := service.AccountFieeProvider.GetChatAutoReplyRulerList(ctx, &accountFiee.GetChatAutoReplyRulerListRequest{
|
||||
Query: &accountFiee.ChatAutoReplyRulerData{Status: 1},
|
||||
@ -87,6 +89,7 @@ type Robot struct {
|
||||
isRunning bool //运行状态
|
||||
mu sync.Mutex
|
||||
*ws.EventListener
|
||||
cache *chatCache.ChatCache
|
||||
}
|
||||
|
||||
//func (r *Robot) Listen(record *accountFiee.ChatRecordData) {
|
||||
@ -144,6 +147,8 @@ func (r *Robot) Run() {
|
||||
|
||||
for {
|
||||
select {
|
||||
default:
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
case <-r.ticker.C:
|
||||
r.mu.Lock()
|
||||
if len(r.DelayTask) == 0 {
|
||||
@ -157,7 +162,7 @@ func (r *Robot) Run() {
|
||||
if now.After(task.RunTime) {
|
||||
// 执行任务
|
||||
go func() {
|
||||
err := task.Run(task.Response)
|
||||
err := task.Run(task.Response, r.cache, task.ChatUser)
|
||||
if err != nil {
|
||||
log.Printf("聊天机器人[%d]回复消息失败:%v", r.Info.ID, err)
|
||||
}
|
||||
@ -172,39 +177,21 @@ func (r *Robot) Run() {
|
||||
case <-r.stopChan:
|
||||
return
|
||||
case event := <-r.EventListener.Chan:
|
||||
fmt.Printf("listen event:%#v\n", event)
|
||||
switch event.EventType {
|
||||
case ws.EventUserJoin: //用户加入聊天室
|
||||
for _, ruleResponse := range r.Rules {
|
||||
hit, runtime, logic := ruleResponse.Hit(ws.EventUserJoin, nil, event.Client, nil, r.Info)
|
||||
if hit {
|
||||
if runtime.IsZero() {
|
||||
err := logic(ruleResponse.Response)
|
||||
if err != nil {
|
||||
log.Printf("robot 执行任务失败:%v\n", err)
|
||||
}
|
||||
} else {
|
||||
r.DelayTask = append(r.DelayTask, RobotTask{
|
||||
RunTime: runtime,
|
||||
Run: logic,
|
||||
Response: ruleResponse.Response,
|
||||
})
|
||||
fmt.Printf("robot listen event:%#v\n", event)
|
||||
for _, ruleResponse := range r.Rules {
|
||||
hit, task := ruleResponse.Hit(event, r.Info)
|
||||
if hit {
|
||||
if task.RunTime.IsZero() {
|
||||
err := task.Run(ruleResponse.Response, r.cache, r.Info)
|
||||
if err != nil {
|
||||
log.Printf("robot 执行任务失败:%v\n", err)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
case ws.EventChatMessage:
|
||||
for _, ruleResponse := range r.Rules {
|
||||
hit, runtime, logic := ruleResponse.Hit(ws.EventUserJoin, nil, event.Client, nil, r.Info)
|
||||
if hit {
|
||||
if !runtime.IsZero() {
|
||||
err := logic(ruleResponse.Response)
|
||||
if err != nil {
|
||||
log.Printf("robot 执行任务失败:%v\n", err)
|
||||
}
|
||||
}
|
||||
break
|
||||
} else {
|
||||
task.Response = ruleResponse.Response
|
||||
r.RegisterDelayTask(task)
|
||||
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -219,3 +206,11 @@ func (r *Robot) Stop() {
|
||||
}
|
||||
r.mu.Unlock()
|
||||
}
|
||||
func (r *Robot) RegisterDelayTask(task RobotTask) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
if task.Run == nil {
|
||||
return
|
||||
}
|
||||
r.DelayTask = append(r.DelayTask, task)
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ func ParseReplyRule(data *dto.ChatAutoReplyData) (r Reply) {
|
||||
switch ruleName {
|
||||
case "keywords": //关键字回复
|
||||
var keywords []string
|
||||
if v.Content != "" {
|
||||
if v.Content == "" {
|
||||
continue
|
||||
} else {
|
||||
keywords = strings.Split(v.Content, ",")
|
||||
|
@ -6,10 +6,15 @@
|
||||
// -------------------------------------------
|
||||
package robot
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"fonchain-fiee/api/accountFiee"
|
||||
"fonchain-fiee/pkg/service/asChat/chatCache"
|
||||
"time"
|
||||
)
|
||||
|
||||
type RobotTask struct {
|
||||
RunTime time.Time
|
||||
Run func(msg string) error
|
||||
Run func(msg string, cache *chatCache.ChatCache, Sender *accountFiee.ChatUserData) error
|
||||
Response string
|
||||
ChatUser *accountFiee.ChatUserData
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user