mirror of
https://github.com/silenceper/wechat.git
synced 2026-02-04 12:52:27 +08:00
微信小程序回调消息兼容json格式 (#560)
This commit is contained in:
1
go.mod
1
go.mod
@@ -9,6 +9,7 @@ require (
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/spf13/cast v1.4.1
|
||||
github.com/stretchr/testify v1.7.1
|
||||
github.com/tidwall/gjson v1.14.1
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4
|
||||
gopkg.in/h2non/gock.v1 v1.1.2
|
||||
)
|
||||
|
||||
6
go.sum
6
go.sum
@@ -66,6 +66,12 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tidwall/gjson v1.14.1 h1:iymTbGkQBhveq21bEvAQ81I0LEBork8BFe1CUZXdyuo=
|
||||
github.com/tidwall/gjson v1.14.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
|
||||
@@ -117,7 +117,7 @@ type MixMessage struct {
|
||||
URL string `xml:"Url"`
|
||||
|
||||
// 事件相关
|
||||
Event EventType `xml:"Event"`
|
||||
Event EventType `xml:"Event" json:"Event"`
|
||||
EventKey string `xml:"EventKey"`
|
||||
Ticket string `xml:"Ticket"`
|
||||
Latitude string `xml:"Latitude"`
|
||||
@@ -149,6 +149,8 @@ type MixMessage struct {
|
||||
Poiname string `xml:"Poiname"`
|
||||
}
|
||||
|
||||
subscribeMsgPopupEventList []SubscribeMsgPopupEvent `json:"-"`
|
||||
|
||||
SubscribeMsgPopupEvent []struct {
|
||||
List SubscribeMsgPopupEvent `xml:"List"`
|
||||
} `xml:"SubscribeMsgPopupEvent"`
|
||||
@@ -209,9 +211,26 @@ type MixMessage struct {
|
||||
|
||||
// SubscribeMsgPopupEvent 订阅通知事件推送的消息体
|
||||
type SubscribeMsgPopupEvent struct {
|
||||
TemplateID string `xml:"TemplateId"`
|
||||
SubscribeStatusString string `xml:"SubscribeStatusString"`
|
||||
PopupScene int `xml:"PopupScene"`
|
||||
TemplateID string `xml:"TemplateId" json:"TemplateId"`
|
||||
SubscribeStatusString string `xml:"SubscribeStatusString" json:"SubscribeStatusString"`
|
||||
PopupScene int `xml:"PopupScene" json:"PopupScene,string"`
|
||||
}
|
||||
|
||||
// SetSubscribeMsgPopupEvents 设置订阅消息事件
|
||||
func (s *MixMessage) SetSubscribeMsgPopupEvents(list []SubscribeMsgPopupEvent) {
|
||||
s.subscribeMsgPopupEventList = list
|
||||
}
|
||||
|
||||
// GetSubscribeMsgPopupEvents 获取订阅消息事件数据
|
||||
func (s *MixMessage) GetSubscribeMsgPopupEvents() []SubscribeMsgPopupEvent {
|
||||
if s.subscribeMsgPopupEventList != nil {
|
||||
return s.subscribeMsgPopupEventList
|
||||
}
|
||||
list := make([]SubscribeMsgPopupEvent, len(s.SubscribeMsgPopupEvent))
|
||||
for i, item := range s.SubscribeMsgPopupEvent {
|
||||
list[i] = item.List
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
// EventPic 发图事件推送
|
||||
@@ -248,10 +267,10 @@ func (c CDATA) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
// CommonToken 消息中通用的结构
|
||||
type CommonToken struct {
|
||||
XMLName xml.Name `xml:"xml"`
|
||||
ToUserName CDATA `xml:"ToUserName"`
|
||||
FromUserName CDATA `xml:"FromUserName"`
|
||||
CreateTime int64 `xml:"CreateTime"`
|
||||
MsgType MsgType `xml:"MsgType"`
|
||||
ToUserName CDATA `xml:"ToUserName" json:"ToUserName"`
|
||||
FromUserName CDATA `xml:"FromUserName" json:"FromUserName"`
|
||||
CreateTime int64 `xml:"CreateTime" json:"CreateTime"`
|
||||
MsgType MsgType `xml:"MsgType" json:"MsgType"`
|
||||
}
|
||||
|
||||
// SetToUserName set ToUserName
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -9,13 +10,14 @@ import (
|
||||
"reflect"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/silenceper/wechat/v2/officialaccount/context"
|
||||
"github.com/silenceper/wechat/v2/officialaccount/message"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
// Server struct
|
||||
@@ -36,6 +38,7 @@ type Server struct {
|
||||
ResponseMsg interface{}
|
||||
|
||||
isSafeMode bool
|
||||
isJSONContent bool
|
||||
random []byte
|
||||
nonce string
|
||||
timestamp int64
|
||||
@@ -98,6 +101,10 @@ func (srv *Server) handleRequest() (reply *message.Reply, err error) {
|
||||
srv.isSafeMode = true
|
||||
}
|
||||
|
||||
//set request contentType
|
||||
contentType := srv.Request.Header.Get("Content-Type")
|
||||
srv.isJSONContent = strings.Contains(contentType, "application/json")
|
||||
|
||||
// set openID
|
||||
srv.openID = srv.Query("openid")
|
||||
|
||||
@@ -125,9 +132,9 @@ func (srv *Server) getMessage() (interface{}, error) {
|
||||
var rawXMLMsgBytes []byte
|
||||
var err error
|
||||
if srv.isSafeMode {
|
||||
var encryptedXMLMsg message.EncryptedXMLMsg
|
||||
if err := xml.NewDecoder(srv.Request.Body).Decode(&encryptedXMLMsg); err != nil {
|
||||
return nil, fmt.Errorf("从body中解析xml失败,err=%v", err)
|
||||
encryptedXMLMsg, dataErr := srv.getEncryptBody()
|
||||
if dataErr != nil {
|
||||
return nil, dataErr
|
||||
}
|
||||
|
||||
// 验证消息签名
|
||||
@@ -161,10 +168,49 @@ func (srv *Server) getMessage() (interface{}, error) {
|
||||
return srv.parseRequestMessage(rawXMLMsgBytes)
|
||||
}
|
||||
|
||||
func (srv *Server) getEncryptBody() (*message.EncryptedXMLMsg, error) {
|
||||
var encryptedXMLMsg = &message.EncryptedXMLMsg{}
|
||||
if srv.isJSONContent {
|
||||
if err := json.NewDecoder(srv.Request.Body).Decode(encryptedXMLMsg); err != nil {
|
||||
return nil, fmt.Errorf("从body中解析json失败,err=%v", err)
|
||||
}
|
||||
} else {
|
||||
if err := xml.NewDecoder(srv.Request.Body).Decode(encryptedXMLMsg); err != nil {
|
||||
return nil, fmt.Errorf("从body中解析xml失败,err=%v", err)
|
||||
}
|
||||
}
|
||||
return encryptedXMLMsg, nil
|
||||
}
|
||||
|
||||
func (srv *Server) parseRequestMessage(rawXMLMsgBytes []byte) (msg *message.MixMessage, err error) {
|
||||
msg = &message.MixMessage{}
|
||||
if !srv.isJSONContent {
|
||||
err = xml.Unmarshal(rawXMLMsgBytes, msg)
|
||||
return
|
||||
}
|
||||
//parse json
|
||||
err = json.Unmarshal(rawXMLMsgBytes, msg)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// nonstandard json, 目前小程序订阅消息返回数据格式不标准,订阅消息模板单个List返回是对象,多个List返回是数组。
|
||||
if msg.MsgType == message.MsgTypeEvent {
|
||||
listData := gjson.Get(string(rawXMLMsgBytes), "List")
|
||||
if listData.IsObject() {
|
||||
listItem := message.SubscribeMsgPopupEvent{}
|
||||
if parseErr := json.Unmarshal([]byte(listData.Raw), &listItem); parseErr != nil {
|
||||
return msg, parseErr
|
||||
}
|
||||
msg.SetSubscribeMsgPopupEvents([]message.SubscribeMsgPopupEvent{listItem})
|
||||
} else if listData.IsArray() {
|
||||
listItems := make([]message.SubscribeMsgPopupEvent, 0)
|
||||
if parseErr := json.Unmarshal([]byte(listData.Raw), &listItems); parseErr != nil {
|
||||
return msg, parseErr
|
||||
}
|
||||
msg.SetSubscribeMsgPopupEvents(listItems)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SetMessageHandler 设置用户自定义的回调方法
|
||||
|
||||
Reference in New Issue
Block a user