diff --git a/pkg/service/asChat/robot/KeywordsReplyRuler.go b/pkg/service/asChat/robot/KeywordsReplyRuler.go index 5d921a1..ecdbc45 100644 --- a/pkg/service/asChat/robot/KeywordsReplyRuler.go +++ b/pkg/service/asChat/robot/KeywordsReplyRuler.go @@ -24,8 +24,8 @@ import ( //} type AutoReply struct { - Response string `json:"response"` - Rules map[string]IRule `json:"rules"` + Response string `json:"response"` + Rules map[string]IRobotTask `json:"rules"` } type AutoReplyRule struct { Enable bool `json:"enable"` diff --git a/pkg/service/asChat/robot/readme.md b/pkg/service/asChat/robot/readme.md index b8a2c56..0e1b1fb 100644 --- a/pkg/service/asChat/robot/readme.md +++ b/pkg/service/asChat/robot/readme.md @@ -26,3 +26,6 @@ web端和后端交互式时,增删改查的规则配置是存放在rules对象 - keywords :关键字回复 - joinSession:用户打开聊天窗口后 - noReplyAfter:客服指定时间没有回复后 + +## 注意 +- 目前不支持用户多端登录,会导致用户收到重复消息 \ No newline at end of file diff --git a/pkg/service/asChat/robot/replyAndRuler.go b/pkg/service/asChat/robot/replyAndRuler.go index 4c90121..0483d9d 100644 --- a/pkg/service/asChat/robot/replyAndRuler.go +++ b/pkg/service/asChat/robot/replyAndRuler.go @@ -7,28 +7,20 @@ 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" - "strings" - "time" ) // 回复规则 type Reply struct { Title string Response string - Rules []IRule + Rules []IRobotTask } -func (r *Reply) Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserData) (hit bool, task RobotTask) { - for _, rule := range r.Rules { - hit, task = rule.Hit(event, robotInfo) +func (r *Reply) Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserData) (hit bool, rule IRobotTask) { + for _, rule = range r.Rules { + hit = rule.Hit(event, robotInfo) if hit { return } @@ -36,232 +28,219 @@ func (r *Reply) Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserDat return } -// 规则接口 -type IRule interface { - Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserData) (hit bool, task RobotTask) -} - -// KeywordsRuleChecker 关键字回复 -type ReplyWhenHitKeywords struct { - Keywords []string `json:"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 { - return - } - if event.ChatUser.Role != 1 { - return - } - for _, v := range k.Keywords { - if strings.Contains(event.Msg, v) { - hit = true - break - } - } - 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{} -} - -func (k ReplyWhenUserJoinSession) Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserData) (hit bool, task RobotTask) { - 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 == robotInfo.ID { - return - } else { - break - } - } - } - hit = true - if event.ChatUser == nil { - event.ChatUser, err = service.AccountFieeProvider.GetChatUserDetail(context.Background(), &accountFiee.GetChatUserByIdRequest{Id: event.Client.UserId}) - if err != nil { - return - } - } - 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, - } -} - -func (k *ReplyWhenWaiterNoAction) Hit(event ws.ListenEventData, sender *accountFiee.ChatUserData) (hit bool, task RobotTask) { - if event.Client == nil || event.EventType != ws.EventChatMessage { - return - } - //客服和机器人的的消息不需要处理 - if event.ChatUser.Role != 1 { - return - } - hit = true // 立即保存SessionId的值 - clientSessionId := event.Client.SessionId - - fmt.Printf("闭包前: clientSessionId=%s\n", clientSessionId) - task = RobotTask{ - RunTime: time.Now().Add(k.DelaySecond * time.Second), - Run: func(content string, cache *chatCache.ChatCache, Sender *accountFiee.ChatUserData) error { - // 记录闭包执行时的Client状态 - fmt.Printf("闭包执行: clientSessionId=%s\n", clientSessionId) - - //如果客服已经回复则不发送消息 - 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 - } - - //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 - fmt.Println("延时回复 sessionID:", clientSessionId) - err = logic.NewMessage(context.Background(), cache, sender, dto.NewMessageRequest{ - Waiter: true, - SessionId: clientSessionId, - Message: dto.Message{ - MsgType: 1, - Text: content, - LocalStamp: time.Now().Unix(), - }, - }) - return err - }, - Response: "", - ChatUser: event.ChatUser, - } - return - -} +// +//// 规则接口 +//type IRule interface { +// Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserData) (hit bool, task RobotTask) +//} +// +//// KeywordsRuleChecker 关键字回复 +//type ReplyWhenHitKeywords struct { +// Keywords []string `json:"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 { +// return +// } +// if event.ChatUser.Role != 1 { +// return +// } +// for _, v := range k.Keywords { +// if strings.Contains(event.Msg, v) { +// hit = true +// break +// } +// } +// atUserId := event.Client.UserId +// 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, +// Robot: true, +// AtUserId: atUserId, +// SessionId: event.Client.SessionId, +// Message: dto.Message{ +// MsgType: 1, +// Text: msg, +// LocalStamp: time.Now().Unix(), +// }, +// }) +// }, +// } +// return +//} +// +//// 用户打开聊天会话直接发送 +//type ReplyWhenUserJoinSession struct { +//} +// +//func NewReplyWhenUserJoinSession() IRule { +// return &ReplyWhenUserJoinSession{} +//} +// +//func (k ReplyWhenUserJoinSession) Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserData) (hit bool, task RobotTask) { +// if event.EventType != ws.EventUserJoin { +// return +// } +// if event.Client == nil { +// return +// } +// clientSessionId := event.Client.SessionId +// atUserId := event.Client.UserId +// 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 == robotInfo.ID { +// return +// } else { +// break +// } +// } +// } +// hit = true +// if event.ChatUser == nil { +// event.ChatUser, err = service.AccountFieeProvider.GetChatUserDetail(context.Background(), &accountFiee.GetChatUserByIdRequest{Id: event.Client.UserId}) +// if err != nil { +// return +// } +// } +// 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, +// Robot: true, +// AtUserId: atUserId, +// SessionId: clientSessionId, +// 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, +//// } +////} +// +//func (k *ReplyWhenWaiterNoAction) Hit(event ws.ListenEventData, sender *accountFiee.ChatUserData) (hit bool, task RobotTask) { +// if event.Client == nil || event.EventType != ws.EventChatMessage { +// return +// } +// //客服和机器人的的消息不需要处理 +// if event.ChatUser.Role != 1 { +// return +// } +// hit = true // 立即保存SessionId的值 +// +// clientSessionId := event.Client.SessionId +// atUserId := event.Client.UserId +// fmt.Printf("闭包前: clientSessionId=%s\n", clientSessionId) +// task = RobotTask{ +// RunTime: time.Now().Add(k.DelaySecond * time.Second), +// Run: func(content string, cache *chatCache.ChatCache, Sender *accountFiee.ChatUserData) error { +// // 记录闭包执行时的Client状态 +// fmt.Printf("闭包执行: clientSessionId=%s\n", clientSessionId) +// +// //如果客服已经回复则不发送消息 +// 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 +// } +// +// //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 +// fmt.Println("延时回复 sessionID:", clientSessionId) +// err = logic.NewMessage(context.Background(), cache, sender, dto.NewMessageRequest{ +// Waiter: true, +// Robot: true, +// AtUserId: atUserId, +// SessionId: clientSessionId, +// Message: dto.Message{ +// MsgType: 1, +// Text: content, +// LocalStamp: time.Now().Unix(), +// }, +// }) +// return err +// }, +// Response: "", +// ChatUser: event.ChatUser, +// } +// return +// +//} diff --git a/pkg/service/asChat/robot/robot.go b/pkg/service/asChat/robot/robot.go index c78a278..8cdbaf4 100644 --- a/pkg/service/asChat/robot/robot.go +++ b/pkg/service/asChat/robot/robot.go @@ -57,7 +57,7 @@ func NewRobot(cache *chatCache.ChatCache) *Robot { cache: cache, } err = r.ReloadRules(ctx) - fmt.Println("机器人规则加载失败") + fmt.Println("机器人规则加载完成,结果:", err) consts.ChatRoom.RegisterEventListener(r.EventListener) go r.Run() return r @@ -66,7 +66,7 @@ func NewRobot(cache *chatCache.ChatCache) *Robot { type Robot struct { Info *accountFiee.ChatUserData //机器人信息 Rules []Reply //回复规则 - DelayTask []RobotTask //演示任务 + DelayTask []IRobotTask //演示任务 ticker *time.Ticker //定时器 stopChan chan struct{} //停止管道 isRunning bool //运行状态 @@ -140,12 +140,12 @@ func (r *Robot) Run() { //return // 没有任务时退出 } now := time.Now() - var remainingTasks []RobotTask + var remainingTasks []IRobotTask for _, task := range r.DelayTask { - if now.After(task.RunTime) { + if now.After(task.RunTime()) { // 执行任务 go func() { - err := task.Run(task.Response, r.cache, task.ChatUser) + err := task.Run(r.cache) if err != nil { log.Printf("聊天机器人[%d]延时回复消息失败:%v", r.Info.ID, err) } else { @@ -167,16 +167,16 @@ func (r *Robot) Run() { hit, task := ruleResponse.Hit(event, r.Info) if hit { fmt.Println("命中规则:", ruleResponse.Title) - if task.RunTime.IsZero() { - 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 { log.Printf("robot 执行任务失败:%v\n", err) } } else { ruleResponse := ruleResponse - task.Response = ruleResponse.Response + task.SetResponse(ruleResponse.Response) r.RegisterDelayTask(task) - } break } @@ -193,7 +193,7 @@ func (r *Robot) Stop() { } 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 { diff --git a/pkg/service/asChat/robot/ruler_ReplyWhenWaiterNoAction.go b/pkg/service/asChat/robot/ruler_ReplyWhenWaiterNoAction.go new file mode 100644 index 0000000..8d27646 --- /dev/null +++ b/pkg/service/asChat/robot/ruler_ReplyWhenWaiterNoAction.go @@ -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 +} diff --git a/pkg/service/asChat/robot/ruler_keywords.go b/pkg/service/asChat/robot/ruler_keywords.go new file mode 100644 index 0000000..2555527 --- /dev/null +++ b/pkg/service/asChat/robot/ruler_keywords.go @@ -0,0 +1,67 @@ +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) { + hit = true + break + } + } + 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 +} diff --git a/pkg/service/asChat/robot/ruler_replyWhenUserJoinSession.go b/pkg/service/asChat/robot/ruler_replyWhenUserJoinSession.go new file mode 100644 index 0000000..1f4532f --- /dev/null +++ b/pkg/service/asChat/robot/ruler_replyWhenUserJoinSession.go @@ -0,0 +1,86 @@ +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" +) + +func NewReplyWhenUserJoinSession() IRobotTask { + return &ReplyWhenUserJoinSession{} +} + +type ReplyWhenUserJoinSession struct { + Response string + Receiver *accountFiee.ChatUserData + Sender *accountFiee.ChatUserData + Msg string + Resp string +} + +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.Receiver = event.ChatUser + return +} + +func (r ReplyWhenUserJoinSession) Run(cache *chatCache.ChatCache) (err error) { + clientSessionId := fmt.Sprintf("%d", r.Receiver.ID) + 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 +} + +func (r ReplyWhenUserJoinSession) RunTime() time.Time { + //TODO implement me + panic("implement me") +} + +func (r ReplyWhenUserJoinSession) SetResponse(response string) { + //TODO implement me + panic("implement me") +}