|
@@ -7,7 +7,6 @@ import (
|
|
|
"encoding/json"
|
|
"encoding/json"
|
|
|
"encoding/xml"
|
|
"encoding/xml"
|
|
|
"fmt"
|
|
"fmt"
|
|
|
- "github.com/elliotchance/pie/pie"
|
|
|
|
|
"github.com/valyala/fastjson"
|
|
"github.com/valyala/fastjson"
|
|
|
"io/ioutil"
|
|
"io/ioutil"
|
|
|
"net/http"
|
|
"net/http"
|
|
@@ -111,9 +110,8 @@ func KfMsgOrEventHandle(svcCtx *svc.ServiceContext, ct types.EventContent) {
|
|
|
}
|
|
}
|
|
|
_ = svcCtx.CbServiceModel.UpdateCursorByOpenKfid(ct.OpenKfId, cursor)
|
|
_ = svcCtx.CbServiceModel.UpdateCursorByOpenKfid(ct.OpenKfId, cursor)
|
|
|
//保存消息到数据库
|
|
//保存消息到数据库
|
|
|
- var userIds []string
|
|
|
|
|
for _, msg := range list {
|
|
for _, msg := range list {
|
|
|
- userIds = append(userIds, msg.ExternalUserid)
|
|
|
|
|
|
|
+ //保存消息
|
|
|
cbMsg := &model.CbMsg{}
|
|
cbMsg := &model.CbMsg{}
|
|
|
cbMsg.Msgid = msg.Msgid
|
|
cbMsg.Msgid = msg.Msgid
|
|
|
cbMsg.OpenKfid = msg.OpenKfid
|
|
cbMsg.OpenKfid = msg.OpenKfid
|
|
@@ -139,7 +137,6 @@ func KfMsgOrEventHandle(svcCtx *svc.ServiceContext, ct types.EventContent) {
|
|
|
msgTypeEventHandle(svcCtx, cbMsg)
|
|
msgTypeEventHandle(svcCtx, cbMsg)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- go updateCustomerList(svcCtx, userIds)
|
|
|
|
|
if more == 0 {
|
|
if more == 0 {
|
|
|
break
|
|
break
|
|
|
}
|
|
}
|
|
@@ -155,10 +152,13 @@ func KfAccountAuthChangeHandle(svcCtx *svc.ServiceContext, ct types.EventContent
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
for _, s := range list {
|
|
for _, s := range list {
|
|
|
- cbService, err := svcCtx.CbServiceModel.GetServiceByOpenKfid(ct.OpenKfId)
|
|
|
|
|
|
|
+ if s.OpenKfid != ct.OpenKfId {
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+ cbService, err := svcCtx.CbServiceModel.GetServiceByOpenKfid(s.OpenKfid)
|
|
|
//保存客服账号
|
|
//保存客服账号
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- cbService.NextCursor, _ = svcCtx.Redis.Get(fmt.Sprintf("cb_cursor:%v", ct.OpenKfId))
|
|
|
|
|
|
|
+ cbService.NextCursor, _ = svcCtx.Redis.Get(fmt.Sprintf("cb_cursor:%v", s.OpenKfid))
|
|
|
cbService.Corpid = svcCtx.Config.Wxwork.Corpid
|
|
cbService.Corpid = svcCtx.Config.Wxwork.Corpid
|
|
|
cbService.OpenKfid = s.OpenKfid
|
|
cbService.OpenKfid = s.OpenKfid
|
|
|
cbService.Name = s.Name
|
|
cbService.Name = s.Name
|
|
@@ -221,51 +221,50 @@ func KfAccountAuthChangeHandle(svcCtx *svc.ServiceContext, ct types.EventContent
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 更新客户信息
|
|
|
|
|
-func updateCustomerList(svcCtx *svc.ServiceContext, userIds pie.Strings) {
|
|
|
|
|
- for _, uid := range userIds.Unique() {
|
|
|
|
|
- if uid == "" {
|
|
|
|
|
- continue
|
|
|
|
|
- }
|
|
|
|
|
- _, err := svcCtx.CbCustomerModel.GetCustomerByExternalUserid(uid)
|
|
|
|
|
- key := fmt.Sprintf("cb_user_state:%v", uid)
|
|
|
|
|
- v, _ := svcCtx.Redis.Get(key)
|
|
|
|
|
- if v == "4" {
|
|
|
|
|
- continue
|
|
|
|
|
- }
|
|
|
|
|
- if err != nil {
|
|
|
|
|
|
|
+// 消息额外处理
|
|
|
|
|
+func msgTypeTextHandle(svcCtx *svc.ServiceContext, msg *model.CbMsg) {
|
|
|
|
|
+ key := fmt.Sprintf("cb_user_state:%v", msg.ExternalUserid)
|
|
|
|
|
+ v, err := svcCtx.Redis.Get(key)
|
|
|
|
|
+ if err != nil || v == "" {
|
|
|
|
|
+ //新增用户
|
|
|
|
|
+ c, err := svcCtx.CbCustomerModel.GetCustomerByExternalUserid(msg.OpenKfid, msg.ExternalUserid)
|
|
|
|
|
+ if err != nil || c.Id == 0 {
|
|
|
//此处因为该接口查询多个用户时,如果其中一个超过24小时不回复,会导致所有信息都不会返回,因此这里单独请求
|
|
//此处因为该接口查询多个用户时,如果其中一个超过24小时不回复,会导致所有信息都不会返回,因此这里单独请求
|
|
|
- err, list := svcCtx.WxApi.GetCustomerList([]string{uid})
|
|
|
|
|
- if err != nil || len(list) == 0 {
|
|
|
|
|
|
|
+ err, clist := svcCtx.WxApi.GetCustomerList([]string{msg.ExternalUserid})
|
|
|
|
|
+ if err != nil || len(clist) == 0 {
|
|
|
logx.Error("GetCustomerList fail ", err)
|
|
logx.Error("GetCustomerList fail ", err)
|
|
|
- continue
|
|
|
|
|
|
|
+ return
|
|
|
}
|
|
}
|
|
|
- c := &model.CbCustomer{}
|
|
|
|
|
- c.ExternalUserid = list[0].ExternalUserid
|
|
|
|
|
- c.Nickname = list[0].Nickname
|
|
|
|
|
- c.Avatar = list[0].Avatar
|
|
|
|
|
- c.Gender = int64(list[0].Gender)
|
|
|
|
|
- now := time.Now()
|
|
|
|
|
- c.CreatedAt = now
|
|
|
|
|
- c.UpdatedAt = now
|
|
|
|
|
|
|
+ c.ServiceState = -1
|
|
|
|
|
+ c.OpenKfid = msg.OpenKfid
|
|
|
|
|
+ c.ExternalUserid = clist[0].ExternalUserid
|
|
|
|
|
+ c.Nickname = clist[0].Nickname
|
|
|
|
|
+ c.Avatar = clist[0].Avatar
|
|
|
|
|
+ c.Gender = int64(clist[0].Gender)
|
|
|
|
|
+ cnow := time.Now()
|
|
|
|
|
+ c.CreatedAt = cnow
|
|
|
|
|
+ c.UpdatedAt = cnow
|
|
|
_, err = svcCtx.CbCustomerModel.Insert(nil, c)
|
|
_, err = svcCtx.CbCustomerModel.Insert(nil, c)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
logx.Error("Insert cb_customer fail ", err)
|
|
logx.Error("Insert cb_customer fail ", err)
|
|
|
|
|
+ return
|
|
|
|
|
+ } else {
|
|
|
|
|
+ _ = svcCtx.Redis.Set(key, fmt.Sprintf("%v", c.ServiceState))
|
|
|
|
|
+ v = fmt.Sprintf("%v", c.ServiceState)
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-// 消息额外处理
|
|
|
|
|
-func msgTypeTextHandle(svcCtx *svc.ServiceContext, msg *model.CbMsg) {
|
|
|
|
|
- key := fmt.Sprintf("cb_user_state:%v", msg.ExternalUserid)
|
|
|
|
|
- v, _ := svcCtx.Redis.Get(key)
|
|
|
|
|
- if v == "" || v == "4" {
|
|
|
|
|
|
|
+ if v == "-1" || v == "4" {
|
|
|
//获取会话状态
|
|
//获取会话状态
|
|
|
err, sessionState := svcCtx.WxApi.GetSessionState(msg.OpenKfid, msg.ExternalUserid)
|
|
err, sessionState := svcCtx.WxApi.GetSessionState(msg.OpenKfid, msg.ExternalUserid)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
logx.Error("GetSessionState fail ", err)
|
|
logx.Error("GetSessionState fail ", err)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ err = svcCtx.CbCustomerModel.UpdateServiceState(msg.OpenKfid, msg.ExternalUserid, sessionState.ServiceState)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ logx.Error("UpdateServiceState fail ", err)
|
|
|
|
|
+ return
|
|
|
}
|
|
}
|
|
|
_ = svcCtx.Redis.Set(key, fmt.Sprintf("%v", sessionState.ServiceState))
|
|
_ = svcCtx.Redis.Set(key, fmt.Sprintf("%v", sessionState.ServiceState))
|
|
|
v = fmt.Sprintf("%v", sessionState.ServiceState)
|
|
v = fmt.Sprintf("%v", sessionState.ServiceState)
|
|
@@ -280,9 +279,15 @@ func msgTypeTextHandle(svcCtx *svc.ServiceContext, msg *model.CbMsg) {
|
|
|
err, sessionState := svcCtx.WxApi.GetSessionState(msg.OpenKfid, msg.ExternalUserid)
|
|
err, sessionState := svcCtx.WxApi.GetSessionState(msg.OpenKfid, msg.ExternalUserid)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
logx.Error("GetSessionState fail ", err)
|
|
logx.Error("GetSessionState fail ", err)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ err = svcCtx.CbCustomerModel.UpdateServiceState(msg.OpenKfid, msg.ExternalUserid, sessionState.ServiceState)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ logx.Error("UpdateServiceState fail ", err)
|
|
|
|
|
+ return
|
|
|
}
|
|
}
|
|
|
_ = svcCtx.Redis.Set(key, fmt.Sprintf("%v", sessionState.ServiceState))
|
|
_ = svcCtx.Redis.Set(key, fmt.Sprintf("%v", sessionState.ServiceState))
|
|
|
- return
|
|
|
|
|
|
|
+ v = fmt.Sprintf("%v", sessionState.ServiceState)
|
|
|
}
|
|
}
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
@@ -297,14 +302,58 @@ func msgTypeEventHandle(svcCtx *svc.ServiceContext, msg *model.CbMsg) {
|
|
|
switch string(eventType) {
|
|
switch string(eventType) {
|
|
|
case types.EventTypeSessionStatusChange:
|
|
case types.EventTypeSessionStatusChange:
|
|
|
key := fmt.Sprintf("cb_user_state:%v", msg.ExternalUserid)
|
|
key := fmt.Sprintf("cb_user_state:%v", msg.ExternalUserid)
|
|
|
- _, _ = svcCtx.Redis.Del(key)
|
|
|
|
|
//获取会话状态
|
|
//获取会话状态
|
|
|
err, sessionState := svcCtx.WxApi.GetSessionState(msg.OpenKfid, msg.ExternalUserid)
|
|
err, sessionState := svcCtx.WxApi.GetSessionState(msg.OpenKfid, msg.ExternalUserid)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
logx.Error("GetSessionState fail ", err)
|
|
logx.Error("GetSessionState fail ", err)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ err = svcCtx.CbCustomerModel.UpdateServiceState(msg.OpenKfid, msg.ExternalUserid, sessionState.ServiceState)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ logx.Error("UpdateServiceState fail ", err)
|
|
|
|
|
+ return
|
|
|
}
|
|
}
|
|
|
_ = svcCtx.Redis.Set(key, fmt.Sprintf("%v", sessionState.ServiceState))
|
|
_ = svcCtx.Redis.Set(key, fmt.Sprintf("%v", sessionState.ServiceState))
|
|
|
- return
|
|
|
|
|
case types.EventTypeEnterSession:
|
|
case types.EventTypeEnterSession:
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+// 同步状态
|
|
|
|
|
+func InitCustomerState(svcCtx *svc.ServiceContext) {
|
|
|
|
|
+ page := 1
|
|
|
|
|
+ size := 1000
|
|
|
|
|
+ for {
|
|
|
|
|
+ all, _ := svcCtx.CbCustomerModel.GetCustomerByPage(page, size)
|
|
|
|
|
+ if len(all) == 0 {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ for _, customer := range all {
|
|
|
|
|
+ key := fmt.Sprintf("cb_user_state:%v", customer.ExternalUserid)
|
|
|
|
|
+ v, _ := svcCtx.Redis.Get(key)
|
|
|
|
|
+ //状态不一致则同步
|
|
|
|
|
+ if v != fmt.Sprintf("%v", customer.ServiceState) {
|
|
|
|
|
+ //获取会话状态
|
|
|
|
|
+ err, sessionState := svcCtx.WxApi.GetSessionState(customer.OpenKfid, customer.ExternalUserid)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ logx.Error("GetSessionState fail ", err)
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+ if sessionState.ServiceState == 0 {
|
|
|
|
|
+ //进入会话事件,加入消息流转池
|
|
|
|
|
+ err := svcCtx.WxApi.UpdateSessionState(customer.OpenKfid, customer.ExternalUserid, "", 2)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ logx.Error("UpdateSessionState fail ", err)
|
|
|
|
|
+ }
|
|
|
|
|
+ sessionState.ServiceState = 2
|
|
|
|
|
+ }
|
|
|
|
|
+ err = svcCtx.CbCustomerModel.UpdateServiceState(customer.OpenKfid, customer.ExternalUserid, sessionState.ServiceState)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ logx.Error("UpdateServiceState fail ", err)
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+ _ = svcCtx.Redis.Set(key, fmt.Sprintf("%v", sessionState.ServiceState))
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ page++
|
|
|
|
|
+ }
|
|
|
|
|
+}
|