v2
This commit is contained in:
1
business/jxutils/cache/cache.go
vendored
1
business/jxutils/cache/cache.go
vendored
@@ -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)
|
||||
|
||||
13
business/jxutils/cache/redis/redis.go
vendored
13
business/jxutils/cache/redis/redis.go
vendored
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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过期时间
|
||||
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user