Documentation
¶
Overview ¶
微信公众平台(订阅号&服务号) SDK 的核心库
Index ¶
- Constants
- type AccessTokenServer
- type Client
- 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 Context
- func (ctx *Context) AESResponse(msg interface{}, timestamp int64, nonce string, random []byte) (err error)
- func (ctx *Context) Abort()
- func (ctx *Context) Get(key string) (value interface{}, exists bool)
- func (ctx *Context) IsAborted() bool
- func (ctx *Context) MustGet(key string) interface{}
- func (ctx *Context) Next()
- func (ctx *Context) NoneResponse() (err error)
- func (ctx *Context) RawResponse(msg interface{}) (err error)
- func (ctx *Context) Set(key string, value interface{})
- func (ctx *Context) SetHandlers(handlers HandlerChain)
- type DefaultAccessTokenServer
- type Error
- type ErrorHandler
- type ErrorHandlerFunc
- type EventType
- type Handler
- type HandlerChain
- type HandlerFunc
- type MixedMsg
- type MsgHeader
- type MsgType
- type MultipartFormField
- type ServeMux
- func (mux *ServeMux) DefaultEventHandle(handlers ...Handler)
- func (mux *ServeMux) DefaultEventHandleFunc(handlers ...func(*Context))
- func (mux *ServeMux) DefaultMsgHandle(handlers ...Handler)
- func (mux *ServeMux) DefaultMsgHandleFunc(handlers ...func(*Context))
- func (mux *ServeMux) EventHandle(eventType EventType, handlers ...Handler)
- func (mux *ServeMux) EventHandleFunc(eventType EventType, handlers ...func(*Context))
- func (mux *ServeMux) MsgHandle(msgType MsgType, handlers ...Handler)
- func (mux *ServeMux) MsgHandleFunc(msgType MsgType, handlers ...func(*Context))
- func (mux *ServeMux) ServeMsg(ctx *Context)
- func (mux *ServeMux) Use(middlewares ...Handler)
- func (mux *ServeMux) UseForEvent(middlewares ...Handler)
- func (mux *ServeMux) UseForMsg(middlewares ...Handler)
- func (mux *ServeMux) UseFunc(middlewares ...func(*Context))
- func (mux *ServeMux) UseFuncForEvent(middlewares ...func(*Context))
- func (mux *ServeMux) UseFuncForMsg(middlewares ...func(*Context))
- type Server
Examples ¶
Constants ¶
const ( ErrCodeOK = 0 ErrCodeInvalidCredential = 40001 // access_token 过期错误码 ErrCodeAccessTokenExpired = 42001 // access_token 过期错误码(maybe!!!) )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AccessTokenServer ¶
type AccessTokenServer interface {
Token() (token string, err error) // 请求中控服务器返回缓存的 access_token
RefreshToken(currentToken string) (token string, err error) // 请求中控服务器刷新 access_token
IID01332E16DF5011E5A9D5A4DB30FED8E1() // 接口标识, 没有实际意义
}
access_token 中控服务器接口.
type Client ¶
type Client struct {
AccessTokenServer
HttpClient *http.Client
}
func NewClient ¶
func NewClient(srv AccessTokenServer, clt *http.Client) *Client
NewClient 创建一个新的 Client.
如果 clt == nil 则默认用 http.DefaultClient
func (*Client) GetJSON ¶
GetJSON HTTP 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)
PostJSON 用 encoding/json 把 request marshal 为 JSON, HTTP 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)
PostMultipartForm 通用上传接口.
--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 Context ¶
type Context struct {
ResponseWriter http.ResponseWriter
Request *http.Request
QueryParams url.Values // 回调请求 URL 的查询参数集合
EncryptType string // 回调请求 URL 的加密方式参数: encrypt_type
MsgSignature string // 回调请求 URL 的消息体签名参数: msg_signature
Signature string // 回调请求 URL 的签名参数: signature
Timestamp int64 // 回调请求 URL 的时间戳参数: timestamp
Nonce string // 回调请求 URL 的随机数参数: nonce
MsgCiphertext []byte // 消息的密文文本
MsgPlaintext []byte // 消息的明文文本, xml格式
MixedMsg *MixedMsg // 消息
Token string // 当前消息所属公众号的 Token
AESKey []byte // 当前消息加密所用的 aes-key, read-only!!!
Random []byte // 当前消息加密所用的 random, 16-bytes
AppId string // 当前消息加密所用的 AppId
// contains filtered or unexported fields
}
Context 是 Handler 处理消息(事件)的上下文环境. 非并发安全!
func (*Context) AESResponse ¶
func (ctx *Context) AESResponse(msg interface{}, timestamp int64, nonce string, random []byte) (err error)
AESResponse 回复aes加密的消息给微信服务器.
msg: 经过 encoding/xml.Marshal 得到的结果符合微信消息格式的任何数据结构 timestamp: 时间戳, 如果为 0 则默认使用 Context.Timestamp nonce: 随机数, 如果为 "" 则默认使用 Context.Nonce random: 16字节的随机字符串, 如果为 nil 则默认使用 Context.Random
func (*Context) Abort ¶
func (ctx *Context) Abort()
Abort 阻止系统调用当前 handler 后续的 handlers, 即当前的 handler 处理完毕就返回, 一般在 middleware 中调用.
func (*Context) Get ¶
Get 返回 Context 中 key 对应的 value, 如果 key 存在的返回 (value, true), 否则返回 (nil, false).
func (*Context) Next ¶
func (ctx *Context) Next()
Next 中断当前 handler 程序逻辑执行其后续的 handlers, 一般在 middleware 中调用.
func (*Context) NoneResponse ¶
RawResponse 表示没有消息回复给微信服务器.
func (*Context) RawResponse ¶
RawResponse 回复明文消息给微信服务器.
msg: 经过 encoding/xml.Marshal 得到的结果符合微信消息格式的任何数据结构
func (*Context) SetHandlers ¶
func (ctx *Context) SetHandlers(handlers HandlerChain)
SetHandlers 设置 handlers 给 Context.Next() 调用, 务必在 Context.Next() 调用之前设置, 否则会 panic.
NOTE: 此方法一般用不到, 除非你自己实现一个 Handler 给 Server 使用, 参考 ServeMux.
type DefaultAccessTokenServer ¶
type DefaultAccessTokenServer struct {
// contains filtered or unexported fields
}
DefaultAccessTokenServer 实现了 AccessTokenServer 接口.
NOTE: 1. 用于单进程环境. 2. 因为 DefaultAccessTokenServer 同时也是一个简单的中控服务器, 而不是仅仅实现 AccessTokenServer 接口, 所以整个系统只能存在一个 DefaultAccessTokenServer 实例!
func NewDefaultAccessTokenServer ¶
func NewDefaultAccessTokenServer(appId, appSecret string, httpClient *http.Client) (srv *DefaultAccessTokenServer)
NewDefaultAccessTokenServer 创建一个新的 DefaultAccessTokenServer, 如果 httpClient == nil 则默认使用 http.DefaultClient.
func (*DefaultAccessTokenServer) IID01332E16DF5011E5A9D5A4DB30FED8E1 ¶
func (srv *DefaultAccessTokenServer) IID01332E16DF5011E5A9D5A4DB30FED8E1()
func (*DefaultAccessTokenServer) RefreshToken ¶
func (srv *DefaultAccessTokenServer) RefreshToken(currentToken string) (token string, err error)
func (*DefaultAccessTokenServer) Token ¶
func (srv *DefaultAccessTokenServer) Token() (token string, err error)
type ErrorHandler ¶
type ErrorHandler interface {
ServeError(http.ResponseWriter, *http.Request, error)
}
var DefaultErrorHandler ErrorHandler = ErrorHandlerFunc(defaultErrorHandlerFunc)
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 HandlerChain ¶
type HandlerChain []Handler
type HandlerFunc ¶
type HandlerFunc func(*Context)
func (HandlerFunc) ServeMsg ¶
func (fn HandlerFunc) ServeMsg(ctx *Context)
type MixedMsg ¶
type MixedMsg struct {
XMLName struct{} `xml:"xml" json:"-"`
MsgHeader
EventType EventType `xml:"Event" json:"Event"`
MsgId int64 `xml:"MsgId" json:"MsgId"` // request
Content string `xml:"Content" json:"Content"` // request
MediaId string `xml:"MediaId" json:"MediaId"` // request
PicURL string `xml:"PicUrl" json:"PicUrl"` // request
Format string `xml:"Format" json:"Format"` // request
Recognition string `xml:"Recognition" json:"Recognition"` // request
ThumbMediaId string `xml:"ThumbMediaId" json:"ThumbMediaId"` // request
LocationX float64 `xml:"Location_X" json:"Location_X"` // request
LocationY float64 `xml:"Location_Y" json:"Location_Y"` // request
Scale int `xml:"Scale" json:"Scale"` // request
Label string `xml:"Label" json:"Label"` // request
Title string `xml:"Title" json:"Title"` // request
Description string `xml:"Description" json:"Description"` // request
URL string `xml:"Url" json:"Url"` // request
EventKey string `xml:"EventKey" json:"EventKey"` // request, menu
Ticket string `xml:"Ticket" json:"Ticket"` // request
Latitude float64 `xml:"Latitude" json:"Latitude"` // request
Longitude float64 `xml:"Longitude" json:"Longitude"` // request
Precision float64 `xml:"Precision" json:"Precision"` // request
// menu
MenuId int64 `xml:"MenuId" json:"MenuId"`
ScanCodeInfo *struct {
ScanType string `xml:"ScanType" json:"ScanType"`
ScanResult string `xml:"ScanResult" json:"ScanResult"`
} `xml:"ScanCodeInfo,omitempty" json:"ScanCodeInfo,omitempty"`
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,omitempty" json:"SendPicsInfo,omitempty"`
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"`
} `xml:"SendLocationInfo,omitempty" json:"SendLocationInfo,omitempty"`
MsgID int64 `xml:"MsgID" json:"MsgID"` // template, mass
Status string `xml:"Status" json:"Status"` // template, mass
// shakearound
ChosenBeacon *struct {
UUID string `xml:"Uuid" json:"Uuid"`
Major int `xml:"Major" json:"Major"`
Minor int `xml:"Minor" json:"Minor"`
Distance float64 `xml:"Distance" json:"Distance"`
} `xml:"ChosenBeacon,omitempty" json:"ChosenBeacon,omitempty"`
AroundBeacons []struct {
UUID string `xml:"Uuid" json:"Uuid"`
Major int `xml:"Major" json:"Major"`
Minor int `xml:"Minor" json:"Minor"`
Distance float64 `xml:"Distance" json:"Distance"`
} `xml:"AroundBeacons>AroundBeacon,omitempty" json:"AroundBeacons,omitempty"`
// contains filtered or unexported fields
}
微信服务器推送过来的消息(事件)的合集.
type MsgHeader ¶
type MsgHeader struct {
ToUserName string `xml:"ToUserName" json:"ToUserName"`
FromUserName string `xml:"FromUserName" json:"FromUserName"`
CreateTime int64 `xml:"CreateTime" json:"CreateTime"`
MsgType MsgType `xml:"MsgType" json:"MsgType"`
}
微信服务器推送过来的消息(事件)的通用消息头.
type MultipartFormField ¶
type ServeMux ¶
type ServeMux struct {
// contains filtered or unexported fields
}
ServeMux 是一个消息(事件)路由器, 同时也是一个 Handler 的实现.
NOTE: ServeMux 非并发安全, 如果需要并发安全的 Handler, 可以参考 ServeMux 实现一个.
func NewServeMux ¶
func NewServeMux() *ServeMux
func (*ServeMux) DefaultEventHandle ¶
DefaultEventHandle 设置 handlers 以处理没有匹配到具体类型的 HandlerChain 的事件.
func (*ServeMux) DefaultEventHandleFunc ¶
DefaultEventHandleFunc 设置 handlers 以处理没有匹配到具体类型的 HandlerChain 的事件.
func (*ServeMux) DefaultMsgHandle ¶
DefaultMsgHandle 设置 handlers 以处理没有匹配到具体类型的 HandlerChain 的消息.
func (*ServeMux) DefaultMsgHandleFunc ¶
DefaultMsgHandleFunc 设置 handlers 以处理没有匹配到具体类型的 HandlerChain 的消息.
func (*ServeMux) EventHandle ¶
EventHandle 设置 handlers 以处理特定类型的事件.
func (*ServeMux) EventHandleFunc ¶
EventHandleFunc 设置 handlers 以处理特定类型的事件.
func (*ServeMux) MsgHandleFunc ¶
MsgHandleFunc 设置 handlers 以处理特定类型的消息.
func (*ServeMux) UseForEvent ¶
UseForEvent 注册(新增) middlewares 使其在所有事件的 Handler 之前处理该处理事件.
func (*ServeMux) UseFuncForEvent ¶
UseFuncForEvent 注册(新增) middlewares 使其在所有事件的 Handler 之前处理该处理事件.
func (*ServeMux) UseFuncForMsg ¶
UseFuncForMsg 注册(新增) middlewares 使其在所有消息的 Handler 之前处理该处理消息.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server 用于处理微信服务器的回调请求, 并发安全!
通常情况下一个 Server 实例用于处理一个公众号的消息(事件), 此时建议指定 oriId(原始ID) 和 appId(明文模式下无需指定) 用于约束消息(事件); 特殊情况下也可以一个 Server 实例用于处理多个公众号的消息(事件), 此时要求这些公众号的 token 是一样的, 并且 oriId 和 appId 必须设置为 "".
func NewServer ¶
func NewServer(oriId, appId, token, base64AESKey string, handler Handler, errorHandler ErrorHandler) (srv *Server)
NewServer 创建一个新的 Server.
oriId: 可选; 公众号的原始ID(微信公众号管理后台查看), 如果设置了值则该Server只能处理 ToUserName 为该值的公众号的消息(事件); appId: 可选; 公众号的AppId, 如果设置了值则安全模式时该Server只能处理 AppId 为该值的公众号的消息(事件); token: 必须; 公众号用于验证签名的token; base64AESKey: 可选; aes加密解密key, 43字节长(base64编码, 去掉了尾部的'='), 安全模式必须设置; handler: 必须; 处理微信服务器推送过来的消息(事件)的Handler; errorHandler: 可选; 用于处理Server在处理消息(事件)过程中产生的错误, 如果没有设置则默认使用 DefaultErrorHandler.
func (*Server) ServeHTTP ¶
ServeHTTP 处理微信服务器的回调请求, queryParams 参数可以为 nil.
Example ¶
package main
import (
"net/http"
"github.com/XieXianbin/msg-provider/wechat/mp/core"
)
func main() {
mux := core.NewServeMux() // 创建 core.Handler, 也可以用自己实现的 core.Handler
// 注册消息(事件)处理 Handler, 都不是必须的!
{
mux.UseFunc(func(ctx *core.Context) { // 注册中间件, 处理所有的消息(事件)
// TODO: 中间件处理逻辑
})
mux.UseFuncForMsg(func(ctx *core.Context) { // 注册中间件, 处理所有的消息
// TODO: 中间件处理逻辑
})
mux.UseFuncForEvent(func(ctx *core.Context) { // 注册中间件, 处理所有的事件
// TODO: 中间件处理逻辑
})
mux.DefaultMsgHandleFunc(func(ctx *core.Context) { // 设置默认消息处理 Handler
// TODO: 消息处理逻辑
})
mux.DefaultEventHandleFunc(func(ctx *core.Context) { // 设置默认事件处理 Handler
// TODO: 事件处理逻辑
})
mux.MsgHandleFunc("{MsgType}", func(ctx *core.Context) { // 设置具体类型的消息处理 Handler
// TODO: 消息处理逻辑
})
mux.EventHandleFunc("{EventType}", func(ctx *core.Context) { // 设置具体类型的事件处理 Handler
// TODO: 事件处理逻辑
})
}
// 创建 Server, 设置正确的参数.
// 通常一个 Server 对应一个公众号, 当然一个 Server 也可以对应多个公众号, 这个时候 oriId 和 appId 都应该设置为空值!
srv := core.NewServer("{oriId}", "{appId}", "{token}", "{base64AESKey}", mux, nil)
// 在回调 URL 的 Handler 里处理消息(事件)
http.HandleFunc("/wechat_callback", func(w http.ResponseWriter, r *http.Request) {
srv.ServeHTTP(w, r, nil)
})
}
