This commit is contained in:
richboo111
2024-02-06 14:42:51 +08:00
parent 0333466b01
commit 2e33b86a7b
4 changed files with 273 additions and 42 deletions

View File

@@ -12,6 +12,7 @@ type ICacher interface {
GetAs(key string, ptr interface{}) error
Keys(prefix string) ([]string, error)
GetString(key string) string
FlushDB() error
Incr(key string) error
LRange(key string) (retVal []string)

View File

@@ -1,6 +1,7 @@
package redis
import (
"encoding/json"
"fmt"
"time"
@@ -60,6 +61,18 @@ func (c *Cacher) Get(key string) interface{} {
return nil
}
func (c *Cacher) GetString(key string) string {
result, err := c.client.Get(key).Result()
if err == nil {
//return result
var retVal interface{}
if err = json.Unmarshal([]byte(result), &retVal); err == nil {
return retVal.(string)
}
}
return ""
}
func (c *Cacher) GetAs(key string, ptr interface{}) error {
result, err := c.client.Get(key).Result()
if err == nil {

View File

@@ -262,6 +262,9 @@ func ReadMsgFromVendor(vendorID int, elmAppID string, msg []byte) error {
errList.AddErr(fmt.Errorf("客服自动回复出错:%v", err))
}
//5延迟40s 自动回复
//timer := time.NewTimer(30 * time.Second)
if errList.GetErrListAsOne() != nil {
return fmt.Errorf("ReadMsgFromVendor:%v", errList.GetErrListAsOne())
}
@@ -519,10 +522,11 @@ type AutoReply struct {
Timestamp int `json:"timestamp"` //消息接收时间
}
// CheckAndReply 判断并回复
// CheckAndReply 判断并回复V1
func CheckAndReply(req *JXMsg, elmAppID string) (err error) {
var (
key string
key string
//keyDetail UserRelInfo
flag = false
vendorID int
errList errlist.ErrList
@@ -540,8 +544,14 @@ func CheckAndReply(req *JXMsg, elmAppID string) (err error) {
}
key = utils.Int2Str(mt.AppID) + ":" + utils.Int2Str(mt.OpenUserID) + ":autoReply"
keyDetailMt := UserRelInfo{
AppID: utils.Int2Str(mt.AppID),
VendorStoreID: mt.AppPoiCode,
VendorID: VendorIDMTStr,
UserID: utils.Int2Str(mt.OpenUserID),
}
//1 检测是否已自动回复
flag = GetIfReply(key)
flag = GetIfReply(key, keyDetailMt)
//判断flag状态
if !flag {
apply = &AutoReply{
@@ -553,8 +563,8 @@ func CheckAndReply(req *JXMsg, elmAppID string) (err error) {
temp := mt
//获取自定义回复模板
if template := GetCustomTemplate(utils.Int2Str(mt.AppID), mt.AppPoiCode); len(template) > 0 {
temp.MsgContent = template
if template := GetCustomTemplate(utils.Int2Str(mt.AppID), mt.AppPoiCode); len(template.Template) > 0 {
temp.MsgContent = template.Template
} else {
temp.MsgContent, err = GetDefaultTemplate(utils.Int2Str(mt.AppID), mt.AppPoiCode, VendorIDMT)
if err != nil {
@@ -575,22 +585,11 @@ func CheckAndReply(req *JXMsg, elmAppID string) (err error) {
SendType: SendTypeJx,
MsgContent: temp,
}
//userList = &UserMessageList{
// VendorID: VendorIDMT,
// UserID: utils.Int2Str(mt.OpenUserID),
// LatestMsg: mt.MsgContent,
// LatestTime: mt.Cts,
// OrderID: "",
//}
//1 存储详细聊天记录
// 存储详细聊天记录
if err = SetMessageDetail(jxMsg, vendorID, elmAppID); err != nil {
errList.AddErr(fmt.Errorf("自动回复:存储详细聊天记录错误:%v", err))
}
//2 存储展示列表时单条数据
//if err = SetUserList(jxMsg, userList, vendorID, elmAppID); err != nil {
// errList.AddErr(fmt.Errorf("自动回复存储STU聊天记录错误%v", err))
//}
}
//3 记录自动回复状态
if err = RecordAutoStatus(key, apply); err != nil {
@@ -608,8 +607,14 @@ func CheckAndReply(req *JXMsg, elmAppID string) (err error) {
return nil
}
keyDetailElm := UserRelInfo{
AppID: elmAppID,
VendorStoreID: elm.PlatformShopID,
VendorID: VendorIDELMStr,
UserID: elm.PayLoad.GroupID,
}
//1 检测是否已自动回复
flag = GetIfReply(key)
flag = GetIfReply(key, keyDetailElm)
if !flag {
apply = &AutoReply{
UserID: utils.Str2Int(elm.PayLoad.SenderID),
@@ -631,8 +636,8 @@ func CheckAndReply(req *JXMsg, elmAppID string) (err error) {
}
temp := ""
if template := GetCustomTemplate(elmAppID, elm.PlatformShopID); len(template) > 0 {
temp = template
if template := GetCustomTemplate(elmAppID, elm.PlatformShopID); len(template.Template) > 0 {
temp = template.Template
} else {
temp, err = GetDefaultTemplate(elmAppID, elm.PlatformShopID, VendorIDELM)
if err != nil {
@@ -645,33 +650,23 @@ func CheckAndReply(req *JXMsg, elmAppID string) (err error) {
//Text: temp,
}
tempContentStr, _ := json.Marshal(tempContent)
param.PayLoad.Content = string(tempContentStr)
if err = partner.CurAPIManager.GetAPI(model.VendorIDEBAI, elmAppID).(*ebaiapi.API).BusinessSendMsg(param); err != nil {
apply.IsApply = false
globals.SugarLogger.Debugf("CheckAndReply mtSend err:%v", err)
} else {
//t1 := json.Unmarshal(param.Payload.Content)
jxMsg = &JXMsg{
SendType: SendTypeJx,
MsgContent: param,
}
//userList = &UserMessageList{
// VendorID: VendorIDELM,
// UserID: elm.PayLoad.SenderID,
// LatestMsg: elm.PayLoad.Content,
// LatestTime: elm.PayLoad.CreateTime,
// OrderID: "",
//}
//1 存储详细聊天记录list
//存储详细聊天记录list
if err = SetMessageDetail(jxMsg, vendorID, elmAppID); err != nil {
errList.AddErr(fmt.Errorf("自动回复:存储详细聊天记录错误:%v", err))
}
//2 存储展示列表时单条数据
//if err = SetUserList(jxMsg, userList, vendorID, elmAppID); err != nil {
// errList.AddErr(fmt.Errorf("自动回复存储STU聊天记录错误%v", err))
//}
}
//3 记录自动回复状态
if err = RecordAutoStatus(key, apply); err != nil {
@@ -686,8 +681,170 @@ func CheckAndReply(req *JXMsg, elmAppID string) (err error) {
return nil
}
// CheckAndReplyV2 判断并回复V2 延迟35s
//func CheckAndReplyV2(req *JXMsg, elmAppID string) (err error) {
// var (
// key string
// vendorID int
// errList errlist.ErrList
// jxMsg = &JXMsg{}
// )
//
// if req.SendType == SendTypeMt {
// vendorID = VendorIDMT
// mt := req.MsgContent.(mtwmapi.PushContentReq)
// //获取聊天详情
// imDetail, err := GetImChatDetail([]UserRelInfo{{
// VendorStoreID: mt.AppPoiCode,
// VendorID: VendorIDMTStr,
// AppID: utils.Int2Str(mt.AppID),
// UserID: utils.Int2Str(mt.OpenUserID),
// }})
// if err != nil {
// return err
// }
// if len(imDetail) > 0 {
// //获取此消息列表最后一条数据
// key = GenMsgDetailID(req, VendorIDMT, elmAppID)
// temp := imDetail[key][len(imDetail)-1]
// tStr, _ := json.Marshal(temp)
//
// lastMsg := &JXMsg{}
// err = json.Unmarshal(tStr, lastMsg)
// if err != nil {
// return err
// }
// //京西发送或美团商家发送 跳过
// if lastMsg.SendType == SendTypeJx {
// return nil
// }
//
// lastMt := lastMsg.MsgContent.(mtwmapi.PushContentReq)
// if lastMt.MsgSource == mtwmapi.MsgSourceStore {
// return nil
// }
//
// //生成回复消息体
// sendMt := mt
// //获取自定义回复模板
// if template := GetCustomTemplate(utils.Int2Str(mt.AppID), mt.AppPoiCode); len(template) > 0 {
// sendMt.MsgContent = template
// } else {
// sendMt.MsgContent, err = GetDefaultTemplate(utils.Int2Str(mt.AppID), mt.AppPoiCode, VendorIDMT)
// if err != nil {
// sendMt.MsgContent = AutoReplyByAppID[mt.AppID]
// }
// }
// sendMt.MsgType = mtwmapi.MsgTypeText
// sendMt.MsgSource = mtwmapi.MsgSourceStore
// sendMt.Cts = int(time.Now().Unix())
// sendMt.MsgID = RandTimeNumber()
//
// //向美团发送消息
// dataStr, _ := json.Marshal(sendMt)
// if _, err = partner.CurAPIManager.GetAPI(model.VendorIDMTWM, utils.Int2Str(mt.AppID)).(*mtwmapi.API).MsgSend(string(dataStr)); err != nil {
// globals.SugarLogger.Debugf("CheckAndReply mtSend err:%v", err)
// return err
// } else {
// jxMsg = &JXMsg{
// SendType: SendTypeJx,
// MsgContent: temp,
// }
// if err = SetMessageDetail(jxMsg, vendorID, elmAppID); err != nil {
// errList.AddErr(fmt.Errorf("自动回复V2存储详细聊天记录错误%v", err))
// }
// }
// }
// }
//
// if req.SendType == SendTypeElm {
// vendorID = VendorIDELM
// elm := req.MsgContent.(ebaiapi.ImMessageSend)
// imDetail, err := GetImChatDetail([]UserRelInfo{{
// VendorStoreID: elm.PlatformShopID,
// VendorID: VendorIDELMStr,
// AppID: elmAppID,
// UserID: elm.PayLoad.SenderID,
// }})
// if err != nil {
// return err
// }
// if len(imDetail) > 0 {
// //获取此消息列表最后一条数据
// key = GenMsgDetailID(req, VendorIDELM, elmAppID)
// temp := imDetail[key][len(imDetail)-1]
// tStr, _ := json.Marshal(temp)
//
// lastMsg := &JXMsg{}
// err = json.Unmarshal(tStr, lastMsg)
// if err != nil {
// return err
// }
// //京西发送或美团商家发送 跳过
// if lastMsg.SendType == SendTypeJx {
// return nil
// }
//
// //结构不一样后解
// lastElm := lastMsg.MsgContent.(ebaiapi.ImMessageSend)
// if lastElm.PayLoad.SenderID == "" || elm.PayLoad.SenderID[:2] != ebaiapi.SenderTypeUser {
// return nil
// }
//
// param := &ebaiapi.BusinessSendMsgReq{
// PlatformShopId: elm.PlatformShopID,
// BizType: ebaiapi.IMType,
// SubBizType: ebaiapi.IMTypeSendMsg,
// PayLoad: ebaiapi.BusinessMsgPayload{
// GroupId: elm.PayLoad.GroupID,
// MsgId: utils.Int2Str(RandTimeNumber()),
// ReceiverIds: elm.PayLoad.ReceiverIDs,
// ContentType: utils.Int2Str(ebaiapi.ContentTypeNormal),
// },
// }
//
// data := ""
// if template := GetCustomTemplate(elmAppID, elm.PlatformShopID); len(template) > 0 {
// data = template
// } else {
// data, err = GetDefaultTemplate(elmAppID, elm.PlatformShopID, VendorIDELM)
// if err != nil {
// data = LastTemplate
// }
// }
// dataStr, _ := json.Marshal(data)
// tempContent := ebaiapi.Content{
// Text: string(dataStr),
// }
// tempContentStr, _ := json.Marshal(tempContent)
// param.PayLoad.Content = string(tempContentStr)
//
// if err = partner.CurAPIManager.GetAPI(model.VendorIDEBAI, elmAppID).(*ebaiapi.API).BusinessSendMsg(param); err != nil {
// globals.SugarLogger.Debugf("CheckAndReply mtSend err:%v", err)
// return err
// } else {
// jxMsg = &JXMsg{
// SendType: SendTypeJx,
// MsgContent: param,
// }
// if err = SetMessageDetail(jxMsg, vendorID, elmAppID); err != nil {
// errList.AddErr(fmt.Errorf("自动回复V2存储详细聊天记录错误%v", err))
// }
// }
//
// }
//
// }
//
// if errList.GetErrListAsOne() != nil {
// return fmt.Errorf("CheckAndReplyV2 err=%v", errList.GetErrListAsOne())
// }
//
// return nil
//}
// GetIfReply 检查是否已回复
func GetIfReply(key string) (flag bool) {
func GetIfReply(key string, keyDetail UserRelInfo) (flag bool) {
flag = false
if n, err := rdb.Exists(key); n > 0 && err == nil {
str := rdb.LRange(key)
@@ -698,6 +855,37 @@ func GetIfReply(key string) (flag bool) {
}
}
}
//检测是否商家回复
var param []UserRelInfo
temp := append(param, keyDetail)
if detail, err := GetImChatDetail(temp); err == nil && detail != nil {
tKey := keyDetail.AppID + ":" + keyDetail.VendorStoreID + ":" + keyDetail.VendorID + ":" + keyDetail.UserID
if detail[tKey] != nil {
tDetail := detail[tKey][len(detail[tKey])-1]
//b, _ := json.Marshal(tDetail)
b := tDetail.(string)
lastMsg := &JXMsg{}
//err = json.Unmarshal(b, lastMsg)
err = json.Unmarshal([]byte(b), lastMsg)
if err != nil || lastMsg.SendType == SendTypeJx {
return false
}
switch keyDetail.VendorID {
case VendorIDMTStr:
mt := lastMsg.MsgContent.(map[string]interface{})
if mt["msg_source"].(float64) != mtwmapi.MsgSourceUser {
return false
}
case VendorIDELMStr:
elm := lastMsg.MsgContent.(map[string]interface{})
s := elm["payLoad"].(map[string]interface{})["senderId"].(string)
if s == "" || s[:2] != ebaiapi.SenderTypeUser {
return false
}
}
}
}
return flag
}
@@ -705,7 +893,7 @@ func GetIfReply(key string) (flag bool) {
func RecordAutoStatus(key string, apply *AutoReply) error {
data, _ := json.Marshal(apply)
err := rdb.RPush(key, string(data))
ok, err := rdb.ExpireResult(key, ExpireTimeDay)
ok, err := rdb.ExpireResult(key, ExpireTimeAutoReply)
if err != nil || !ok {
globals.SugarLogger.Debugf("CheckAndReply apply err:%v", err)
return err
@@ -719,12 +907,24 @@ func GenCustomReplyID(appID, vendorStoreID string) string {
}
// GetCustomTemplate 获取自动回复模板
func GetCustomTemplate(appID, vendorStoreID string) (storeTemplate string) {
func GetCustomTemplate(appID, vendorStoreID string) (storeTemplate StoreTemplate) {
var retVal string
key := GenCustomReplyID(appID, vendorStoreID)
temp := rdb.Get(key)
if temp != nil {
storeTemplate = temp.(string)
data := rdb.LRange(key)
if data != nil {
retVal = data[0]
}
//temp := rdb.Get(key)
//temp := regexp.MustCompile(`^"(.*)"$`).ReplaceAllString(retVal, `$1`)
//storeTemplate = strings.Trim(retVal, "/")
//fmt.Println(temp)
temp := StoreTemplate{}
_ = json.Unmarshal([]byte(retVal), &temp)
storeTemplate = temp
return storeTemplate
}
@@ -736,9 +936,15 @@ func AddCustomReply(appID, vendorStoreID, replyTemplate string) (storeTemplate s
key := GenCustomReplyID(appID, vendorStoreID)
template := StoreTemplate{
Template: replyTemplate,
}
data, _ := json.Marshal(template)
err = rdb.Del(key)
if err == nil {
err = rdb.Set(key, replyTemplate, 0)
err = rdb.RPush(key, data)
//err = rdb.Set(key, replyTemplate, 0)
}
return "", err
}

View File

@@ -10,7 +10,9 @@ const (
BaseTemplate = "您好,特殊天气或节假日可能出现骑手变少,配送延迟等情况,烦请耐心等待,售后及其他问题请联系店长,电话:"
LastTemplate = "您好,特殊天气或节假日可能出现骑手变少,配送延迟等情况,烦请耐心等待,售后及其他问题请联系店长" //兜底模板
BasePhoneNum = "18048531223"
BasePhoneNum = "18048531223"
BaseUserListKey = "userList"
BaseMsgDetailKey = "messageDetail"
)
var AutoReplyByAppID = map[int]string{
@@ -60,12 +62,19 @@ type UserRelInfo struct {
UserID string `json:"userID"` //用户id/groupID
}
type StoreTemplate struct {
Template string `json:"template"`
}
var (
rdb = api.Cacher
VendorIDMT = 1 //im美团
VendorIDELM = 3 //im饿了么
VendorIDJX = 3 //im京西
VendorIDMTStr = "1" //im美团
VendorIDELMStr = "3" //im饿了么
SendTypeJx = "jx" //京西客户端发送方标识
SendTypeMt = "mt" //美团用户发送方标识符
SendTypeElm = "elm" //饿了么用户发送方标识符
@@ -75,5 +84,7 @@ var (
)
const (
ExpireTimeDay = 12 * time.Hour //redis过期时间
ExpireTimeDay = 12 * time.Hour //redis过期时间
ExpireTimeAutoReply = 20 * time.Second //redis过期时间
)