Tao Zhang 5 жил өмнө
parent
commit
235c71ace3
1 өөрчлөгдсөн 538 нэмэгдсэн , 0 устгасан
  1. 538 0
      接口说明.md

+ 538 - 0
接口说明.md

@@ -0,0 +1,538 @@
+```GO
+package wx_util // import "app.yhyue.com/BP/weixin_util"
+
+
+CONSTANTS
+
+const (
+	// Event type
+	msgEvent = "event"
+
+	EventSubscribe    = "subscribe"
+	EventUnsubscribe  = "unsubscribe"
+	EventScan         = "SCAN"
+	EventView         = "VIEW"
+	EventClick        = "CLICK"
+	EventLocation     = "LOCATION"
+	EventTemplateSent = "TEMPLATESENDJOBFINISH"
+
+	// Message type
+	MsgTypeDefault           = ".*"
+	MsgTypeText              = "text"
+	MsgTypeImage             = "image"
+	MsgTypeVoice             = "voice"
+	MsgTypeVideo             = "video"
+	MsgTypeShortVideo        = "shortvideo"
+	MsgTypeLocation          = "location"
+	MsgTypeLink              = "link"
+	MsgTypeEvent             = msgEvent + ".*"
+	MsgTypeEventSubscribe    = msgEvent + "\\." + EventSubscribe
+	MsgTypeEventUnsubscribe  = msgEvent + "\\." + EventUnsubscribe
+	MsgTypeEventScan         = msgEvent + "\\." + EventScan
+	MsgTypeEventView         = msgEvent + "\\." + EventView
+	MsgTypeEventClick        = msgEvent + "\\." + EventClick
+	MsgTypeEventLocation     = msgEvent + "\\." + EventLocation
+	MsgTypeEventTemplateSent = msgEvent + "\\." + EventTemplateSent
+
+	// Media type
+	MediaTypeImage = "image"
+	MediaTypeVoice = "voice"
+	MediaTypeVideo = "video"
+	MediaTypeThumb = "thumb"
+	// Button type
+	MenuButtonTypeKey             = "click"
+	MenuButtonTypeUrl             = "view"
+	MenuButtonTypeScancodePush    = "scancode_push"
+	MenuButtonTypeScancodeWaitmsg = "scancode_waitmsg"
+	MenuButtonTypePicSysphoto     = "pic_sysphoto"
+	MenuButtonTypePicPhotoOrAlbum = "pic_photo_or_album"
+	MenuButtonTypePicWeixin       = "pic_weixin"
+	MenuButtonTypeLocationSelect  = "location_select"
+	MenuButtonTypeMediaId         = "media_id"
+	MenuButtonTypeViewLimited     = "view_limited"
+	MenuButtonTypeMiniProgram     = "miniprogram"
+	// Template Status
+	TemplateSentStatusSuccess      = "success"
+	TemplateSentStatusUserBlock    = "failed:user block"
+	TemplateSentStatusSystemFailed = "failed:system failed"
+	// Redirect Scope
+	RedirectURLScopeBasic    = "snsapi_base"
+	RedirectURLScopeUserInfo = "snsapi_userinfo"
+	// Weixin host URL
+	weixinHost               = "https://api.weixin.qq.com/cgi-bin"
+	weixinQRScene            = "https://api.weixin.qq.com/cgi-bin/qrcode"
+	weixinShowQRScene        = "https://mp.weixin.qq.com/cgi-bin/showqrcode"
+	weixinMaterialURL        = "https://api.weixin.qq.com/cgi-bin/material"
+	weixinShortURL           = "https://api.weixin.qq.com/cgi-bin/shorturl"
+	weixinUserInfo           = "https://api.weixin.qq.com/cgi-bin/user/info"
+	weixinFileURL            = "http://file.api.weixin.qq.com/cgi-bin/media"
+	weixinTemplate           = "https://api.weixin.qq.com/cgi-bin/template"
+	weixinRedirectURL        = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect"
+	weixinUserAccessTokenURL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code"
+	weixinJsApiTicketURL     = "https://api.weixin.qq.com/cgi-bin/ticket/getticket"
+	// Max retry count
+	retryMaxN = 3
+	// Reply format
+	replyText               = "<xml>%s<MsgType><![CDATA[text]]></MsgType><Content><![CDATA[%s]]></Content></xml>"
+	replyImage              = "<xml>%s<MsgType><![CDATA[image]]></MsgType><Image><MediaId><![CDATA[%s]]></MediaId></Image></xml>"
+	replyVoice              = "<xml>%s<MsgType><![CDATA[voice]]></MsgType><Voice><MediaId><![CDATA[%s]]></MediaId></Voice></xml>"
+	replyVideo              = "<xml>%s<MsgType><![CDATA[video]]></MsgType><Video><MediaId><![CDATA[%s]]></MediaId><Title><![CDATA[%s]]></Title><Description><![CDATA[%s]]></Description></Video></xml>"
+	replyMusic              = "<xml>%s<MsgType><![CDATA[music]]></MsgType><Music><Title><![CDATA[%s]]></Title><Description><![CDATA[%s]]></Description><MusicUrl><![CDATA[%s]]></MusicUrl><HQMusicUrl><![CDATA[%s]]></HQMusicUrl><ThumbMediaId><![CDATA[%s]]></ThumbMediaId></Music></xml>"
+	replyNews               = "<xml>%s<MsgType><![CDATA[news]]></MsgType><ArticleCount>%d</ArticleCount><Articles>%s</Articles></xml>"
+	replyHeader             = "<ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%d</CreateTime>"
+	replyArticle            = "<item><Title><![CDATA[%s]]></Title> <Description><![CDATA[%s]]></Description><PicUrl><![CDATA[%s]]></PicUrl><Url><![CDATA[%s]]></Url></item>"
+	transferCustomerService = "<xml>" + replyHeader + "<MsgType><![CDATA[transfer_customer_service]]></MsgType></xml>"
+
+	// Material request
+	requestMaterial = `{"type":"%s","offset":%d,"count":%d}`
+	// QR scene request
+	requestQRScene         = `{"expire_seconds":%d,"action_name":"QR_SCENE","action_info":{"scene":{"scene_id":%d}}}`
+	requestQRSceneStr      = `{"expire_seconds":%d,"action_name":"QR_STR_SCENE","action_info":{"scene":{"scene_str":"%s"}}}`
+	requestQRLimitScene    = `{"action_name":"QR_LIMIT_SCENE","action_info":{"scene":{"scene_id":%d}}}`
+	requestQRLimitSceneStr = `{"action_name":"QR_LIMIT_STR_SCENE","action_info":{"scene":{"scene_str":"%s"}}}`
+)
+    nolint
+
+
+FUNCTIONS
+
+func authAccessToken(appid string, secret string) (string, time.Duration)
+func checkSignature(t string, w http.ResponseWriter, r *http.Request) bool
+func createJsAPITicket(cin chan AccessToken, c chan jsAPITicket)
+func downloadMedia(c chan AccessToken, mediaID string, writer io.Writer) error
+func fixPKCS7UnPadding(data []byte) []byte
+func marshal(v interface{}) ([]byte, error)
+func postMessage(c chan AccessToken, msg interface{}) error
+func postRequest(reqURL string, c chan AccessToken, data []byte) ([]byte, error)
+func sendGetRequest(reqURL string, c chan AccessToken) ([]byte, error)
+func uploadMedia(c chan AccessToken, mediaType string, filename string, reader io.Reader) (string, error)
+    nolint: gocyclo
+
+
+TYPES
+
+type AccessToken struct {
+	Token   string
+	Expires time.Time
+}
+    AccessToken define weixin access token.
+
+type Article struct {
+	Title       string `json:"title"`
+	Description string `json:"description"`
+	PicUrl      string `json:"picurl"` // nolint
+	Url         string `json:"url"`    // nolint
+}
+    Article is the response of news message.
+
+type HandlerFunc func(ResponseWriter, *Request)
+    HandlerFunc is callback function handler
+
+type Material struct {
+	MediaId    string `json:"media_id,omitempty"` // nolint
+	Name       string `json:"name,omitempty"`
+	UpdateTime int64  `json:"update_time,omitempty"`
+	CreateTime int64  `json:"create_time,omitempty"`
+	Url        string `json:"url,omitempty"` // nolint
+	Content    struct {
+		NewsItem []struct {
+			Title            string `json:"title,omitempty"`
+			ThumbMediaId     string `json:"thumb_media_id,omitempty"` // nolint
+			ShowCoverPic     int    `json:"show_cover_pic,omitempty"`
+			Author           string `json:"author,omitempty"`
+			Digest           string `json:"digest,omitempty"`
+			Content          string `json:"content,omitempty"`
+			Url              string `json:"url,omitempty"`                // nolint
+			ContentSourceUrl string `json:"content_source_url,omitempty"` // nolint
+		} `json:"news_item,omitempty"`
+	} `json:"content,omitempty"`
+}
+    Material data.
+
+type Materials struct {
+	TotalCount int        `json:"total_count,omitempty"`
+	ItemCount  int        `json:"item_count,omitempty"`
+	Items      []Material `json:"item,omitempty"`
+}
+    Materials is the list of material
+
+type Menu struct {
+	Buttons []MenuButton `json:"button,omitempty"`
+}
+    Menu is custom menu.
+
+type MenuButton struct {
+	Name       string       `json:"name"`
+	Type       string       `json:"type,omitempty"`
+	Key        string       `json:"key,omitempty"`
+	Url        string       `json:"url,omitempty"`      // nolint
+	MediaId    string       `json:"media_id,omitempty"` // nolint
+	SubButtons []MenuButton `json:"sub_button,omitempty"`
+	AppId      string       `json:"appid,omitempty"` // nolint
+	PagePath   string       `json:"pagepath,omitempty"`
+}
+    MenuButton is the button of custom menu.
+
+type MessageHeader struct {
+	ToUserName   string
+	FromUserName string
+	CreateTime   int
+	MsgType      string
+	Encrypt      string
+}
+    MessageHeader is the header of common message.
+
+type Music struct {
+	Title        string `json:"title"`
+	Description  string `json:"description"`
+	MusicUrl     string `json:"musicurl"`       // nolint
+	HQMusicUrl   string `json:"hqmusicurl"`     // nolint
+	ThumbMediaId string `json:"thumb_media_id"` // nolint
+}
+    Music is the response of music message.
+
+type QRScene struct {
+	Ticket        string `json:"ticket"`
+	ExpireSeconds int    `json:"expire_seconds"`
+	Url           string `json:"url,omitempty"` // nolint
+}
+    QRScene is the QR code.
+
+func (qr *QRScene) ToURL() string
+    ToURL convert qr scene to url.
+
+type Request struct {
+	MessageHeader
+	MsgId        int64 // nolint
+	Content      string
+	PicUrl       string // nolint
+	MediaId      string // nolint
+	Format       string
+	ThumbMediaId string  // nolint
+	LocationX    float32 `xml:"Location_X"`
+	LocationY    float32 `xml:"Location_Y"`
+	Scale        float32
+	Label        string
+	Title        string
+	Description  string
+	Url          string // nolint
+	Event        string
+	EventKey     string
+	Ticket       string
+	Latitude     float32
+	Longitude    float32
+	Precision    float32
+	Recognition  string
+	Status       string
+}
+    Request is weixin event request.
+
+type ResponseWriter interface {
+	// Get weixin
+	GetWeixin() *Weixin
+	GetUserData() interface{}
+	// Reply message
+	replyMsg(msg string)
+	ReplyOK()
+	ReplyText(text string)
+	ReplyImage(mediaId string)
+	ReplyVoice(mediaId string)
+	ReplyVideo(mediaId string, title string, description string)
+	ReplyMusic(music *Music)
+	ReplyNews(articles []Article)
+	TransferCustomerService(serviceId string)
+	// Post message
+	PostText(text string) error
+	PostImage(mediaId string) error
+	PostVoice(mediaId string) error
+	PostVideo(mediaId string, title string, description string) error
+	PostMusic(music *Music) error
+	PostNews(articles []Article) error
+	PostTemplateMessage(templateid string, url string, data TmplData) (int32, error)
+	// Media operator
+	UploadMediaFromFile(mediaType string, filepath string) (string, error)
+	DownloadMediaToFile(mediaId string, filepath string) error
+	UploadMedia(mediaType string, filename string, reader io.Reader) (string, error)
+	DownloadMedia(mediaId string, writer io.Writer) error
+}
+    ResponseWriter is used to output reply nolint
+
+type TmplData map[string]TmplItem
+    TmplData for mini program
+
+type TmplItem struct {
+	Value string `json:"value,omitempty"`
+	Color string `json:"color,omitempty"`
+}
+    TmplItem for mini program
+
+type TmplMiniProgram struct {
+	AppId    string `json:"appid,omitempty"` // nolint
+	PagePath string `json:"pagepath,omitempty"`
+}
+    TmplMiniProgram for mini program
+
+type TmplMsg struct {
+	ToUser      string           `json:"touser"`
+	TemplateId  string           `json:"template_id"`           // nolint
+	Url         string           `json:"url,omitempty"`         // nolint 若填写跳转小程序 则此为版本过低的替代跳转url
+	MiniProgram *TmplMiniProgram `json:"miniprogram,omitempty"` // 跳转小程序 选填
+	Data        TmplData         `json:"data,omitempty"`
+	Color       string           `json:"color,omitempty"` // 全局颜色
+}
+    TmplMsg for mini program
+
+type UserAccessToken struct {
+	AccessToken   string `json:"access_token"`
+	RefreshToken  string `json:"refresh_token"`
+	ExpireSeconds int    `json:"expires_in"`
+	OpenId        string `json:"openid"` // nolint
+	Scope         string `json:"scope"`
+	UnionId       string `json:"unionid,omitempty"` // nolint
+}
+    UserAccessToken access token for user.
+
+type UserInfo struct {
+	Subscribe     int    `json:"subscribe,omitempty"`
+	Language      string `json:"language,omitempty"`
+	OpenId        string `json:"openid,omitempty"`  // nolint
+	UnionId       string `json:"unionid,omitempty"` // nolint
+	Nickname      string `json:"nickname,omitempty"`
+	Sex           int    `json:"sex,omitempty"`
+	City          string `json:"city,omitempty"`
+	Country       string `json:"country,omitempty"`
+	Province      string `json:"province,omitempty"`
+	HeadImageUrl  string `json:"headimgurl,omitempty"` // nolint
+	SubscribeTime int64  `json:"subscribe_time,omitempty"`
+	Remark        string `json:"remark,omitempty"`
+	GroupId       int    `json:"groupid,omitempty"` // nolint
+}
+    UserInfo store user information.
+
+type Weixin struct {
+	token          string
+	routes         []*route
+	tokenChan      chan AccessToken
+	ticketChan     chan jsAPITicket
+	userData       interface{}
+	appID          string
+	appSecret      string
+	refreshToken   int32
+	encodingAESKey []byte
+}
+    Weixin instance
+
+func New(token string, appid string, secret string) *Weixin
+    New create a Weixin instance.
+
+func NewWithUserData(token string, appid string, secret string, userData interface{}) *Weixin
+    NewWithUserData create data with userdata.
+
+func (wx *Weixin) AddTemplate(shortid string) (string, error)
+    AddTemplate used to add template.
+
+func (wx *Weixin) BatchGetMaterial(materialType string, offset int, count int) (*Materials, error)
+    BatchGetMaterial used to batch get Material.
+
+func (wx *Weixin) CreateHandlerFunc(w http.ResponseWriter, r *http.Request) http.HandlerFunc
+    CreateHandlerFunc used to create handler function.
+
+func (wx *Weixin) CreateMenu(menu *Menu) error
+    CreateMenu used to create custom menu.
+
+func (wx *Weixin) CreateQRLimitScene(sceneID int) (*QRScene, error)
+    CreateQRLimitScene used to create QR limit scene.
+
+func (wx *Weixin) CreateQRLimitSceneByString(sceneStr string) (*QRScene, error)
+    CreateQRLimitSceneByString used to create QR limit scene by str.
+
+func (wx *Weixin) CreateQRScene(sceneID int, expires int) (*QRScene, error)
+    CreateQRScene used to create QR scene.
+
+func (wx *Weixin) CreateQRSceneByString(sceneStr string, expires int) (*QRScene, error)
+    CreateQRSceneByString used to create QR scene by str.
+
+func (wx *Weixin) CreateRedirectURL(urlStr string, scope string, state string) string
+    CreateRedirectURL used to create redirect url
+
+func (wx *Weixin) DeleteMenu() error
+    DeleteMenu used to delete menu.
+
+func (wx *Weixin) DownloadMedia(mediaID string, writer io.Writer) error
+    DownloadMedia used to download media with media.
+
+func (wx *Weixin) DownloadMediaToFile(mediaID string, fp string) error
+    DownloadMediaToFile used to download media and save to local file.
+
+func (wx *Weixin) GetAccessToken() AccessToken
+    GetAccessToken read access token.
+
+func (wx *Weixin) GetAppId() string
+    GetAppId retrun app id.
+
+func (wx *Weixin) GetAppSecret() string
+    GetAppSecret return app secret.
+
+func (wx *Weixin) GetIpList() ([]string, error)
+    GetIpList used to get ip list.
+
+func (wx *Weixin) GetJsAPITicket() (string, error)
+    GetJsAPITicket used to get js api ticket.
+
+func (wx *Weixin) GetMenu() (*Menu, error)
+    GetMenu used to get menu.
+
+func (wx *Weixin) GetUserAccessToken(code string) (*UserAccessToken, error)
+    GetUserAccessToken used to get open id
+
+func (wx *Weixin) GetUserInfo(openid string) (*UserInfo, error)
+    GetUserInfo used to get user info
+
+func (wx *Weixin) HandleFunc(pattern string, handler HandlerFunc)
+    HandleFunc used to register request callback.
+
+func (wx *Weixin) JsSignature(url string, timestamp int64, noncestr string) (string, error)
+    JsSignature used to sign js url.
+
+func (wx *Weixin) PostImage(touser string, mediaID string) error
+    PostImage used to post image message.
+
+func (wx *Weixin) PostMusic(touser string, music *Music) error
+    PostMusic used to post music message.
+
+func (wx *Weixin) PostNews(touser string, articles []Article) error
+    PostNews used to post news message.
+
+func (wx *Weixin) PostTemplateMessage(touser string, templateid string, url string, data TmplData) (int32, error)
+    PostTemplateMessage used to post template message.
+
+func (wx *Weixin) PostTemplateMessageMiniProgram(msg *TmplMsg) (int64, error)
+    PostTemplateMessageMiniProgram 兼容模板消息跳转小程序
+
+func (wx *Weixin) PostText(touser string, text string) error
+    PostText used to post text message.
+
+func (wx *Weixin) PostVideo(touser string, m string, t string, d string) error
+    PostVideo used to post video message.
+
+func (wx *Weixin) PostVoice(touser string, mediaID string) error
+    PostVoice used to post voice message.
+
+func (wx *Weixin) RefreshAccessToken()
+    RefreshAccessToken update access token.
+
+func (wx *Weixin) ServeHTTP(w http.ResponseWriter, r *http.Request)
+    ServeHTTP used to process weixin request and send response.
+
+func (wx *Weixin) SetEncodingAESKey(key string) error
+    SetEncodingAESKey set AES key
+
+func (wx *Weixin) SetTemplateIndustry(id1 string, id2 string) error
+    SetTemplateIndustry used to set template industry.
+
+func (wx *Weixin) ShortURL(url string) (string, error)
+    ShortURL used to convert long url to short url
+
+func (wx *Weixin) UploadMedia(mediaType string, filename string, reader io.Reader) (string, error)
+    UploadMedia used to upload media with media.
+
+func (wx *Weixin) UploadMediaFromFile(mediaType string, fp string) (string, error)
+    UploadMediaFromFile used to upload media from local file.
+
+func (wx *Weixin) createAccessToken(c chan AccessToken, appid string, secret string)
+
+func (wx *Weixin) routeRequest(w http.ResponseWriter, r *Request)
+
+type jsAPITicket struct {
+	ticket  string
+	expires time.Time
+}
+
+func getJsAPITicket(c chan AccessToken) (*jsAPITicket, error)
+
+type response struct {
+	ErrorCode    int    `json:"errcode,omitempty"`
+	ErrorMessage string `json:"errmsg,omitempty"`
+}
+
+type responseWriter struct {
+	wx           *Weixin
+	writer       http.ResponseWriter
+	toUserName   string
+	fromUserName string
+}
+
+func (w responseWriter) DownloadMedia(mediaID string, writer io.Writer) error
+    Download media with writer
+
+func (w responseWriter) DownloadMediaToFile(mediaID string, filepath string) error
+    Download media and save to local file
+
+func (w responseWriter) GetUserData() interface{}
+    Return user data.
+
+func (w responseWriter) GetWeixin() *Weixin
+    Return weixin instance.
+
+func (w responseWriter) PostImage(mediaID string) error
+    Post image message
+
+func (w responseWriter) PostMusic(music *Music) error
+    Post music message
+
+func (w responseWriter) PostNews(articles []Article) error
+    Post news message
+
+func (w responseWriter) PostTemplateMessage(templateid string, url string, data TmplData) (int32, error)
+    Post template message
+
+func (w responseWriter) PostText(text string) error
+    PostText used to Post text message
+
+func (w responseWriter) PostVideo(mediaID string, title string, desc string) error
+    Post video message
+
+func (w responseWriter) PostVoice(mediaID string) error
+    Post voice message
+
+func (w responseWriter) ReplyImage(mediaID string)
+    ReplyImage used to reply image message.
+
+func (w responseWriter) ReplyMusic(m *Music)
+    ReplyMusic used to reply music message
+
+func (w responseWriter) ReplyNews(articles []Article)
+    ReplyNews used to reply news message (max 10 news)
+
+func (w responseWriter) ReplyOK()
+    ReplyOK used to reply empty message.
+
+func (w responseWriter) ReplyText(text string)
+    ReplyText used to reply text message.
+
+func (w responseWriter) ReplyVideo(mediaID string, title string, description string)
+    ReplyVideo used to reply video message
+
+func (w responseWriter) ReplyVoice(mediaID string)
+    ReplyVoice used to reply voice message.
+
+func (w responseWriter) TransferCustomerService(serviceID string)
+    TransferCustomerService used to tTransfer customer service
+
+func (w responseWriter) UploadMedia(mediaType string, filename string, reader io.Reader) (string, error)
+    Upload media with reader
+
+func (w responseWriter) UploadMediaFromFile(mediaType string, filepath string) (string, error)
+    Upload media from local file
+
+func (w responseWriter) replyHeader() string
+    Format reply message header.
+
+func (w responseWriter) replyMsg(msg string)
+
+type route struct {
+	regex   *regexp.Regexp
+	handler HandlerFunc
+}
+
+```