forked from chanxuehong/wechat
/
msg_handler.go
118 lines (95 loc) · 4.13 KB
/
msg_handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// @description wechat 是腾讯微信公众平台 api 的 golang 语言封装
// @link https://github.com/chanxuehong/wechat for the canonical source repository
// @license https://github.com/chanxuehong/wechat/blob/master/LICENSE
// @authors chanxuehong(chanxuehong@gmail.com)
package corp
import (
"io"
"net/http"
"net/url"
)
// 微信服务器推送过来的消息(事件)处理接口
type MessageHandler interface {
ServeMessage(w http.ResponseWriter, r *Request)
}
type MessageHandlerFunc func(http.ResponseWriter, *Request)
func (fn MessageHandlerFunc) ServeMessage(w http.ResponseWriter, r *Request) {
fn(w, r)
}
type httpResponseWriter struct {
io.Writer
}
func (httpResponseWriter) Header() http.Header {
return make(map[string][]string)
}
func (httpResponseWriter) WriteHeader(int) {}
// 将 io.Writer 从语义上实现 http.ResponseWriter.
// 某些 http 框架可能没有提供 http.ResponseWriter, 而只是提供了 io.Writer.
func HttpResponseWriter(w io.Writer) http.ResponseWriter {
if rw, ok := w.(http.ResponseWriter); ok {
return rw
}
return httpResponseWriter{Writer: w}
}
// 消息(事件)请求信息
type Request struct {
HttpRequest *http.Request // 可以为 nil, 因为某些 http 框架没有提供此参数
// 下面的字段必须提供
QueryValues url.Values // 回调请求 URL 中的查询参数集合
MsgSignature string // 回调请求 URL 中的消息体签名: msg_signature
TimeStamp int64 // 回调请求 URL 中的时间戳: timestamp
Nonce string // 回调请求 URL 中的随机数: nonce
RawMsgXML []byte // 消息的"明文"XML 文本
MixedMsg *MixedMessage // RawMsgXML 解析后的消息
AESKey [32]byte // 当前消息 AES 加密的 key
Random []byte // 当前消息加密时所用的 random, 16 bytes
// 下面字段是企业号应用的基本信息
CorpId string // 请求消息所属企业号的 ID
AgentId int64 // 请求消息所属企业号应用的 ID
AgentToken string // 请求消息所属企业号应用的 Token
}
// 微信服务器推送过来的消息(事件)通用的消息头
type CommonMessageHeader struct {
ToUserName string `xml:"ToUserName" json:"ToUserName"`
FromUserName string `xml:"FromUserName" json:"FromUserName"`
CreateTime int64 `xml:"CreateTime" json:"CreateTime"`
MsgType string `xml:"MsgType" json:"MsgType"`
AgentId int64 `xml:"AgentID" json:"AgentID"`
}
// 微信服务器推送过来的消息(事件)的合集.
type MixedMessage struct {
XMLName struct{} `xml:"xml" json:"-"`
CommonMessageHeader
MsgId int64 `xml:"MsgId" json:"MsgId"`
Content string `xml:"Content" json:"Content"`
MediaId string `xml:"MediaId" json:"MediaId"`
PicURL string `xml:"PicUrl" json:"PicUrl"`
Format string `xml:"Format" json:"Format"`
ThumbMediaId string `xml:"ThumbMediaId" json:"ThumbMediaId"`
LocationX float64 `xml:"Location_X" json:"Location_X"`
LocationY float64 `xml:"Location_Y" json:"Location_Y"`
Scale int `xml:"Scale" json:"Scale"`
Label string `xml:"Label" json:"Label"`
Event string `xml:"Event" json:"Event"`
EventKey string `xml:"EventKey" json:"EventKey"`
ScanCodeInfo struct {
ScanType string `xml:"ScanType" json:"ScanType"`
ScanResult string `xml:"ScanResult" json:"ScanResult"`
} `xml:"ScanCodeInfo" json:"ScanCodeInfo"`
SendPicsInfo struct {
Count int `xml:"Count" json:"Count"`
PicList []struct {
PicMD5Sum string `xml:"PicMd5Sum" json:"PicMd5Sum"`
} `xml:"PicList>item,omitempty" json:"PicList,omitempty"`
} `xml:"SendPicsInfo" json:"SendPicsInfo"`
SendLocationInfo struct {
LocationX float64 `xml:"Location_X" json:"Location_X"`
LocationY float64 `xml:"Location_Y" json:"Location_Y"`
Scale int `xml:"Scale" json:"Scale"`
Label string `xml:"Label" json:"Label"`
Poiname string `xml:"Poiname" json:"Poiname"`
} `xml:"SendLocationInfo" json:"SendLocationInfo"`
Latitude float64 `xml:"Latitude" json:"Latitude"`
Longitude float64 `xml:"Longitude" json:"Longitude"`
Precision float64 `xml:"Precision" json:"Precision"`
}