Compare commits
19 Commits
ac5fe7a266
...
17e3b6513f
Author | SHA1 | Date | |
---|---|---|---|
17e3b6513f | |||
e97bd859fc | |||
eaf04ae02d | |||
03adb50fee | |||
48a47a8681 | |||
65c14cc10c | |||
0c682db6e8 | |||
543514dae9 | |||
e1fbbfce04 | |||
42b6c1262d | |||
1ba87f9c30 | |||
d42b82381e | |||
65f12cc019 | |||
5c84210272 | |||
ac79481ec5 | |||
b39f315ac2 | |||
be6d4dbb63 | |||
1424e76f54 | |||
613057182e |
@ -194,8 +194,8 @@ func (o *ChatRoom) Register(c *Client) (sessionId string) {
|
|||||||
// message: 消息内容
|
// message: 消息内容
|
||||||
func (o *ChatRoom) SendSessionMessage(sender *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")
|
fmt.Println("ChatRoom.SendSessionMessage ------------------1")
|
||||||
//o.clientsRwLocker.Lock()
|
o.clientsRwLocker.Lock()
|
||||||
//defer o.clientsRwLocker.Unlock()
|
defer o.clientsRwLocker.Unlock()
|
||||||
var msg = WsSessionInfo{
|
var msg = WsSessionInfo{
|
||||||
Type: msgType,
|
Type: msgType,
|
||||||
Content: message,
|
Content: message,
|
||||||
@ -209,18 +209,26 @@ func (o *ChatRoom) SendSessionMessage(sender *accountFiee.ChatUserData, sessionI
|
|||||||
fmt.Println("ChatRoom.SendSessionMessage ------------------3")
|
fmt.Println("ChatRoom.SendSessionMessage ------------------3")
|
||||||
usableClients := []*Client{}
|
usableClients := []*Client{}
|
||||||
fmt.Printf("sessionId:[%s],客户端数量%d\n", sessionId, len(o.Session[sessionId]))
|
fmt.Printf("sessionId:[%s],客户端数量%d\n", sessionId, len(o.Session[sessionId]))
|
||||||
|
pushed := false
|
||||||
for i, client := range o.Session[sessionId] {
|
for i, client := range o.Session[sessionId] {
|
||||||
if client != nil {
|
if client != nil {
|
||||||
_, exist := o.clients[client.UserId][client.ClientId]
|
_, exist := o.clients[client.UserId][client.ClientId]
|
||||||
if exist {
|
if exist {
|
||||||
usableClients = append(usableClients, o.Session[sessionId][i])
|
usableClients = append(usableClients, o.Session[sessionId][i])
|
||||||
|
if !pushed {
|
||||||
go o.pushEvent(EventChatMessage, EventProgressBefore, sender, o.Session[sessionId][i], message)
|
go o.pushEvent(EventChatMessage, EventProgressBefore, sender, o.Session[sessionId][i], message)
|
||||||
|
pushed = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Printf("client:%+v\n", client)
|
fmt.Printf("client:%+v\n", client)
|
||||||
|
pushed = false
|
||||||
if client != nil && (client.UserId != sender.ID || sender.Role == 3) {
|
if client != nil && (client.UserId != sender.ID || sender.Role == 3) {
|
||||||
client.Send <- msgBytes
|
client.Send <- msgBytes
|
||||||
|
if !pushed {
|
||||||
go o.pushEvent(EventChatMessage, EventProgressAfter, sender, o.Session[sessionId][i], message)
|
go o.pushEvent(EventChatMessage, EventProgressAfter, sender, o.Session[sessionId][i], message)
|
||||||
|
pushed = true
|
||||||
|
}
|
||||||
userIdInSession = append(userIdInSession, client.UserId)
|
userIdInSession = append(userIdInSession, client.UserId)
|
||||||
}
|
}
|
||||||
//client.Send <- msgBytes
|
//client.Send <- msgBytes
|
||||||
|
@ -40,6 +40,8 @@ func AuthorizationVerify(sourceData []byte) (userInfo *accountFiee.ChatUserData,
|
|||||||
var ctx = context.Background()
|
var ctx = context.Background()
|
||||||
var accountInfo accountFiee.ChatUserData
|
var accountInfo accountFiee.ChatUserData
|
||||||
//fiee token校验
|
//fiee token校验
|
||||||
|
switch msg.Content.Domain {
|
||||||
|
case "app":
|
||||||
var fieeJwtInfo *jwt.Claims
|
var fieeJwtInfo *jwt.Claims
|
||||||
fieeJwtInfo, err = jwt.ParseToken(msg.Content.Auth, m.JWTSecret)
|
fieeJwtInfo, err = jwt.ParseToken(msg.Content.Auth, m.JWTSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -70,9 +72,10 @@ func AuthorizationVerify(sourceData []byte) (userInfo *accountFiee.ChatUserData,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !check {
|
case "fontree":
|
||||||
msg.Content.Auth, err = secret.GetJwtFromStr(msg.Content.Auth)
|
msg.Content.Auth, err = secret.GetJwtFromStr(msg.Content.Auth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Println("token解析失败:", err.Error())
|
||||||
check = false
|
check = false
|
||||||
} else {
|
} else {
|
||||||
var fontreeJwtInfo *account.DecryptJwtResponse
|
var fontreeJwtInfo *account.DecryptJwtResponse
|
||||||
|
@ -111,7 +111,7 @@ func (a *ChatAutoReplyRulerHandler) GetChatAutoReplyRulerList(c *gin.Context) {
|
|||||||
var protoReq = accountFiee.GetChatAutoReplyRulerListRequest{Query: &accountFiee.ChatAutoReplyRulerData{}}
|
var protoReq = accountFiee.GetChatAutoReplyRulerListRequest{Query: &accountFiee.ChatAutoReplyRulerData{}}
|
||||||
utils.RequestDataConvert(&req, &protoReq)
|
utils.RequestDataConvert(&req, &protoReq)
|
||||||
if req.RuleType != "" {
|
if req.RuleType != "" {
|
||||||
protoReq.Where = fmt.Sprintf("ruler LIKE '%%\"%s\":{\"enable\":true}%%'", req.RuleType)
|
protoReq.Where = fmt.Sprintf("ruler LIKE '%%%s\":{\"enable\":true%%'", req.RuleType)
|
||||||
}
|
}
|
||||||
resp, err := service.AccountFieeProvider.GetChatAutoReplyRulerList(c, &protoReq)
|
resp, err := service.AccountFieeProvider.GetChatAutoReplyRulerList(c, &protoReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -99,7 +99,7 @@ func (cr ChatCache) GetChatRecord(sessionId string) (data []*accountFiee.ChatRec
|
|||||||
//log.Print("获取聊天记录失败", zap.Error(err))
|
//log.Print("获取聊天记录失败", zap.Error(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Printf("cache data: %+v", string(messages))
|
//fmt.Printf("cache data: %+v", string(messages))
|
||||||
if len(messages) > 0 {
|
if len(messages) > 0 {
|
||||||
_ = json.Unmarshal(messages, &data)
|
_ = json.Unmarshal(messages, &data)
|
||||||
}
|
}
|
||||||
@ -144,29 +144,36 @@ func (cr ChatCache) IncreaseNewMessageTotal(ownerId int64, sessionId string) (er
|
|||||||
|
|
||||||
// 重置新消息数量
|
// 重置新消息数量
|
||||||
func (cr ChatCache) ResetNewMessageTotal(ownerId int64, sessionId string, total ...int64) error {
|
func (cr ChatCache) ResetNewMessageTotal(ownerId int64, sessionId string, total ...int64) error {
|
||||||
|
fmt.Printf("ResetNewMessageTotal: %d ,sessionId:%s ,total:%v\n", ownerId, sessionId, total)
|
||||||
chatCacheLocker.Lock()
|
chatCacheLocker.Lock()
|
||||||
defer chatCacheLocker.Unlock()
|
defer chatCacheLocker.Unlock()
|
||||||
var tl int64
|
var tl int64
|
||||||
if len(total) > 0 {
|
if len(total) > 0 {
|
||||||
tl = total[0]
|
tl = total[0]
|
||||||
}
|
}
|
||||||
|
fmt.Println("ResetNewMessageTotal tl:", tl)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
data := cr.GetNewMessageStat(ctx, ownerId)
|
data := cr.GetNewMessageStat(ctx, ownerId)
|
||||||
|
fmt.Printf("ResetNewMessageTotal data:%+v\n", data)
|
||||||
found := false
|
found := false
|
||||||
for i, v := range data {
|
for i, v := range data {
|
||||||
if v.SessionId == sessionId {
|
if v.SessionId == sessionId {
|
||||||
found = true
|
found = true
|
||||||
data[i].Total = tl
|
data[i].Total = tl
|
||||||
|
fmt.Println("ResetNewMessageTotal found!")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !found {
|
if !found {
|
||||||
|
fmt.Println("ResetNewMessageTotal not found!")
|
||||||
data = append(data, dto.UserMsgStatic{
|
data = append(data, dto.UserMsgStatic{
|
||||||
SessionId: sessionId,
|
SessionId: sessionId,
|
||||||
Total: tl,
|
Total: tl,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return cr.coverOwnerNewMessageStat(ctx, ownerId, data)
|
err := cr.coverOwnerNewMessageStat(ctx, ownerId, data)
|
||||||
|
fmt.Println("ResetNewMessageTotal result:", err)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cr ChatCache) RecountNewMessageTotal(ownerId int64) {
|
func (cr ChatCache) RecountNewMessageTotal(ownerId int64) {
|
||||||
@ -194,7 +201,8 @@ func (cr ChatCache) RecountNewMessageTotal(ownerId int64) {
|
|||||||
if len(messages) > 0 {
|
if len(messages) > 0 {
|
||||||
_ = json.Unmarshal(messages, &data)
|
_ = json.Unmarshal(messages, &data)
|
||||||
}
|
}
|
||||||
var sessionId = strings.Split(key, ":")[1]
|
lastIndex := strings.Count(key, ":")
|
||||||
|
var sessionId = strings.Split(key, ":")[lastIndex]
|
||||||
countMap[sessionId] = 0
|
countMap[sessionId] = 0
|
||||||
for _, v := range data {
|
for _, v := range data {
|
||||||
if v.WaiterRead == 2 { //统计未读消息数量
|
if v.WaiterRead == 2 { //统计未读消息数量
|
||||||
|
@ -31,8 +31,10 @@ type MessageMedia struct {
|
|||||||
// 客户端发送消息请求,使用api发送消息
|
// 客户端发送消息请求,使用api发送消息
|
||||||
type NewMessageRequest struct {
|
type NewMessageRequest struct {
|
||||||
Waiter bool `json:"waiter"` //是否是客服发送,客服没有userId
|
Waiter bool `json:"waiter"` //是否是客服发送,客服没有userId
|
||||||
|
Robot bool `json:"-"` //是否机器人发送
|
||||||
SessionId string `json:"sessionId"`
|
SessionId string `json:"sessionId"`
|
||||||
Message
|
Message
|
||||||
|
AtUserId int64 `json:"atUserId"` //指定发送给sessionId中的某一个用户
|
||||||
}
|
}
|
||||||
|
|
||||||
// 服务端接收到消息后,使用websocket发送给userId关联的客户端,通知客户端有新消息,然后调用接口获取消息
|
// 服务端接收到消息后,使用websocket发送给userId关联的客户端,通知客户端有新消息,然后调用接口获取消息
|
||||||
|
@ -230,9 +230,9 @@ func (cr ChatHandler) MessageList(c *gin.Context) {
|
|||||||
service.Error(c, err)
|
service.Error(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
domain := c.GetHeader("domain")
|
//domain := c.GetHeader("domain")
|
||||||
fmt.Println("MessageList domain:", domain)
|
//fmt.Println("MessageList domain:", domain)
|
||||||
if (request.Direction == 0 && request.Recent == false) || (request.Direction > 0 && request.Recent == true) {
|
if (request.Direction == 0 && !request.Recent) || (request.Direction > 0 && request.Recent) {
|
||||||
service.Error(c, errors.New("组合条件校验失败"))
|
service.Error(c, errors.New("组合条件校验失败"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -249,7 +249,7 @@ func (cr ChatHandler) MessageList(c *gin.Context) {
|
|||||||
service.Success(c, resp)
|
service.Success(c, resp)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
chatUser, code := jwt.ParseToChatUser(c)
|
accessUser, code := jwt.ParseToChatUser(c)
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
service.ErrWithCode(c, code)
|
service.ErrWithCode(c, code)
|
||||||
return
|
return
|
||||||
@ -261,16 +261,16 @@ func (cr ChatHandler) MessageList(c *gin.Context) {
|
|||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
//messages := cr.cache.GetChatRecord(request.SessionId)
|
messages := cr.cache.GetChatRecord(request.SessionId)
|
||||||
messages := []*accountFiee.ChatRecordData{}
|
//messages := []*accountFiee.ChatRecordData{}
|
||||||
var returnDataIdList = make([]int64, 0)
|
var returnDataIdList = make([]int64, 0)
|
||||||
defer func() {
|
defer func() {
|
||||||
//获取最新数据时,重置新消息数量统计
|
//获取最新数据时,重置新消息数量统计
|
||||||
if request.Direction == 2 || request.Recent {
|
if request.Direction == 2 || request.Recent {
|
||||||
cr.cache.ResetNewMessageTotal(chatUser.ID, request.SessionId)
|
cr.cache.ResetNewMessageTotal(accessUser.ID, request.SessionId)
|
||||||
}
|
}
|
||||||
//设置消息已被客服阅读,当客服重新通过通过websocket连接时,这些消息将不被纳入新消息数量统计
|
//设置消息已被客服阅读,当客服重新通过通过websocket连接时,这些消息将不被纳入新消息数量统计
|
||||||
if len(returnDataIdList) > 0 && domain == "fontree" {
|
if len(returnDataIdList) > 0 && accessUser.Role == 2 {
|
||||||
for _, hasReadId := range returnDataIdList {
|
for _, hasReadId := range returnDataIdList {
|
||||||
for i, message := range messages {
|
for i, message := range messages {
|
||||||
if message.ID == hasReadId {
|
if message.ID == hasReadId {
|
||||||
@ -368,6 +368,8 @@ func (cr ChatHandler) MessageList(c *gin.Context) {
|
|||||||
resp[i].Message.Media = []dto.MessageMedia{}
|
resp[i].Message.Media = []dto.MessageMedia{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if accessUser.Role == 1 {
|
||||||
|
}
|
||||||
service.Success(c, resp)
|
service.Success(c, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,10 +503,21 @@ func (cr ChatHandler) UserMessageStat(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if result[i].Name == "" {
|
if result[i].Name == "" {
|
||||||
result[i].Name = beautifulZeroName(result[i].Name, result[i].UserId)
|
result[i].Name = beautifulZeroNameWithPhone(result[i].Name, result[i].UserId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reverse(result)
|
reverse(result)
|
||||||
|
if chatUser.Role == 1 {
|
||||||
|
userSessionId := fmt.Sprintf("%d", chatUser.ID)
|
||||||
|
newResp := []dto.UserMsgStatic{}
|
||||||
|
for _, v := range result {
|
||||||
|
if v.SessionId == userSessionId {
|
||||||
|
newResp = append(newResp, v)
|
||||||
|
service.Success(c, newResp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
service.Success(c, result)
|
service.Success(c, result)
|
||||||
}
|
}
|
||||||
func reverse(slice []dto.UserMsgStatic) {
|
func reverse(slice []dto.UserMsgStatic) {
|
||||||
@ -563,6 +576,10 @@ func (cr ChatHandler) UserDetail(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//fmt.Printf("chatUser:%#v\n", chatUser)
|
||||||
|
//if chatUser.Origin == "fiee" {
|
||||||
|
// chatUser.Origin = "app"
|
||||||
|
//}
|
||||||
resp, err := service.AccountFieeProvider.Info(c, &accountFiee.InfoRequest{ID: uint64(chatUser.OriginId), Domain: chatUser.Origin})
|
resp, err := service.AccountFieeProvider.Info(c, &accountFiee.InfoRequest{ID: uint64(chatUser.OriginId), Domain: chatUser.Origin})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
service.Error(c, err)
|
service.Error(c, err)
|
||||||
@ -588,3 +605,31 @@ func (cr ChatHandler) UserDetail(c *gin.Context) {
|
|||||||
func beautifulZeroName(name string, userId int64) string {
|
func beautifulZeroName(name string, userId int64) string {
|
||||||
return utils.IfGec(name == "", fmt.Sprintf("未实名用户:%d", userId), name)
|
return utils.IfGec(name == "", fmt.Sprintf("未实名用户:%d", userId), name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var userIdMapPhone = make(map[int64]string)
|
||||||
|
|
||||||
|
func beautifulZeroNameWithPhone(name string, userId int64) string {
|
||||||
|
var ctx = context.Background()
|
||||||
|
if name == "" {
|
||||||
|
telNum, ok := userIdMapPhone[userId]
|
||||||
|
if ok {
|
||||||
|
return telNum
|
||||||
|
}
|
||||||
|
chatUserRes, err := service.AccountFieeProvider.GetChatUserDetail(ctx, &accountFiee.GetChatUserByIdRequest{Id: userId})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Sprintf("未实名用户:%d", userId)
|
||||||
|
} else {
|
||||||
|
if userRes, errs := service.AccountFieeProvider.Info(ctx, &accountFiee.InfoRequest{
|
||||||
|
Domain: chatUserRes.Origin,
|
||||||
|
ID: uint64(chatUserRes.OriginId),
|
||||||
|
Scene: "",
|
||||||
|
}); errs != nil {
|
||||||
|
return fmt.Sprintf("未实名用户:%d", userId)
|
||||||
|
} else {
|
||||||
|
userIdMapPhone[userId] = userRes.TelNum
|
||||||
|
return userRes.TelNum
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
@ -25,7 +25,7 @@ import (
|
|||||||
|
|
||||||
type AutoReply struct {
|
type AutoReply struct {
|
||||||
Response string `json:"response"`
|
Response string `json:"response"`
|
||||||
Rules map[string]IRule `json:"rules"`
|
Rules map[string]IRobotTask `json:"rules"`
|
||||||
}
|
}
|
||||||
type AutoReplyRule struct {
|
type AutoReplyRule struct {
|
||||||
Enable bool `json:"enable"`
|
Enable bool `json:"enable"`
|
||||||
|
@ -26,3 +26,6 @@ web端和后端交互式时,增删改查的规则配置是存放在rules对象
|
|||||||
- keywords :关键字回复
|
- keywords :关键字回复
|
||||||
- joinSession:用户打开聊天窗口后
|
- joinSession:用户打开聊天窗口后
|
||||||
- noReplyAfter:客服指定时间没有回复后
|
- noReplyAfter:客服指定时间没有回复后
|
||||||
|
|
||||||
|
## 注意
|
||||||
|
- 目前不支持用户多端登录,会导致用户收到重复消息
|
@ -7,26 +7,20 @@
|
|||||||
package robot
|
package robot
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fonchain-fiee/api/accountFiee"
|
"fonchain-fiee/api/accountFiee"
|
||||||
"fonchain-fiee/pkg/common/ws"
|
"fonchain-fiee/pkg/common/ws"
|
||||||
"fonchain-fiee/pkg/service"
|
|
||||||
"fonchain-fiee/pkg/service/asChat/chatCache"
|
|
||||||
"fonchain-fiee/pkg/service/asChat/dto"
|
|
||||||
"fonchain-fiee/pkg/service/asChat/logic"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// 回复规则
|
// 回复规则
|
||||||
type Reply struct {
|
type Reply struct {
|
||||||
|
Title string
|
||||||
Response string
|
Response string
|
||||||
Rules []IRule
|
Rules []IRobotTask
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Reply) Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserData) (hit bool, task RobotTask) {
|
func (r *Reply) Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserData) (hit bool, rule IRobotTask) {
|
||||||
for _, rule := range r.Rules {
|
for _, rule = range r.Rules {
|
||||||
hit, task = rule.Hit(event, robotInfo)
|
hit = rule.Hit(event, robotInfo)
|
||||||
if hit {
|
if hit {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -34,226 +28,219 @@ func (r *Reply) Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserDat
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 规则接口
|
//
|
||||||
type IRule interface {
|
//// 规则接口
|
||||||
Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserData) (hit bool, task RobotTask)
|
//type IRule interface {
|
||||||
}
|
// Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserData) (hit bool, task RobotTask)
|
||||||
|
//}
|
||||||
// KeywordsRuleChecker 关键字回复
|
//
|
||||||
type ReplyWhenHitKeywords struct {
|
//// KeywordsRuleChecker 关键字回复
|
||||||
Keywords []string `json:"keywords"`
|
//type ReplyWhenHitKeywords struct {
|
||||||
}
|
// Keywords []string `json:"keywords"`
|
||||||
|
//}
|
||||||
func NewReplyWhenHitKeywords(keywords []string) IRule {
|
//
|
||||||
return &ReplyWhenHitKeywords{Keywords: keywords}
|
//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 {
|
//func (k ReplyWhenHitKeywords) Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserData) (hit bool, task RobotTask) {
|
||||||
return
|
// if event.EventType != ws.EventChatMessage || event.Msg == "" || event.Client == nil || event.ChatUser == nil {
|
||||||
}
|
// return
|
||||||
//客服的消息不需要处理
|
// }
|
||||||
if event.ChatUser.Role == 2 {
|
// if event.ChatUser.Role != 1 {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
for _, v := range k.Keywords {
|
// for _, v := range k.Keywords {
|
||||||
if strings.Contains(event.Msg, v) {
|
// if strings.Contains(event.Msg, v) {
|
||||||
hit = true
|
// hit = true
|
||||||
break
|
// break
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
task = RobotTask{
|
// atUserId := event.Client.UserId
|
||||||
ChatUser: event.ChatUser,
|
// task = RobotTask{
|
||||||
Run: func(msg string, cache *chatCache.ChatCache, Sender *accountFiee.ChatUserData) error {
|
// ChatUser: event.ChatUser,
|
||||||
return logic.NewMessage(context.Background(), cache, Sender, dto.NewMessageRequest{
|
// Run: func(msg string, cache *chatCache.ChatCache, Sender *accountFiee.ChatUserData) error {
|
||||||
Waiter: true,
|
// return logic.NewMessage(context.Background(), cache, Sender, dto.NewMessageRequest{
|
||||||
SessionId: event.Client.SessionId,
|
// Waiter: true,
|
||||||
Message: dto.Message{
|
// Robot: true,
|
||||||
MsgType: 1,
|
// AtUserId: atUserId,
|
||||||
Text: msg,
|
// SessionId: event.Client.SessionId,
|
||||||
LocalStamp: time.Now().Unix(),
|
// 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,
|
// return
|
||||||
// // UserId: wsClient.UserId,
|
//}
|
||||||
// // Name: chatUser.NickName,
|
//
|
||||||
// // Avatar: robotInfo.Avatar,
|
//// 用户打开聊天会话直接发送
|
||||||
// // MsgType: 1,
|
//type ReplyWhenUserJoinSession struct {
|
||||||
// // Content: content,
|
//}
|
||||||
// //}
|
//
|
||||||
// //notice.BuildMessage(newRecord)
|
//func NewReplyWhenUserJoinSession() IRule {
|
||||||
// //_, err := consts.ChatRoom.SendSessionMessage(robotInfo, wsClient.SessionId, ws.NewChatMsgType, notice)
|
// return &ReplyWhenUserJoinSession{}
|
||||||
// //return err
|
//}
|
||||||
// err := logic.NewMessage(context.Background(), cache, chatUser, dto.NewMessageRequest{
|
//
|
||||||
// Waiter: true,
|
//func (k ReplyWhenUserJoinSession) Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserData) (hit bool, task RobotTask) {
|
||||||
// SessionId: wsClient.SessionId,
|
// if event.EventType != ws.EventUserJoin {
|
||||||
// Message: dto.Message{
|
// return
|
||||||
// MsgType: 1,
|
// }
|
||||||
// Text: msg,
|
// if event.Client == nil {
|
||||||
// LocalStamp: time.Now().Unix(),
|
// return
|
||||||
// },
|
// }
|
||||||
// })
|
// clientSessionId := event.Client.SessionId
|
||||||
// return err
|
// atUserId := event.Client.UserId
|
||||||
//}
|
// ctx := context.Background()
|
||||||
return
|
// queryRes, err := service.AccountFieeProvider.GetChatRecordList(ctx, &accountFiee.GetChatRecordListRequest{
|
||||||
}
|
// Query: &accountFiee.ChatRecordData{
|
||||||
|
// SessionId: event.Client.SessionId,
|
||||||
// 用户打开聊天会话直接发送
|
// },
|
||||||
type ReplyWhenUserJoinSession struct {
|
// Page: 1,
|
||||||
}
|
// PageSize: 1,
|
||||||
|
// Order: "created_at desc",
|
||||||
func NewReplyWhenUserJoinSession() IRule {
|
// })
|
||||||
return &ReplyWhenUserJoinSession{}
|
// if err != nil {
|
||||||
}
|
// return
|
||||||
|
// }
|
||||||
func (k ReplyWhenUserJoinSession) Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserData) (hit bool, task RobotTask) {
|
// //如果最近一次的消息也是机器人发送的,就不再发送了
|
||||||
if event.EventType != ws.EventUserJoin {
|
// for i, v := range queryRes.List {
|
||||||
return
|
// if i == 0 {
|
||||||
}
|
// if v.UserId == robotInfo.ID {
|
||||||
if event.Client == nil {
|
// return
|
||||||
return
|
// } else {
|
||||||
}
|
// break
|
||||||
ctx := context.Background()
|
// }
|
||||||
queryRes, err := service.AccountFieeProvider.GetChatRecordList(ctx, &accountFiee.GetChatRecordListRequest{
|
// }
|
||||||
Query: &accountFiee.ChatRecordData{
|
// }
|
||||||
SessionId: event.Client.SessionId,
|
// hit = true
|
||||||
},
|
// if event.ChatUser == nil {
|
||||||
Page: 1,
|
// event.ChatUser, err = service.AccountFieeProvider.GetChatUserDetail(context.Background(), &accountFiee.GetChatUserByIdRequest{Id: event.Client.UserId})
|
||||||
PageSize: 1,
|
// if err != nil {
|
||||||
Order: "created_at desc",
|
// return
|
||||||
})
|
// }
|
||||||
if err != nil {
|
// }
|
||||||
return
|
// task = RobotTask{
|
||||||
}
|
// ChatUser: event.ChatUser,
|
||||||
//如果最近一次的消息也是机器人发送的,就不再发送了
|
// Run: func(msg string, cache *chatCache.ChatCache, Sender *accountFiee.ChatUserData) error {
|
||||||
for i, v := range queryRes.List {
|
// return logic.NewMessage(ctx, cache, Sender, dto.NewMessageRequest{
|
||||||
if i == 0 {
|
// Waiter: true,
|
||||||
if v.UserId == robotInfo.ID {
|
// Robot: true,
|
||||||
return
|
// AtUserId: atUserId,
|
||||||
} else {
|
// SessionId: clientSessionId,
|
||||||
break
|
// Message: dto.Message{
|
||||||
}
|
// MsgType: 1,
|
||||||
}
|
// Text: msg,
|
||||||
}
|
// LocalStamp: time.Now().Unix(),
|
||||||
hit = true
|
// },
|
||||||
if event.ChatUser == nil {
|
// })
|
||||||
event.ChatUser, err = service.AccountFieeProvider.GetChatUserDetail(context.Background(), &accountFiee.GetChatUserByIdRequest{Id: event.Client.UserId})
|
// },
|
||||||
if err != nil {
|
// }
|
||||||
return
|
// //logicFunc = func(msg string, cache *chatCache.ChatCache, chatUser *accountFiee.ChatUserData) error {
|
||||||
}
|
// // //var notice = dto.MessageListType{}
|
||||||
}
|
// // //newRecord := &accountFiee.ChatRecordData{
|
||||||
task = RobotTask{
|
// // // SessionId: wsClient.SessionId,
|
||||||
ChatUser: event.ChatUser,
|
// // // UserId: wsClient.UserId,
|
||||||
Run: func(msg string, cache *chatCache.ChatCache, Sender *accountFiee.ChatUserData) error {
|
// // // Name: wsClient.SessionId,
|
||||||
return logic.NewMessage(ctx, cache, Sender, dto.NewMessageRequest{
|
// // // Avatar: robotInfo.Avatar,
|
||||||
Waiter: true,
|
// // // MsgType: 1,
|
||||||
SessionId: event.Client.SessionId,
|
// // // Content: msg,
|
||||||
Message: dto.Message{
|
// // //}
|
||||||
MsgType: 1,
|
// // //notice.BuildMessage(newRecord)
|
||||||
Text: msg,
|
// // //_, err = consts.ChatRoom.SendSessionMessage(robotInfo, wsClient.SessionId, ws.NewChatMsgType, notice)
|
||||||
LocalStamp: time.Now().Unix(),
|
// // err = logic.NewMessage(ctx, cache, chatUser, dto.NewMessageRequest{
|
||||||
},
|
// // Waiter: true,
|
||||||
})
|
// // SessionId: wsClient.SessionId,
|
||||||
},
|
// // Message: dto.Message{
|
||||||
}
|
// // MsgType: 1,
|
||||||
//logicFunc = func(msg string, cache *chatCache.ChatCache, chatUser *accountFiee.ChatUserData) error {
|
// // Text: msg,
|
||||||
// //var notice = dto.MessageListType{}
|
// // LocalStamp: time.Now().Unix(),
|
||||||
// //newRecord := &accountFiee.ChatRecordData{
|
// // },
|
||||||
// // SessionId: wsClient.SessionId,
|
// // })
|
||||||
// // UserId: wsClient.UserId,
|
// // return err
|
||||||
// // Name: wsClient.SessionId,
|
// //}
|
||||||
// // Avatar: robotInfo.Avatar,
|
// return
|
||||||
// // MsgType: 1,
|
//}
|
||||||
// // Content: msg,
|
//
|
||||||
// //}
|
//// 客服指定时间不回复则自动回复
|
||||||
// //notice.BuildMessage(newRecord)
|
//
|
||||||
// //_, err = consts.ChatRoom.SendSessionMessage(robotInfo, wsClient.SessionId, ws.NewChatMsgType, notice)
|
//type ReplyWhenWaiterNoAction struct {
|
||||||
// err = logic.NewMessage(ctx, cache, chatUser, dto.NewMessageRequest{
|
// DelaySecond time.Duration
|
||||||
// Waiter: true,
|
//}
|
||||||
// SessionId: wsClient.SessionId,
|
//
|
||||||
// Message: dto.Message{
|
////func NewReplyWhenWaiterNoAction(delaySecond time.Duration) *ReplyWhenWaiterNoAction {
|
||||||
// MsgType: 1,
|
//// return &ReplyWhenWaiterNoAction{
|
||||||
// Text: msg,
|
//// DelaySecond: delaySecond,
|
||||||
// LocalStamp: time.Now().Unix(),
|
//// }
|
||||||
// },
|
////}
|
||||||
// })
|
//
|
||||||
// return err
|
//func (k *ReplyWhenWaiterNoAction) Hit(event ws.ListenEventData, sender *accountFiee.ChatUserData) (hit bool, task RobotTask) {
|
||||||
//}
|
// if event.Client == nil || event.EventType != ws.EventChatMessage {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
// //客服和机器人的的消息不需要处理
|
||||||
// 客服指定时间不回复则自动回复
|
// if event.ChatUser.Role != 1 {
|
||||||
|
// return
|
||||||
type ReplyWhenWaiterNoAction struct {
|
// }
|
||||||
DelaySecond time.Duration
|
// hit = true // 立即保存SessionId的值
|
||||||
}
|
//
|
||||||
|
// clientSessionId := event.Client.SessionId
|
||||||
func NewReplyWhenWaiterNoAction(delaySecond time.Duration) *ReplyWhenWaiterNoAction {
|
// atUserId := event.Client.UserId
|
||||||
return &ReplyWhenWaiterNoAction{
|
// fmt.Printf("闭包前: clientSessionId=%s\n", clientSessionId)
|
||||||
DelaySecond: delaySecond,
|
// task = RobotTask{
|
||||||
}
|
// RunTime: time.Now().Add(k.DelaySecond * time.Second),
|
||||||
}
|
// Run: func(content string, cache *chatCache.ChatCache, Sender *accountFiee.ChatUserData) error {
|
||||||
|
// // 记录闭包执行时的Client状态
|
||||||
func (k *ReplyWhenWaiterNoAction) Hit(event ws.ListenEventData, sender *accountFiee.ChatUserData) (hit bool, task RobotTask) {
|
// fmt.Printf("闭包执行: clientSessionId=%s\n", clientSessionId)
|
||||||
if event.Client == nil || event.EventType != ws.EventChatMessage {
|
//
|
||||||
return
|
// //如果客服已经回复则不发送消息
|
||||||
}
|
// chatRecordListRes, err := service.AccountFieeProvider.GetChatRecordList(context.Background(), &accountFiee.GetChatRecordListRequest{
|
||||||
//客服的消息不需要处理
|
// Query: &accountFiee.ChatRecordData{
|
||||||
if event.ChatUser.Role == 2 {
|
// SessionId: event.Client.SessionId,
|
||||||
return
|
// },
|
||||||
}
|
// Page: 1,
|
||||||
hit = true
|
// PageSize: 1,
|
||||||
task = RobotTask{
|
// Order: "created_at desc",
|
||||||
RunTime: time.Now().Add(k.DelaySecond * time.Second),
|
// })
|
||||||
Run: func(content string, cache *chatCache.ChatCache, Sender *accountFiee.ChatUserData) error {
|
// if err != nil || chatRecordListRes.Total == 0 {
|
||||||
//如果客服已经回复则不发送消息
|
// return err
|
||||||
chatRecordListRes, err := service.AccountFieeProvider.GetChatRecordList(context.Background(), &accountFiee.GetChatRecordListRequest{
|
// }
|
||||||
Query: &accountFiee.ChatRecordData{
|
// checkUserId := chatRecordListRes.List[0].UserId
|
||||||
SessionId: event.Client.SessionId,
|
// checkChatUser, err := service.AccountFieeProvider.GetChatUserDetail(context.Background(), &accountFiee.GetChatUserByIdRequest{Id: checkUserId})
|
||||||
},
|
// if err != nil || checkChatUser.Role != 1 {
|
||||||
Page: 1,
|
// return err
|
||||||
PageSize: 1,
|
// }
|
||||||
Order: "created_at desc",
|
//
|
||||||
})
|
// //var notice = dto.MessageListType{}
|
||||||
if err != nil || chatRecordListRes.Total == 0 {
|
// //newRecord := &accountFiee.ChatRecordData{
|
||||||
return err
|
// // SessionId: wsClient.SessionId,
|
||||||
}
|
// // UserId: wsClient.UserId,
|
||||||
checkUserId := chatRecordListRes.List[0].UserId
|
// // Name: chatUser.NickName,
|
||||||
checkChatUser, err := service.AccountFieeProvider.GetChatUserDetail(context.Background(), &accountFiee.GetChatUserByIdRequest{Id: checkUserId})
|
// // Avatar: robotInfo.Avatar,
|
||||||
if err != nil || checkChatUser.Role != 1 {
|
// // MsgType: 1,
|
||||||
return err
|
// // Content: content,
|
||||||
}
|
// //}
|
||||||
|
// //notice.BuildMessage(newRecord)
|
||||||
//var notice = dto.MessageListType{}
|
// //_, err = consts.ChatRoom.SendSessionMessage(robotInfo, wsClient.SessionId, ws.NewChatMsgType, notice)
|
||||||
//newRecord := &accountFiee.ChatRecordData{
|
// //return err
|
||||||
// SessionId: wsClient.SessionId,
|
// fmt.Println("延时回复 sessionID:", clientSessionId)
|
||||||
// UserId: wsClient.UserId,
|
// err = logic.NewMessage(context.Background(), cache, sender, dto.NewMessageRequest{
|
||||||
// Name: chatUser.NickName,
|
// Waiter: true,
|
||||||
// Avatar: robotInfo.Avatar,
|
// Robot: true,
|
||||||
// MsgType: 1,
|
// AtUserId: atUserId,
|
||||||
// Content: content,
|
// SessionId: clientSessionId,
|
||||||
//}
|
// Message: dto.Message{
|
||||||
//notice.BuildMessage(newRecord)
|
// MsgType: 1,
|
||||||
//_, err = consts.ChatRoom.SendSessionMessage(robotInfo, wsClient.SessionId, ws.NewChatMsgType, notice)
|
// Text: content,
|
||||||
//return err
|
// LocalStamp: time.Now().Unix(),
|
||||||
err = logic.NewMessage(context.Background(), cache, sender, dto.NewMessageRequest{
|
// },
|
||||||
Waiter: true,
|
// })
|
||||||
SessionId: event.Client.SessionId,
|
// return err
|
||||||
Message: dto.Message{
|
// },
|
||||||
MsgType: 1,
|
// Response: "",
|
||||||
Text: content,
|
// ChatUser: event.ChatUser,
|
||||||
LocalStamp: time.Now().Unix(),
|
// }
|
||||||
},
|
// return
|
||||||
})
|
//
|
||||||
return err
|
//}
|
||||||
},
|
|
||||||
Response: "",
|
|
||||||
ChatUser: event.ChatUser,
|
|
||||||
}
|
|
||||||
return
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -57,7 +57,7 @@ func NewRobot(cache *chatCache.ChatCache) *Robot {
|
|||||||
cache: cache,
|
cache: cache,
|
||||||
}
|
}
|
||||||
err = r.ReloadRules(ctx)
|
err = r.ReloadRules(ctx)
|
||||||
fmt.Println("机器人规则加载失败")
|
fmt.Println("机器人规则加载完成,结果:", err)
|
||||||
consts.ChatRoom.RegisterEventListener(r.EventListener)
|
consts.ChatRoom.RegisterEventListener(r.EventListener)
|
||||||
go r.Run()
|
go r.Run()
|
||||||
return r
|
return r
|
||||||
@ -66,7 +66,7 @@ func NewRobot(cache *chatCache.ChatCache) *Robot {
|
|||||||
type Robot struct {
|
type Robot struct {
|
||||||
Info *accountFiee.ChatUserData //机器人信息
|
Info *accountFiee.ChatUserData //机器人信息
|
||||||
Rules []Reply //回复规则
|
Rules []Reply //回复规则
|
||||||
DelayTask []RobotTask //演示任务
|
DelayTask []IRobotTask //演示任务
|
||||||
ticker *time.Ticker //定时器
|
ticker *time.Ticker //定时器
|
||||||
stopChan chan struct{} //停止管道
|
stopChan chan struct{} //停止管道
|
||||||
isRunning bool //运行状态
|
isRunning bool //运行状态
|
||||||
@ -140,12 +140,12 @@ func (r *Robot) Run() {
|
|||||||
//return // 没有任务时退出
|
//return // 没有任务时退出
|
||||||
}
|
}
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
var remainingTasks []RobotTask
|
var remainingTasks []IRobotTask
|
||||||
for _, task := range r.DelayTask {
|
for _, task := range r.DelayTask {
|
||||||
if now.After(task.RunTime) {
|
if now.After(task.RunTime()) {
|
||||||
// 执行任务
|
// 执行任务
|
||||||
go func() {
|
go func() {
|
||||||
err := task.Run(task.Response, r.cache, task.ChatUser)
|
err := task.Run(r.cache)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("聊天机器人[%d]延时回复消息失败:%v", r.Info.ID, err)
|
log.Printf("聊天机器人[%d]延时回复消息失败:%v", r.Info.ID, err)
|
||||||
} else {
|
} else {
|
||||||
@ -163,23 +163,26 @@ func (r *Robot) Run() {
|
|||||||
return
|
return
|
||||||
case event := <-r.EventListener.Chan:
|
case event := <-r.EventListener.Chan:
|
||||||
fmt.Printf("robot listen event:%#v\n", event)
|
fmt.Printf("robot listen event:%#v\n", event)
|
||||||
|
r.mu.Lock()
|
||||||
for _, ruleResponse := range r.Rules {
|
for _, ruleResponse := range r.Rules {
|
||||||
hit, task := ruleResponse.Hit(event, r.Info)
|
hit, task := ruleResponse.Hit(event, r.Info)
|
||||||
if hit {
|
if hit {
|
||||||
if task.RunTime.IsZero() {
|
fmt.Println("命中规则:", ruleResponse.Title)
|
||||||
err := task.Run(ruleResponse.Response, r.cache, r.Info)
|
if task.RunTime().IsZero() {
|
||||||
|
task.SetResponse(ruleResponse.Response)
|
||||||
|
err := task.Run(r.cache)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("robot 执行任务失败:%v\n", err)
|
log.Printf("robot 执行任务失败:%v\n", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ruleResponse := ruleResponse
|
ruleResponse := ruleResponse
|
||||||
task.Response = ruleResponse.Response
|
task.SetResponse(ruleResponse.Response)
|
||||||
r.RegisterDelayTask(task)
|
r.RegisterDelayTask(task)
|
||||||
|
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
r.mu.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,9 +195,7 @@ func (r *Robot) Stop() {
|
|||||||
}
|
}
|
||||||
r.mu.Unlock()
|
r.mu.Unlock()
|
||||||
}
|
}
|
||||||
func (r *Robot) RegisterDelayTask(task RobotTask) {
|
func (r *Robot) RegisterDelayTask(task IRobotTask) {
|
||||||
r.mu.Lock()
|
|
||||||
defer r.mu.Unlock()
|
|
||||||
if task.Run == nil {
|
if task.Run == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
package robot
|
package robot
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"fonchain-fiee/pkg/service/asChat/dto"
|
"fonchain-fiee/pkg/service/asChat/dto"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@ -14,6 +15,7 @@ import (
|
|||||||
// 自动回复规则结构转换
|
// 自动回复规则结构转换
|
||||||
func ParseReplyRule(data *dto.ChatAutoReplyData) (r Reply) {
|
func ParseReplyRule(data *dto.ChatAutoReplyData) (r Reply) {
|
||||||
r.Response = data.Response
|
r.Response = data.Response
|
||||||
|
r.Title = data.Title
|
||||||
for ruleName, v := range data.Rules {
|
for ruleName, v := range data.Rules {
|
||||||
if !v.Enable {
|
if !v.Enable {
|
||||||
continue
|
continue
|
||||||
@ -26,6 +28,7 @@ func ParseReplyRule(data *dto.ChatAutoReplyData) (r Reply) {
|
|||||||
} else {
|
} else {
|
||||||
keywords = strings.Split(v.Content, ",")
|
keywords = strings.Split(v.Content, ",")
|
||||||
}
|
}
|
||||||
|
fmt.Println("ParseReplyRule 解析keywords:", keywords)
|
||||||
r.Rules = append(r.Rules, NewReplyWhenHitKeywords(keywords))
|
r.Rules = append(r.Rules, NewReplyWhenHitKeywords(keywords))
|
||||||
case "joinSession": //加入聊天后回复
|
case "joinSession": //加入聊天后回复
|
||||||
r.Rules = append(r.Rules, NewReplyWhenUserJoinSession())
|
r.Rules = append(r.Rules, NewReplyWhenUserJoinSession())
|
||||||
|
98
pkg/service/asChat/robot/ruler_ReplyWhenWaiterNoAction.go
Normal file
98
pkg/service/asChat/robot/ruler_ReplyWhenWaiterNoAction.go
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
// Package robot -----------------------------
|
||||||
|
// @file : ruler_ReplyWhenWaiterNoAction.go
|
||||||
|
// @author : JJXu
|
||||||
|
// @contact : wavingbear@163.com
|
||||||
|
// @time : 2025/6/13 18:02
|
||||||
|
// -------------------------------------------
|
||||||
|
package robot
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"fonchain-fiee/api/accountFiee"
|
||||||
|
"fonchain-fiee/pkg/common/ws"
|
||||||
|
"fonchain-fiee/pkg/service"
|
||||||
|
"fonchain-fiee/pkg/service/asChat/chatCache"
|
||||||
|
"fonchain-fiee/pkg/service/asChat/dto"
|
||||||
|
"fonchain-fiee/pkg/service/asChat/logic"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IRobotTask interface {
|
||||||
|
Hit(event ws.ListenEventData, sender *accountFiee.ChatUserData) (hit bool)
|
||||||
|
Run(cache *chatCache.ChatCache) error
|
||||||
|
RunTime() time.Time
|
||||||
|
SetResponse(response string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 客服指定时间不回复则自动回复
|
||||||
|
func NewReplyWhenWaiterNoAction(delaySecond time.Duration) IRobotTask {
|
||||||
|
return &RobotTaskReplyWhenWaiterNoAction{
|
||||||
|
delaySecond: delaySecond,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type RobotTaskReplyWhenWaiterNoAction struct {
|
||||||
|
runTime time.Time
|
||||||
|
Response string
|
||||||
|
Receiver *accountFiee.ChatUserData
|
||||||
|
Sender *accountFiee.ChatUserData
|
||||||
|
Msg string
|
||||||
|
Resp string
|
||||||
|
delaySecond time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RobotTaskReplyWhenWaiterNoAction) Hit(event ws.ListenEventData, sender *accountFiee.ChatUserData) (hit bool) {
|
||||||
|
if event.Client == nil || event.EventType != ws.EventChatMessage {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//客服和机器人的的消息不需要处理
|
||||||
|
if event.ChatUser.Role != 1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
hit = true // 立即保存SessionId的值
|
||||||
|
r.Sender = sender
|
||||||
|
r.Receiver = event.ChatUser
|
||||||
|
r.runTime = time.Now().Add(r.delaySecond * time.Second)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RobotTaskReplyWhenWaiterNoAction) Run(cache *chatCache.ChatCache) error {
|
||||||
|
clientSessionId := fmt.Sprintf("%d", r.Receiver.ID)
|
||||||
|
fmt.Println("延时回复 sessionID:", clientSessionId)
|
||||||
|
//如果客服已经回复则不发送消息
|
||||||
|
chatRecordListRes, err := service.AccountFieeProvider.GetChatRecordList(context.Background(), &accountFiee.GetChatRecordListRequest{
|
||||||
|
Query: &accountFiee.ChatRecordData{
|
||||||
|
SessionId: clientSessionId,
|
||||||
|
},
|
||||||
|
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
|
||||||
|
}
|
||||||
|
err = logic.NewMessage(context.Background(), cache, r.Sender, dto.NewMessageRequest{
|
||||||
|
Waiter: true,
|
||||||
|
Robot: true,
|
||||||
|
AtUserId: r.Receiver.ID,
|
||||||
|
SessionId: clientSessionId,
|
||||||
|
Message: dto.Message{
|
||||||
|
MsgType: 1,
|
||||||
|
Text: r.Resp,
|
||||||
|
LocalStamp: time.Now().Unix(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
func (r *RobotTaskReplyWhenWaiterNoAction) RunTime() time.Time {
|
||||||
|
return r.runTime
|
||||||
|
}
|
||||||
|
func (r *RobotTaskReplyWhenWaiterNoAction) SetResponse(response string) {
|
||||||
|
r.Resp = response
|
||||||
|
}
|
69
pkg/service/asChat/robot/ruler_keywords.go
Normal file
69
pkg/service/asChat/robot/ruler_keywords.go
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
package robot
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"fonchain-fiee/api/accountFiee"
|
||||||
|
"fonchain-fiee/pkg/common/ws"
|
||||||
|
"fonchain-fiee/pkg/service/asChat/chatCache"
|
||||||
|
"fonchain-fiee/pkg/service/asChat/dto"
|
||||||
|
"fonchain-fiee/pkg/service/asChat/logic"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RobotTaskWithKeyworkds struct {
|
||||||
|
runTime time.Time
|
||||||
|
Response string
|
||||||
|
Receiver *accountFiee.ChatUserData
|
||||||
|
Sender *accountFiee.ChatUserData
|
||||||
|
Msg string
|
||||||
|
Resp string
|
||||||
|
keywords []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewReplyWhenHitKeywords(keywords []string) IRobotTask {
|
||||||
|
return &RobotTaskWithKeyworkds{keywords: keywords}
|
||||||
|
}
|
||||||
|
func (r *RobotTaskWithKeyworkds) Hit(event ws.ListenEventData, sender *accountFiee.ChatUserData) (hit bool) {
|
||||||
|
if event.EventType != ws.EventChatMessage || event.Msg == "" || event.Client == nil || event.ChatUser == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if event.ChatUser.Role != 1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r.Sender = sender
|
||||||
|
r.Receiver = event.ChatUser
|
||||||
|
for _, v := range r.keywords {
|
||||||
|
if strings.Contains(event.Msg, v) {
|
||||||
|
fmt.Printf("关键词比对:%s ----- %s : true", event.Msg, v)
|
||||||
|
hit = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
fmt.Printf("关键词比对:%s ----- %s: false", event.Msg, v)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RobotTaskWithKeyworkds) Run(cache *chatCache.ChatCache) (err error) {
|
||||||
|
err = logic.NewMessage(context.Background(), cache, r.Sender, dto.NewMessageRequest{
|
||||||
|
Waiter: true,
|
||||||
|
Robot: true,
|
||||||
|
AtUserId: r.Receiver.ID,
|
||||||
|
SessionId: fmt.Sprintf("%d", r.Receiver.ID),
|
||||||
|
Message: dto.Message{
|
||||||
|
MsgType: 1,
|
||||||
|
Text: r.Resp,
|
||||||
|
LocalStamp: time.Now().Unix(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RobotTaskWithKeyworkds) RunTime() time.Time {
|
||||||
|
return time.Time{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RobotTaskWithKeyworkds) SetResponse(response string) {
|
||||||
|
r.Resp = response
|
||||||
|
}
|
85
pkg/service/asChat/robot/ruler_replyWhenUserJoinSession.go
Normal file
85
pkg/service/asChat/robot/ruler_replyWhenUserJoinSession.go
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
package robot
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fonchain-fiee/api/accountFiee"
|
||||||
|
"fonchain-fiee/pkg/common/ws"
|
||||||
|
"fonchain-fiee/pkg/service"
|
||||||
|
"fonchain-fiee/pkg/service/asChat/chatCache"
|
||||||
|
"fonchain-fiee/pkg/service/asChat/dto"
|
||||||
|
"fonchain-fiee/pkg/service/asChat/logic"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewReplyWhenUserJoinSession() IRobotTask {
|
||||||
|
return &ReplyWhenUserJoinSession{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReplyWhenUserJoinSession struct {
|
||||||
|
Response string
|
||||||
|
Sender *accountFiee.ChatUserData
|
||||||
|
Msg string
|
||||||
|
Resp string
|
||||||
|
sessionId string
|
||||||
|
atUserId int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ReplyWhenUserJoinSession) Hit(event ws.ListenEventData, sender *accountFiee.ChatUserData) (hit bool) {
|
||||||
|
if event.EventType != ws.EventUserJoin {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if event.Client == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx := context.Background()
|
||||||
|
queryRes, err := service.AccountFieeProvider.GetChatRecordList(ctx, &accountFiee.GetChatRecordListRequest{
|
||||||
|
Query: &accountFiee.ChatRecordData{
|
||||||
|
SessionId: event.Client.SessionId,
|
||||||
|
},
|
||||||
|
Page: 1,
|
||||||
|
PageSize: 1,
|
||||||
|
Order: "created_at desc",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//如果最近一次的消息也是机器人发送的,就不再发送了
|
||||||
|
for i, v := range queryRes.List {
|
||||||
|
if i == 0 {
|
||||||
|
if v.UserId == sender.ID {
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hit = true
|
||||||
|
r.Sender = sender
|
||||||
|
r.sessionId = event.Client.SessionId
|
||||||
|
r.atUserId, _ = strconv.Atoi(event.Client.SessionId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ReplyWhenUserJoinSession) Run(cache *chatCache.ChatCache) (err error) {
|
||||||
|
err = logic.NewMessage(context.Background(), cache, r.Sender, dto.NewMessageRequest{
|
||||||
|
Waiter: true,
|
||||||
|
Robot: true,
|
||||||
|
AtUserId: int64(r.atUserId),
|
||||||
|
SessionId: r.sessionId,
|
||||||
|
Message: dto.Message{
|
||||||
|
MsgType: 1,
|
||||||
|
Text: r.Resp,
|
||||||
|
LocalStamp: time.Now().Unix(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ReplyWhenUserJoinSession) RunTime() time.Time {
|
||||||
|
return time.Time{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ReplyWhenUserJoinSession) SetResponse(response string) {
|
||||||
|
r.Resp = response
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user