|
@@ -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
|
|
|
+}
|
|
|
+
|
|
|
+```
|