gosdk/qyweixin/app_customer.go

299 lines
7.7 KiB
Go
Raw Normal View History

2024-01-23 11:44:55 +08:00
package qyweixin
2024-01-23 14:48:03 +08:00
import (
"encoding/json"
"fmt"
"github.com/spf13/cast"
"gitlab.batiao8.com/open/gosdk/util"
"gitlab.batiao8.com/open/gosdk/wechat/message"
"time"
)
2024-01-23 22:06:52 +08:00
var (
ChangeTypeFromPool = 1
ChangeTypeTransform = 2
ChangeTypeFinish = 3
ChangeTypeRepeat = 4
OriginCustomer = 3 //用户发送的
OriginSystem = 4 //系统发送的
OriginServicer = 5 //客服发送的
OriginAi = 6 //AI发送的
EventTypeEnterSession = "enter_session"
EventTypeSessionChange = "session_status_change"
CustomerStateEnterSession = 0
CustomerStateRobot = 1
CustomerStateWaitPool = 2
CustomerStateServicing = 3
CustomerStateComplete = 4
)
2024-01-23 14:48:03 +08:00
type CustomerAccount struct {
Name string
KfId string
}
2024-01-23 22:06:52 +08:00
2024-01-23 14:48:03 +08:00
type CustomerMessage struct {
Msgid string
Msgtype string
ExternalUserid string
ServicerUserid string
OpenKfid string
Origin int
SendTime int64
SyncTime int64
2024-01-23 22:06:52 +08:00
Text *CustomerText
Event *CustomerEvent
Image *CustomerImage
2024-01-23 14:48:03 +08:00
}
2024-01-23 22:06:52 +08:00
2024-01-23 21:35:31 +08:00
type CustomerServicer struct {
Userid string
Status int
}
2024-01-23 22:06:52 +08:00
2024-01-23 21:31:39 +08:00
type CustomerState struct {
State int
Servicer string
}
2024-01-23 14:48:03 +08:00
2024-01-23 22:06:52 +08:00
type CustomerText struct {
Content string
MenuId string
}
type CustomerImage struct {
MediaId string
}
type CustomerEvent struct {
EventType string `json:"event_type"`
Scene string `json:"scene"`
ChangeType int `json:"change_type"`
OldServicerUserid string `json:"old_servicer_userid"`
NewServicerUserid string `json:"new_servicer_userid"`
}
2024-01-23 11:44:55 +08:00
type AppCustomer struct {
App
}
func NewAppCustomer(cfg *AppConfig) *AppCustomer {
return &AppCustomer{
App: *NewApp(cfg),
}
}
2024-01-23 14:48:03 +08:00
func (a *AppCustomer) AccountList() ([]*CustomerAccount, error) {
reqUrl := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/kf/account/list?access_token=%s", a.GetToken())
rspBody, err := util.HttpGet(reqUrl, nil)
if err != nil {
return nil, err
}
result, err := a.GetResult(rspBody)
if err != nil {
return nil, err
}
data := cast.ToSlice(result["account_list"])
accounts := make([]*CustomerAccount, 0)
for _, ac := range data {
acc := cast.ToStringMap(ac)
account := new(CustomerAccount)
account.Name = cast.ToString(acc["name"])
account.KfId = cast.ToString(acc["open_kfid"])
accounts = append(accounts, account)
}
return accounts, nil
}
2024-01-23 21:35:31 +08:00
func (a *AppCustomer) ServicerList(openKfid string) ([]*CustomerServicer, error) {
reqUrl := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/kf/service_state/trans?access_token=%s&open_kfid=%s", a.GetToken(), openKfid)
rspBody, err := util.HttpGet(reqUrl, nil)
if err != nil {
return nil, err
}
result, err := a.GetResult(rspBody)
if err != nil {
return nil, err
}
resultList := make([]*CustomerServicer, 0)
servicerList := cast.ToSlice(result["servicer_list"])
for _, s := range servicerList {
serv := cast.ToStringMap(s)
r := new(CustomerServicer)
r.Userid = cast.ToString(serv["userid"])
r.Status = cast.ToInt(serv["status"])
resultList = append(resultList, r)
}
return resultList, nil
}
2024-01-23 21:31:39 +08:00
func (a *AppCustomer) SetCustomerState(openKfid, externalUserid string, state *CustomerState) error {
reqUrl := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/kf/service_state/trans?access_token=%s", a.GetToken())
params := make(map[string]interface{})
params["external_userid"] = externalUserid
params["open_kfid"] = openKfid
params["service_state"] = state.State
params["servicer_userid"] = state.Servicer
reqBody, _ := json.Marshal(params)
rspBody, err := util.HttpPostJson(reqUrl, nil, reqBody)
if err != nil {
return err
}
_, err = a.GetResult(rspBody)
if err != nil {
return err
}
return nil
}
func (a *AppCustomer) GetCustomerState(openKfid, externalUserid string) (*CustomerState, error) {
reqUrl := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/kf/service_state/get?access_token=%s", a.GetToken())
params := make(map[string]interface{})
params["external_userid"] = externalUserid
params["open_kfid"] = openKfid
reqBody, _ := json.Marshal(params)
rspBody, err := util.HttpPostJson(reqUrl, nil, reqBody)
if err != nil {
return nil, err
}
result, err := a.GetResult(rspBody)
if err != nil {
return nil, err
}
state := new(CustomerState)
state.State = cast.ToInt(result["service_state"])
state.Servicer = cast.ToString(result["servicer_userid"])
return state, nil
}
2024-01-23 18:28:28 +08:00
func (a *AppCustomer) SendCustomerText(toUser, openKfId, content string) error {
reqUrl := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/kf/send_msg?access_token=%s", a.GetToken())
params := make(map[string]interface{})
params["touser"] = toUser
params["open_kfid"] = openKfId
2024-01-23 19:35:41 +08:00
params["msgtype"] = "text"
2024-01-23 18:28:28 +08:00
params["text"] = map[string]interface{}{
"content": content,
}
reqBody, _ := json.Marshal(params)
rspBody, err := util.HttpPostJson(reqUrl, nil, reqBody)
if err != nil {
return err
}
_, err = a.GetResult(rspBody)
if err != nil {
return err
}
return nil
}
2024-01-23 14:48:03 +08:00
func (a *AppCustomer) SyncMessage(cursor, token, openKfId string) ([]*CustomerMessage, string, error) {
reqUrl := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/kf/sync_msg?access_token=%s", a.GetToken())
params := make(map[string]interface{})
params["token"] = token
params["limit"] = 1000
params["voice_format"] = 0
params["open_kfid"] = openKfId
message := make([]*CustomerMessage, 0)
for {
params["cursor"] = cursor
reqBody, _ := json.Marshal(params)
rspBody, err := util.HttpPostJson(reqUrl, nil, reqBody)
if err != nil {
return nil, "", err
}
result, err := a.GetResult(rspBody)
if err != nil {
return nil, "", err
}
msgList := cast.ToSlice(result["msg_list"])
for _, msg := range msgList {
m := new(CustomerMessage)
m.From(cast.ToStringMap(msg))
message = append(message, m)
}
cursor = cast.ToString(result["next_cursor"])
hasMore := cast.ToInt(result["has_more"])
if hasMore == 0 {
break
}
}
return message, cursor, nil
}
func (m *CustomerMessage) From(data map[string]interface{}) {
m.SyncTime = time.Now().Unix()
m.SendTime = cast.ToInt64(data["send_time"])
m.Msgid = cast.ToString(data["msgid"])
m.Msgtype = cast.ToString(data["msgtype"])
m.Origin = cast.ToInt(data["origin"])
m.ExternalUserid = cast.ToString(data["external_userid"])
m.ServicerUserid = cast.ToString(data["servicer_userid"])
m.OpenKfid = cast.ToString(data["open_kfid"])
if m.Msgtype == message.MsgTypeEvent {
m.parseEvent(data)
2024-01-23 22:06:52 +08:00
} else if m.Msgtype == string(message.MsgTypeText) {
m.parseText(data)
} else if m.Msgtype == message.MsgTypeImage {
m.parseText(data)
2024-01-23 14:48:03 +08:00
}
}
func (m *CustomerMessage) parseEvent(data map[string]interface{}) error {
event, err := cast.ToStringMapE(data["event"])
if err != nil {
return err
}
externalUserid := cast.ToString(event["external_userid"])
if externalUserid != "" {
m.ExternalUserid = externalUserid
}
openKfid := cast.ToString(event["open_kfid"])
if openKfid != "" {
m.OpenKfid = openKfid
}
2024-01-23 22:06:52 +08:00
m.Event = &CustomerEvent{
EventType: cast.ToString(event["event_type"]),
Scene: cast.ToString(event["scene"]),
ChangeType: cast.ToInt(event["change_type"]),
NewServicerUserid: cast.ToString(event["new_servicer_userid"]),
OldServicerUserid: cast.ToString(event["old_servicer_userid"]),
}
return nil
}
func (m *CustomerMessage) parseText(data map[string]interface{}) error {
image, err := cast.ToStringMapE(data["text"])
if err != nil {
return err
}
m.Text = &CustomerText{
Content: cast.ToString(image["content"]),
MenuId: cast.ToString(image["menu_id"]),
}
2024-01-23 14:48:03 +08:00
return nil
}
2024-01-23 22:06:52 +08:00
func (m *CustomerMessage) parseImage(data map[string]interface{}) error {
image, err := cast.ToStringMapE(data["image"])
2024-01-23 14:48:03 +08:00
if err != nil {
return err
}
2024-01-23 22:06:52 +08:00
m.Image = &CustomerImage{
MediaId: cast.ToString(image["media_id"]),
}
2024-01-23 14:48:03 +08:00
return nil
}