1
0
mirror of https://github.com/silenceper/wechat.git synced 2026-02-04 21:02:25 +08:00
Files
wechat/work/kf/syncmsg.go

109 lines
4.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package kf
import (
"encoding/json"
"errors"
"fmt"
"github.com/silenceper/wechat/v2/util"
"github.com/silenceper/wechat/v2/work/kf/syncmsg"
)
const (
// 获取消息
syncMsgAddr = "https://qyapi.weixin.qq.com/cgi-bin/kf/sync_msg?access_token=%s"
)
// SyncMsgOptions 获取消息查询参数
type SyncMsgOptions struct {
Cursor string `json:"cursor"` // 上一次调用时返回的 next_cursor第一次拉取可以不填不多于 64 字节
Token string `json:"token"` // 回调事件返回的 token 字段10 分钟内有效;可不填,如果不填接口有严格的频率限制,不多于 128 字节
Limit uint `json:"limit"` // 期望请求的数据量,默认值和最大值都为 1000, 注意:可能会出现返回条数少于 limit 的情况,需结合返回的 has_more 字段判断是否继续请求。
VoiceFormat uint `json:"voice_format,omitempty"` // 语音消息类型0-Amr 1-Silk默认 0。可通过该参数控制返回的语音格式开发者可按需选择自己程序支持的一种格式
OpenKfID string `json:"open_kfid,omitempty"` // 指定拉取某个客服帐号的消息,否则默认返回有权限的客服帐号的消息。当客服帐号较多,建议按 open_kfid 来拉取以获取更好的性能。
}
// SyncMsgSchema 获取消息查询响应内容
type syncMsgSchema struct {
ErrCode int32 `json:"errcode"` // 返回码
ErrMsg string `json:"errmsg"` // 错误码描述
NextCursor string `json:"next_cursor"` // 下次调用带上该值,则从当前的位置继续往后拉,以实现增量拉取。强烈建议对改该字段入库保存,每次请求读取带上,请求结束后更新。避免因意外丢,导致必须从头开始拉取,引起消息延迟。
HasMore uint32 `json:"has_more"` // 是否还有更多数据。0-否1-是。不能通过判断 msg_list 是否空来停止拉取,可能会出现 has_more 为 1而 msg_list 为空的情况
MsgList []map[string]interface{} `json:"msg_list"` // 消息列表
}
// SyncMsgSchema 获取消息查询响应内容
type SyncMsgSchema struct {
ErrCode int32 `json:"errcode"` // 返回码
ErrMsg string `json:"errmsg"` // 错误码描述
NextCursor string `json:"next_cursor"` // 下次调用带上该值则从该 key 值往后拉,用于增量拉取
HasMore uint32 `json:"has_more"` // 是否还有更多数据。0-否1-是。不能通过判断 msg_list 是否空来停止拉取,可能会出现 has_more 为 1而 msg_list 为空的情况
MsgList []syncmsg.Message `json:"msg_list"` // 消息列表
}
// SyncMsg 获取消息
func (r *Client) SyncMsg(options SyncMsgOptions) (info SyncMsgSchema, err error) {
var (
accessToken string
data []byte
)
if accessToken, err = r.ctx.GetAccessToken(); err != nil {
return
}
if data, err = util.PostJSON(fmt.Sprintf(syncMsgAddr, accessToken), options); err != nil {
return
}
originInfo := syncMsgSchema{}
if err = json.Unmarshal(data, &originInfo); err != nil {
return
}
if originInfo.ErrCode != 0 {
return info, errors.New(originInfo.ErrMsg)
}
msgList := make([]syncmsg.Message, 0)
if len(originInfo.MsgList) > 0 {
for _, msg := range originInfo.MsgList {
newMsg := syncmsg.Message{}
if val, ok := msg["msgid"].(string); ok {
newMsg.MsgID = val
}
if val, ok := msg["open_kfid"].(string); ok {
newMsg.OpenKFID = val
}
if val, ok := msg["external_userid"].(string); ok {
newMsg.ExternalUserID = val
}
if val, ok := msg["send_time"].(float64); ok {
newMsg.SendTime = uint64(val)
}
if val, ok := msg["origin"].(float64); ok {
newMsg.Origin = uint32(val)
}
if val, ok := msg["msgtype"].(string); ok {
newMsg.MsgType = val
}
if newMsg.MsgType == "event" {
if event, ok := msg["event"].(map[string]interface{}); ok {
if eType, ok := event["event_type"].(string); ok {
newMsg.EventType = eType
}
}
}
originData, err := json.Marshal(msg)
if err != nil {
return info, err
}
newMsg.OriginData = originData
msgList = append(msgList, newMsg)
}
}
return SyncMsgSchema{
ErrCode: originInfo.ErrCode,
ErrMsg: originInfo.ErrMsg,
NextCursor: originInfo.NextCursor,
HasMore: originInfo.HasMore,
MsgList: msgList,
}, nil
}