@@ -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 , ExpireTimeDa y )
ok , err := rdb . ExpireResult ( key , ExpireTimeAutoRepl y )
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
}