Documentation ¶
Overview ¶
微信企业号SDK
Index ¶
- Constants
- Variables
- func ServeHTTP(w http.ResponseWriter, r *http.Request, queryValues url.Values, ...)
- func SetLogInfoln(fn func(v ...interface{}))
- func WriteResponse(w http.ResponseWriter, r *Request, msg interface{}) (err error)
- type AccessTokenServer
- type AgentServer
- type AgentServerFrontend
- type Client
- func (clt *Client) GetCallbackIP() (ipList []string, err error)
- func (clt *Client) GetJSON(incompleteURL string, response interface{}) (err error)
- func (clt *Client) PostJSON(incompleteURL string, request interface{}, response interface{}) (err error)
- func (clt *Client) PostMultipartForm(incompleteURL string, fields []MultipartFormField, response interface{}) (err error)
- type DefaultAccessTokenServer
- type DefaultAgentServer
- func (srv *DefaultAgentServer) AgentId() int64
- func (srv *DefaultAgentServer) CorpId() string
- func (srv *DefaultAgentServer) CurrentAESKey() (key [32]byte)
- func (srv *DefaultAgentServer) LastAESKey() (key [32]byte, valid bool)
- func (srv *DefaultAgentServer) MessageHandler() MessageHandler
- func (srv *DefaultAgentServer) Token() string
- func (srv *DefaultAgentServer) UpdateAESKey(aesKey []byte) (err error)
- type Error
- type ErrorHandler
- type ErrorHandlerFunc
- type Interceptor
- type InterceptorFunc
- type MessageHandler
- type MessageHandlerFunc
- type MessageHeader
- type MessageServeMux
- func (mux *MessageServeMux) DefaultEventHandle(handler MessageHandler)
- func (mux *MessageServeMux) DefaultEventHandleFunc(handler func(http.ResponseWriter, *Request))
- func (mux *MessageServeMux) DefaultMessageHandle(handler MessageHandler)
- func (mux *MessageServeMux) DefaultMessageHandleFunc(handler func(http.ResponseWriter, *Request))
- func (mux *MessageServeMux) EventHandle(eventType string, handler MessageHandler)
- func (mux *MessageServeMux) EventHandleFunc(eventType string, handler func(http.ResponseWriter, *Request))
- func (mux *MessageServeMux) MessageHandle(msgType string, handler MessageHandler)
- func (mux *MessageServeMux) MessageHandleFunc(msgType string, handler func(http.ResponseWriter, *Request))
- func (mux *MessageServeMux) ServeMessage(w http.ResponseWriter, r *Request)
- type MixedMessage
- type MultiAgentServerFrontend
- func (frontend *MultiAgentServerFrontend) DeleteAgentServer(serverKey string)
- func (frontend *MultiAgentServerFrontend) DeleteAllAgentServer()
- func (frontend *MultiAgentServerFrontend) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (frontend *MultiAgentServerFrontend) SetAgentServer(serverKey string, server AgentServer) (err error)
- type MultipartFormField
- type Request
- type RequestHttpBody
- type ResponseHttpBody
Constants ¶
const ( ErrCodeOK = 0 ErrCodeAccessTokenExpired = 42001 // access_token 过期(无效)返回这个错误 ErrCodeSuiteAccessTokenExpired = 42009 // suite_access_token 过期(无效)返回这个错误 )
Variables ¶
var DefaultErrorHandler = ErrorHandlerFunc(func(w http.ResponseWriter, r *http.Request, err error) {})
var LogInfoln = log.Println
var MediaHttpClient = &http.Client{ Timeout: 300 * time.Second, }
多媒体上传下载请求的 http.Client
var TextHttpClient = &http.Client{ Timeout: 60 * time.Second, }
一般请求的 http.Client
Functions ¶
func ServeHTTP ¶
func ServeHTTP(w http.ResponseWriter, r *http.Request, queryValues url.Values, srv AgentServer, errHandler ErrorHandler)
ServeHTTP 处理 http 消息请求
NOTE: 调用者保证所有参数有效
func WriteResponse ¶
func WriteResponse(w http.ResponseWriter, r *Request, msg interface{}) (err error)
回复消息给微信服务器.
要求 msg 是有效的消息数据结构(经过 encoding/xml marshal 后符合消息的格式); 如果有必要可以修改 Request 里面的某些值, 比如 Timestamp.
Types ¶
type AccessTokenServer ¶
type AccessTokenServer interface { // 从中控服务器获取被缓存的 access_token. Token() (string, error) // 请求中控服务器到微信服务器刷新 access_token. // // 高并发场景下某个时间点可能有很多请求(比如缓存的 access_token 刚好过期时), 但是我们 // 不期望也没有必要让这些请求都去微信服务器获取 access_token(有可能导致api超过调用限制), // 实际上这些请求只需要一个新的 access_token 即可, 所以建议 AccessTokenServer 从微信服务器 // 获取一次 access_token 之后的至多5秒内(收敛时间, 视情况而定, 理论上至多5个http或tcp周期) // 再次调用该函数不再去微信服务器获取, 而是直接返回之前的结果. TokenRefresh() (string, error) // 没有实际意义, 接口标识 Tag6D89F2E2FE9811E49EAAA4DB30FED8E1() }
access_token 中控服务器接口, see access_token_server.png
type AgentServer ¶
type AgentServer interface { Token() string // 获取应用的Token, 用于校验签名. CurrentAESKey() [32]byte // 获取当前有效的 AES 加密 Key LastAESKey() (key [32]byte, valid bool) // 获取上一个有效的 AES 加密 Key CorpId() string // 企业号Id, 用于约束消息的 CorpId, 如果为空表示不约束, 同时忽略 AgentId 的约束 AgentId() int64 // 应用Id, 用于约束消息的 AgentId, 如果为 -1 表示不约束 MessageHandler() MessageHandler // 获取 MessageHandler }
type AgentServerFrontend ¶
type AgentServerFrontend struct {
// contains filtered or unexported fields
}
实现了 http.Handler, 处理一个企业号应用的消息(事件)请求.
func NewAgentServerFrontend ¶
func NewAgentServerFrontend(srv AgentServer, handler ErrorHandler, interceptor Interceptor) *AgentServerFrontend
handler, interceptor 均可以为 nil
func (*AgentServerFrontend) ServeHTTP ¶
func (frontend *AgentServerFrontend) ServeHTTP(w http.ResponseWriter, r *http.Request)
实现 http.Handler.
type Client ¶
type Client struct { AccessTokenServer HttpClient *http.Client }
企业号"主动"请求功能的基本封装.
func NewClient ¶
func NewClient(srv AccessTokenServer, clt *http.Client) *Client
创建一个新的 Client.
如果 clt == nil 则默认用 http.DefaultClient
func (*Client) GetCallbackIP ¶
获取微信服务器的ip段
func (*Client) GetJSON ¶
GET 微信资源, 然后将微信服务器返回的 JSON 用 encoding/json 解析到 response.
NOTE: 1. 一般不用调用这个方法, 请直接调用高层次的封装方法; 2. 最终的 URL == incompleteURL + access_token; 3. response 格式有要求, 要么是 *Error, 要么是下面结构体的指针(注意 Error 必须是第一个 Field): struct { Error ... }
func (*Client) PostJSON ¶
func (clt *Client) PostJSON(incompleteURL string, request interface{}, response interface{}) (err error)
用 encoding/json 把 request marshal 为 JSON, 放入 http 请求的 body 中, POST 到微信服务器, 然后将微信服务器返回的 JSON 用 encoding/json 解析到 response.
NOTE: 1. 一般不用调用这个方法, 请直接调用高层次的封装方法; 2. 最终的 URL == incompleteURL + access_token; 3. response 格式有要求, 要么是 *Error, 要么是下面结构体的指针(注意 Error 必须是第一个 Field): struct { Error ... }
func (*Client) PostMultipartForm ¶
func (clt *Client) PostMultipartForm(incompleteURL string, fields []MultipartFormField, response interface{}) (err error)
通用上传接口.
--BOUNDARY Content-Disposition: form-data; name="FIELDNAME"; filename="FILENAME" Content-Type: application/octet-stream FILE-CONTENT --BOUNDARY Content-Disposition: form-data; name="FIELDNAME" JSON-DESCRIPTION --BOUNDARY-- NOTE: 1. 一般不需要调用这个方法, 请直接调用高层次的封装方法; 2. 最终的 URL == incompleteURL + access_token; 3. response 格式有要求, 要么是 *Error, 要么是下面结构体的指针(注意 Error 必须是第一个 Field): struct { Error ... }
type DefaultAccessTokenServer ¶
type DefaultAccessTokenServer struct {
// contains filtered or unexported fields
}
AccessTokenServer 的简单实现.
NOTE: 1. 用于单进程环境. 2. 因为 DefaultAccessTokenServer 同时也是一个简单的中控服务器, 而不是仅仅实现 AccessTokenServer 接口, 所以整个系统只能存在一个 DefaultAccessTokenServer 实例!
func NewDefaultAccessTokenServer ¶
func NewDefaultAccessTokenServer(corpId, corpSecret string, clt *http.Client) (srv *DefaultAccessTokenServer)
创建一个新的 DefaultAccessTokenServer.
如果 clt == nil 则默认使用 http.DefaultClient.
func (*DefaultAccessTokenServer) Tag6D89F2E2FE9811E49EAAA4DB30FED8E1 ¶
func (srv *DefaultAccessTokenServer) Tag6D89F2E2FE9811E49EAAA4DB30FED8E1()
func (*DefaultAccessTokenServer) Token ¶
func (srv *DefaultAccessTokenServer) Token() (token string, err error)
func (*DefaultAccessTokenServer) TokenRefresh ¶
func (srv *DefaultAccessTokenServer) TokenRefresh() (token string, err error)
type DefaultAgentServer ¶
type DefaultAgentServer struct {
// contains filtered or unexported fields
}
func NewDefaultAgentServer ¶
func NewDefaultAgentServer(corpId string, agentId int64, token string, aesKey []byte, handler MessageHandler) (srv *DefaultAgentServer)
NewDefaultAgentServer 创建一个新的 DefaultAgentServer.
func (*DefaultAgentServer) AgentId ¶
func (srv *DefaultAgentServer) AgentId() int64
func (*DefaultAgentServer) CorpId ¶
func (srv *DefaultAgentServer) CorpId() string
func (*DefaultAgentServer) CurrentAESKey ¶
func (srv *DefaultAgentServer) CurrentAESKey() (key [32]byte)
func (*DefaultAgentServer) LastAESKey ¶
func (srv *DefaultAgentServer) LastAESKey() (key [32]byte, valid bool)
func (*DefaultAgentServer) MessageHandler ¶
func (srv *DefaultAgentServer) MessageHandler() MessageHandler
func (*DefaultAgentServer) Token ¶
func (srv *DefaultAgentServer) Token() string
func (*DefaultAgentServer) UpdateAESKey ¶
func (srv *DefaultAgentServer) UpdateAESKey(aesKey []byte) (err error)
type Error ¶
type ErrorHandler ¶
type ErrorHandler interface {
ServeError(http.ResponseWriter, *http.Request, error)
}
type ErrorHandlerFunc ¶
type ErrorHandlerFunc func(http.ResponseWriter, *http.Request, error)
func (ErrorHandlerFunc) ServeError ¶
func (fn ErrorHandlerFunc) ServeError(w http.ResponseWriter, r *http.Request, err error)
type Interceptor ¶
type Interceptor interface { // 拦截 http 请求, 根据需要做一些判断, 返回是否允许后续逻辑继续处理请求, 如返回 false 则表示请求到此为止. // 请注意, 后续逻辑需要读取 r.Body 里的内容, 请谨慎读取! Intercept(w http.ResponseWriter, r *http.Request, queryValues url.Values) (shouldContinue bool) }
http 请求拦截器
type InterceptorFunc ¶
type InterceptorFunc func(w http.ResponseWriter, r *http.Request, queryValues url.Values) (shouldContinue bool)
func (InterceptorFunc) Intercept ¶
func (fn InterceptorFunc) Intercept(w http.ResponseWriter, r *http.Request, queryValues url.Values) (shouldContinue bool)
type MessageHandler ¶
type MessageHandler interface {
ServeMessage(http.ResponseWriter, *Request)
}
微信服务器推送过来的消息(事件)处理接口
type MessageHandlerFunc ¶
type MessageHandlerFunc func(http.ResponseWriter, *Request)
func (MessageHandlerFunc) ServeMessage ¶
func (fn MessageHandlerFunc) ServeMessage(w http.ResponseWriter, r *Request)
type MessageHeader ¶
type MessageHeader 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 MessageServeMux ¶
type MessageServeMux struct {
// contains filtered or unexported fields
}
MessageServeMux 实现了一个简单的消息(事件)路由器, 同时也是一个 MessageHandler 的实现.
func NewMessageServeMux ¶
func NewMessageServeMux() *MessageServeMux
func (*MessageServeMux) DefaultEventHandle ¶
func (mux *MessageServeMux) DefaultEventHandle(handler MessageHandler)
注册事件的默认 MessageHandler.
func (*MessageServeMux) DefaultEventHandleFunc ¶
func (mux *MessageServeMux) DefaultEventHandleFunc(handler func(http.ResponseWriter, *Request))
注册事件的默认 MessageHandler.
func (*MessageServeMux) DefaultMessageHandle ¶
func (mux *MessageServeMux) DefaultMessageHandle(handler MessageHandler)
注册消息的默认 MessageHandler.
func (*MessageServeMux) DefaultMessageHandleFunc ¶
func (mux *MessageServeMux) DefaultMessageHandleFunc(handler func(http.ResponseWriter, *Request))
注册消息的默认 MessageHandler.
func (*MessageServeMux) EventHandle ¶
func (mux *MessageServeMux) EventHandle(eventType string, handler MessageHandler)
注册特定类型事件的 MessageHandler.
func (*MessageServeMux) EventHandleFunc ¶
func (mux *MessageServeMux) EventHandleFunc(eventType string, handler func(http.ResponseWriter, *Request))
注册特定类型事件的 MessageHandler.
func (*MessageServeMux) MessageHandle ¶
func (mux *MessageServeMux) MessageHandle(msgType string, handler MessageHandler)
注册特定类型消息的 MessageHandler.
func (*MessageServeMux) MessageHandleFunc ¶
func (mux *MessageServeMux) MessageHandleFunc(msgType string, handler func(http.ResponseWriter, *Request))
注册特定类型消息的 MessageHandler.
func (*MessageServeMux) ServeMessage ¶
func (mux *MessageServeMux) ServeMessage(w http.ResponseWriter, r *Request)
MessageServeMux 实现了 MessageHandler 接口.
type MixedMessage ¶
type MixedMessage struct { XMLName struct{} `xml:"xml" json:"-"` MessageHeader 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"` Title string `xml:"Title" json:"Title"` // 文本消息内容 Description string `xml:"Description" json:"Description"` URL string `xml:"Url" json:"Url"` 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"` }
微信服务器推送过来的消息(事件)的合集.
type MultiAgentServerFrontend ¶
type MultiAgentServerFrontend struct {
// contains filtered or unexported fields
}
多个 AgentServer 的前端, http.Handler 的实现.
MultiAgentServerFrontend 可以处理多个企业号应用的消息(事件), 但是要求在回调 URL 上加上一个 查询参数(参数名与 urlAgentServerQueryName 一致), 通过这个参数的值来索引对应的 AgentServer. 例如回调 URL 为(urlAgentServerQueryName == "agent_server"): http://www.xxx.com/weixin?agent_server=1234567890 那么就可以在后端调用 MultiAgentServerFrontend.SetAgentServer("1234567890", AgentServer) 来增加一个 AgentServer 来处理 agent_server=1234567890 的消息(事件). MultiAgentServerFrontend 并发安全, 可以在运行中动态增加和删除 AgentServer.
func NewMultiAgentServerFrontend ¶
func NewMultiAgentServerFrontend(urlAgentServerQueryName string, errHandler ErrorHandler, interceptor Interceptor) *MultiAgentServerFrontend
NewMultiAgentServerFrontend 创建一个新的 MultiAgentServerFrontend.
urlAgentServerQueryName: 回调 URL 上参数名, 这个参数的值就是索引 AgentServer 的 key errHandler: 错误处理 handler, 可以为 nil interceptor: 拦截器, 可以为 nil
func (*MultiAgentServerFrontend) DeleteAgentServer ¶
func (frontend *MultiAgentServerFrontend) DeleteAgentServer(serverKey string)
func (*MultiAgentServerFrontend) DeleteAllAgentServer ¶
func (frontend *MultiAgentServerFrontend) DeleteAllAgentServer()
func (*MultiAgentServerFrontend) ServeHTTP ¶
func (frontend *MultiAgentServerFrontend) ServeHTTP(w http.ResponseWriter, r *http.Request)
func (*MultiAgentServerFrontend) SetAgentServer ¶
func (frontend *MultiAgentServerFrontend) SetAgentServer(serverKey string, server AgentServer) (err error)
type MultipartFormField ¶
type Request ¶
type Request struct { AgentToken string // 请求消息所属企业号应用的 Token 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 }
消息(事件)请求信息
type RequestHttpBody ¶
type RequestHttpBody struct { XMLName struct{} `xml:"xml" json:"-"` CorpId string `xml:"ToUserName"` AgentId int64 `xml:"AgentID"` EncryptedMsg string `xml:"Encrypt"` }
微信服务器请求 http body