mirror of
https://github.com/silenceper/wechat.git
synced 2026-02-04 12:52:27 +08:00
* 企业微信微信客服字段同步 * fix ci lint * fix open_kfid xml Unmarshal error and 'syncMsg: field `open_kfid` unexpected empty string. invalid Request Parameter' * add struct CallbackMessage xml tag --------- Co-authored-by: liuyuezhong <liuyuezhong@inke.cn>
100 lines
3.4 KiB
Go
100 lines
3.4 KiB
Go
package kf
|
||
|
||
import (
|
||
"encoding/xml"
|
||
|
||
"github.com/silenceper/wechat/v2/util"
|
||
)
|
||
|
||
// SignatureOptions 微信服务器验证参数
|
||
type SignatureOptions struct {
|
||
Signature string `form:"msg_signature"`
|
||
TimeStamp string `form:"timestamp"`
|
||
Nonce string `form:"nonce"`
|
||
EchoStr string `form:"echostr"`
|
||
}
|
||
|
||
// VerifyURL 验证请求参数是否合法并返回解密后的消息内容
|
||
//
|
||
// //Gin框架的使用示例
|
||
// r.GET("/v1/event/callback", func(c *gin.Context) {
|
||
// options := kf.SignatureOptions{}
|
||
// //获取回调的的校验参数
|
||
// if = c.ShouldBindQuery(&options); err != nil {
|
||
// c.String(http.StatusUnauthorized, "参数解析失败")
|
||
// }
|
||
// // 调用VerifyURL方法校验当前请求,如果合法则把解密后的内容作为响应返回给微信服务器
|
||
// echo, err := kfClient.VerifyURL(options)
|
||
// if err == nil {
|
||
// c.String(http.StatusOK, echo)
|
||
// } else {
|
||
// c.String(http.StatusUnauthorized, "非法请求来源")
|
||
// }
|
||
// })
|
||
func (r *Client) VerifyURL(options SignatureOptions) (string, error) {
|
||
if options.Signature != util.Signature(r.ctx.Token, options.TimeStamp, options.Nonce, options.EchoStr) {
|
||
return "", NewSDKErr(40015)
|
||
}
|
||
_, bData, err := util.DecryptMsg(r.corpID, options.EchoStr, r.encodingAESKey)
|
||
if err != nil {
|
||
return "", NewSDKErr(40016)
|
||
}
|
||
|
||
return string(bData), nil
|
||
}
|
||
|
||
// 原始回调消息内容
|
||
type callbackOriginMessage struct {
|
||
ToUserName string // 企业微信的CorpID,当为第三方套件回调事件时,CorpID的内容为suiteid
|
||
AgentID string // 接收的应用id,可在应用的设置页面获取
|
||
Encrypt string // 消息结构体加密后的字符串
|
||
}
|
||
|
||
// CallbackMessage 微信客服回调消息
|
||
type CallbackMessage struct {
|
||
ToUserName string `json:"to_user_name" xml:"ToUserName"` // 微信客服组件ID
|
||
CreateTime int `json:"create_time" xml:"CreateTime"` // 消息创建时间,unix时间戳
|
||
MsgType string `json:"msgtype" xml:"MsgType"` // 消息的类型,此时固定为 event
|
||
Event string `json:"event" xml:"Event"` // 事件的类型,此时固定为 kf_msg_or_event
|
||
Token string `json:"token" xml:"Token"` // 调用拉取消息接口时,需要传此token,用于校验请求的合法性
|
||
OpenKfID string `json:"open_kfid" xml:"OpenKfId"` // 有新消息的客服帐号。可通过sync_msg接口指定open_kfid获取此客服帐号的消息
|
||
}
|
||
|
||
// GetCallbackMessage 获取回调事件中的消息内容
|
||
//
|
||
// //Gin框架的使用示例
|
||
// r.POST("/v1/event/callback", func(c *gin.Context) {
|
||
// var (
|
||
// message kf.CallbackMessage
|
||
// body []byte
|
||
// )
|
||
// // 读取原始消息内容
|
||
// body, err = c.GetRawData()
|
||
// if err != nil {
|
||
// c.String(http.StatusInternalServerError, err.Error())
|
||
// return
|
||
// }
|
||
// // 解析原始数据
|
||
// message, err = kfClient.GetCallbackMessage(body)
|
||
// if err != nil {
|
||
// c.String(http.StatusInternalServerError, "消息获取失败")
|
||
// return
|
||
// }
|
||
// fmt.Println(message)
|
||
// c.String(200, "ok")
|
||
// })
|
||
func (r *Client) GetCallbackMessage(encryptedMsg []byte) (msg CallbackMessage, err error) {
|
||
var origin callbackOriginMessage
|
||
if err = xml.Unmarshal(encryptedMsg, &origin); err != nil {
|
||
return msg, err
|
||
}
|
||
_, bData, err := util.DecryptMsg(r.corpID, origin.Encrypt, r.encodingAESKey)
|
||
if err != nil {
|
||
return msg, NewSDKErr(40016)
|
||
}
|
||
if err = xml.Unmarshal(bData, &msg); err != nil {
|
||
return msg, err
|
||
}
|
||
return msg, err
|
||
}
|