|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- package wechat
-
- import (
- "bytes"
- "encoding/binary"
- "encoding/xml"
- "errors"
- "strconv"
- "time"
- )
-
- var EventTicket = "component_verify_ticket" //ticket推送
- var EventUnauthorized = "unauthorized" //取消授权
- var EventUpdateAuthorized = "updateauthorized" //更新授权
- var EventAuthorized = "authorized" //授权成功
-
- var MsgTypeText = "text" //文本消息
- var MsgTypeImage = "image" //文本消息
- var MsgTypeVoice = "voice" //语音消息
- var MsgTypeVideo = "Video" //视频消息
- var MsgTypeMusic = "music" //音乐消息
- var MsgTypeNews = "news" //图文消息
-
- // EventMessageBody 事件推送
- type EventMessageBody struct {
- XMLName xml.Name `xml:"xml"`
- AppId string `xml:"AppId" json:"app_id"`
- CreateTime int `xml:"CreateTime" json:"create_time"`
- InfoType string `xml:"InfoType" json:"info_type"`
- ComponentVerifyTicket string `xml:"ComponentVerifyTicket" json:"component_verify_ticket"`
- AuthorizerAppid string `xml:"AuthorizerAppid" json:"authorizer_appid"`
- AuthorizationCode string `xml:"AuthorizationCode" json:"authorization_code"`
- AuthorizationCodeExpiredTime string `xml:"AuthorizationCodeExpiredTime" json:"authorization_code_expired_time"`
- PreAuthCode string `xml:"PreAuthCode" json:"pre_auth_code"`
- }
-
- // MessageBodyDecrypt 消息体
- type MessageBodyDecrypt struct {
- XMLName xml.Name `xml:"xml"`
- ToUserName string `xml:"ToUserName"`
- FromUserName string `xml:"FromUserName"`
- CreateTime string `xml:"CreateTime"`
- MsgType string `xml:"MsgType"`
- Url string `xml:"Url"`
- PicUrl string `xml:"PicUrl"`
- MediaId string `xml:"MediaId"`
- ThumbMediaId string `xml:"ThumbMediaId"`
- Content string `xml:"Content"`
- MsgId int `xml:"MsgId"`
- Location_X string `xml:"Location_x"`
- Location_Y string `xml:"Location_y"`
- Label string `xml:"Label"`
- }
-
- type MessageEncryptBody struct {
- XMLName xml.Name `xml:"xml"`
- Encrypt CDATA `xml:"Encrypt"`
- MsgSignature CDATA `xml:"MsgSignature"`
- TimeStamp string `xml:"TimeStamp"`
- Nonce CDATA `xml:"Nonce"`
- }
-
- type MessageText struct {
- XMLName xml.Name `xml:"xml"`
- ToUserName CDATA `xml:"ToUserName"`
- FromUserName CDATA `xml:"FromUserName"`
- CreateTime string `xml:"CreateTime"`
- MsgType CDATA `xml:"MsgType"`
- Content CDATA `xml:"Content"`
- }
-
- type MessageImage struct {
- XMLName xml.Name `xml:"xml"`
- ToUserName CDATA `xml:"ToUserName"`
- FromUserName CDATA `xml:"FromUserName"`
- CreateTime string `xml:"CreateTime"`
- MsgType CDATA `xml:"MsgType"`
- Image Media `xml:"Image"`
- }
-
- type MessageVoice struct {
- XMLName xml.Name `xml:"xml"`
- ToUserName CDATA `xml:"ToUserName"`
- FromUserName CDATA `xml:"FromUserName"`
- CreateTime string `xml:"CreateTime"`
- MsgType CDATA `xml:"MsgType"`
- Voice Media `xml:"Voice"`
- }
-
- type MessageVideo struct {
- XMLName xml.Name `xml:"xml"`
- ToUserName CDATA `xml:"ToUserName"`
- FromUserName CDATA `xml:"FromUserName"`
- CreateTime string `xml:"CreateTime"`
- MsgType CDATA `xml:"MsgType"`
- Video Video `xml:"Video"`
- }
-
- type MessageMusic struct {
- XMLName xml.Name `xml:"xml"`
- ToUserName CDATA `xml:"ToUserName"`
- FromUserName CDATA `xml:"FromUserName"`
- CreateTime string `xml:"CreateTime"`
- MsgType CDATA `xml:"MsgType"`
- Music Music `xml:"Music"`
- }
-
- type MessageArticle struct {
- XMLName xml.Name `xml:"xml"`
- ToUserName CDATA `xml:"ToUserName"`
- FromUserName CDATA `xml:"FromUserName"`
- CreateTime string `xml:"CreateTime"`
- MsgType CDATA `xml:"MsgType"`
- ArticleCount string `xml:"ArticleCount"`
- Articles []ArticleItem `xml:"Articles"`
- }
-
- type CDATA struct {
- Text string `xml:",innerxml"`
- }
-
- type Media struct {
- MediaId CDATA `xml:"MediaId"`
- }
-
- type Video struct {
- MediaId CDATA `xml:"MediaId"`
- Title CDATA `xml:"Title"`
- Description CDATA `xml:"Description"`
- }
-
- type Music struct {
- Title CDATA `xml:"Title"`
- Description CDATA `xml:"Description"`
- MusicUrl CDATA `xml:"MusicUrl"`
- HQMusicUrl CDATA `xml:"HQMusicUrl"`
- ThumbMediaId CDATA `xml:"ThumbMediaId"`
- }
-
- type ArticleItem struct {
- Title CDATA `xml:"Title"`
- Description CDATA `xml:"Description"`
- PicUrl CDATA `xml:"PicUrl"`
- Url CDATA `xml:"Url"`
- }
-
- func FormatMessage(plainText []byte, data interface{}) (*interface{}, error) {
- length := GetMessageLength(plainText)
- err := xml.Unmarshal(plainText[20:20+length], data)
- if err != nil {
- return nil, errors.New("格式化消息失败:format message error")
- }
- return &data, nil
- }
-
- func GetMessageLength(plainText []byte) int32 {
- // Read length
- buf := bytes.NewBuffer(plainText[16:20])
- var length int32
- err := binary.Read(buf, binary.BigEndian, &length)
- if err != nil {
- panic("获取消息长度失败:read message length error")
- }
- return length
- }
-
- func ValueToCDATA(content string) CDATA {
- return CDATA{"<![CDATA[" + content + "]]>"}
- }
-
- // FormatTextMessage 格式化文本消息
- func FormatTextMessage(fromUserName string, toUserName string, content string) []byte {
- timestamp := strconv.Itoa(int(time.Now().Unix()))
- textMessage := MessageText{FromUserName: ValueToCDATA(fromUserName), ToUserName: ValueToCDATA(toUserName), Content: ValueToCDATA(content), CreateTime: timestamp, MsgType: ValueToCDATA(MsgTypeText)}
- messageBytes, err := xml.MarshalIndent(textMessage, " ", " ")
- if err != nil {
- panic("格式化文本消息失败:xml marsha1 error;" + err.Error())
- }
- return messageBytes
- }
-
- // FormatImageMessage 格式化图片消息
- func FormatImageMessage(fromUserName string, toUserName string, mediaId string) []byte {
- timestamp := strconv.Itoa(int(time.Now().Unix()))
- imageMessage := MessageImage{FromUserName: ValueToCDATA(fromUserName), ToUserName: ValueToCDATA(toUserName), CreateTime: timestamp, MsgType: ValueToCDATA(MsgTypeImage), Image: Media{ValueToCDATA(mediaId)}}
- messageBytes, err := xml.MarshalIndent(imageMessage, " ", " ")
- if err != nil {
- panic("格式化图片消息失败:xml marsha1 error;" + err.Error())
- }
- return messageBytes
- }
-
- // FormatVoiceMessage 格式语音消息
- func FormatVoiceMessage(fromUserName string, toUserName string, mediaId string) []byte {
- timestamp := strconv.Itoa(int(time.Now().Unix()))
- voiceMessage := MessageVoice{FromUserName: ValueToCDATA(fromUserName), ToUserName: ValueToCDATA(toUserName), CreateTime: timestamp, MsgType: ValueToCDATA(MsgTypeVoice), Voice: Media{ValueToCDATA(mediaId)}}
- messageBytes, err := xml.MarshalIndent(voiceMessage, " ", " ")
- if err != nil {
- panic("格式化语音消息失败:xml marsha1 error;" + err.Error())
- }
- return messageBytes
- }
-
- // FormatVideoMessage 格式化视频消息
- func FormatVideoMessage(fromUserName string, toUserName string, mediaId string, title string, description string) []byte {
- timestamp := strconv.Itoa(int(time.Now().Unix()))
- videoMessage := MessageVideo{FromUserName: ValueToCDATA(fromUserName), ToUserName: ValueToCDATA(toUserName), CreateTime: timestamp, MsgType: ValueToCDATA(MsgTypeVideo), Video: Video{
- MediaId: ValueToCDATA(mediaId),
- Title: ValueToCDATA(title),
- Description: ValueToCDATA(description),
- }}
- messageBytes, err := xml.MarshalIndent(videoMessage, " ", " ")
- if err != nil {
- panic("格式化语音消息失败:xml marsha1 error;" + err.Error())
- }
- return messageBytes
- }
-
- // FormatMusicMessage 格式化音乐消息
- func FormatMusicMessage(fromUserName string, toUserName string, thumbMediaId string, title string, description string, musicUrl string, hQMusicUrl string) []byte {
- timestamp := strconv.Itoa(int(time.Now().Unix()))
- musicMessage := MessageMusic{FromUserName: ValueToCDATA(fromUserName), ToUserName: ValueToCDATA(toUserName), CreateTime: timestamp, MsgType: ValueToCDATA(MsgTypeMusic), Music: Music{
- Title: ValueToCDATA(title),
- Description: ValueToCDATA(description),
- MusicUrl: ValueToCDATA(musicUrl),
- HQMusicUrl: ValueToCDATA(hQMusicUrl),
- ThumbMediaId: ValueToCDATA(thumbMediaId),
- }}
- messageBytes, err := xml.MarshalIndent(musicMessage, " ", " ")
- if err != nil {
- panic("格式化音乐消息失败:xml marsha1 error;" + err.Error())
- }
- return messageBytes
- }
-
- // FormatArticlesMessage 格式化音乐消息
- func FormatArticlesMessage(fromUserName string, toUserName string, items []ArticleItem) []byte {
- timestamp := strconv.Itoa(int(time.Now().Unix()))
- articleNum := strconv.Itoa(len(items))
- musicMessage := MessageArticle{FromUserName: ValueToCDATA(fromUserName), ToUserName: ValueToCDATA(toUserName), CreateTime: timestamp, MsgType: ValueToCDATA(MsgTypeNews), Articles: items, ArticleCount: articleNum}
- messageBytes, err := xml.MarshalIndent(musicMessage, " ", " ")
- if err != nil {
- panic("格式化图文消息失败:xml marsha1 error;" + err.Error())
- }
- return messageBytes
- }
-
- // FormatEncryptData 格式化微信加密数据
- func FormatEncryptData(encrypted string, token string) MessageEncryptBody {
- nonce := makeRandomString(16)
- timestamp := strconv.Itoa(int(time.Now().Unix()))
- data := MessageEncryptBody{Encrypt: ValueToCDATA(encrypted), Nonce: ValueToCDATA(nonce), MsgSignature: ValueToCDATA(GetSignature(timestamp, nonce, encrypted, token)), TimeStamp: timestamp}
- return data
- }
|