|
- package main
-
- import (
- "crypto/sha1"
- "errors"
- "fmt"
- "log"
- "math/rand"
- "sort"
- "strings"
- "time"
- )
-
- //Article is one item in News Message
- // one such message can contains upto 10 Articles
- type Article struct {
- title, description, picURL, url string
- }
-
- //BuildTextMsg Given a text message send it to wechat client
- func BuildTextMsg(txt string, ToUserName string) (xml string, err error) {
- if txt == "" || ToUserName == "" {
- err = errors.New("Empty text body or Empty destination")
- xml = ""
- return
- }
-
- msg := fmt.Sprintf(txtMsgTemplate(), ToUserName, APIConfig.PublicAccountID, int32(time.Now().Unix()), txt)
- e := Encode(msg)
- xml, _, _, _ = signMsg(e)
- return
- }
-
- func signMsg(content string) (xml string, timestamp int32, nonce int32, signature string) {
- timestamp = int32(time.Now().Unix())
- nonce = rand.Int31()
-
- strTimestamp := fmt.Sprintf("%d", timestamp)
- strNonce := fmt.Sprintf("%d", nonce)
- signature = getSignature(APIConfig.Token, strTimestamp, strNonce, content)
- xml = "<xml>" +
- "<Encrypt>" + content + "</Encrypt>" +
- "<MsgSignature>" + signature + "</MsgSignature>" +
- "<TimeStamp>" + strTimestamp + "</TimeStamp>" +
- "<Nonce>" + strNonce + "</Nonce>" +
- "</xml>"
- return
- }
-
- func getSignature(token string, timestamp string, nonce string, content string) (signature string) {
- strs := []string{token, timestamp, nonce, content}
- sort.Strings(strs)
- s := strings.Join(strs, "")
- h := sha1.New()
- h.Write([]byte(s))
- signature = fmt.Sprintf("%x", h.Sum(nil))
- return
- }
-
- func buildTxtMsg(ToUserName, content string) (msg string) {
- msg = fmt.Sprintf(txtMsgTemplate(), ToUserName, APIConfig.PublicAccountID, int32(time.Now().Unix()), content)
- return
- }
- func txtMsgTemplate() string {
- return `<xml>
- <ToUserName><![CDATA[%s]]></ToUserName>
- <FromUserName><![CDATA[%s]]></FromUserName>
- <CreateTime>%d</CreateTime>
- <MsgType><![CDATA[text]]></MsgType>
- <Content><![CDATA[%s]]></Content>
- </xml>`
- }
-
- func buildPicMsg(ToUserName, mediaID string) (msg string) {
- msg = fmt.Sprintf(picMsgTemplate(), ToUserName, APIConfig.PublicAccountID, int32(time.Now().Unix()), mediaID)
- return
- }
- func picMsgTemplate() string {
- return `<xml>
- <ToUserName><![CDATA[%s]]></ToUserName>
- <FromUserName><![CDATA[%s]]></FromUserName>
- <CreateTime>%d</CreateTime>
- <MsgType><![CDATA[image]]></MsgType>
- <Image>
- <MediaId><![CDATA[%s]]></MediaId>
- </Image>
- </xml>`
- }
-
- func buildVoiceMsg(ToUserName, mediaID string) (msg string) {
- msg = fmt.Sprintf(voiceMsgTemplate(), ToUserName, APIConfig.PublicAccountID, int32(time.Now().Unix()), mediaID)
- return
- }
- func voiceMsgTemplate() string {
- return `<xml>
- <ToUserName><![CDATA[%s]]></ToUserName>
- <FromUserName><![CDATA[%s]]></FromUserName>
- <CreateTime>%d</CreateTime>
- <MsgType><![CDATA[voice]]></MsgType>
- <Voice>
- <MediaId><![CDATA[%s]]></MediaId>
- </Voice>
- </xml>`
- }
-
- func buildVideoMsg(ToUserName, mediaID, title, description string) (msg string) {
- msg = fmt.Sprintf(videoMsgTemplate(), ToUserName, APIConfig.PublicAccountID, int32(time.Now().Unix()), mediaID, title, description)
- return
- }
- func videoMsgTemplate() string {
- return `<xml>
- <ToUserName><![CDATA[%s]]></ToUserName>
- <FromUserName><![CDATA[%s]]></FromUserName>
- <CreateTime>%d</CreateTime>
- <MsgType><![CDATA[video]]></MsgType>
- <Video>
- <MediaId><![CDATA[%s]]></MediaId>
- <Title><![CDATA[%s]]></Title>
- <Description><![CDATA[%s]]></Description>
- </Video>
- </xml>`
- }
-
- func bulidMusicMsg(ToUserName, mediaID, title, description, url, hqURL string) (msg string) {
- msg = fmt.Sprintf(musicMsgTemplate(),
- ToUserName,
- APIConfig.PublicAccountID,
- int32(time.Now().Unix()),
- title,
- description,
- url,
- hqURL,
- mediaID)
- return
- }
- func musicMsgTemplate() string {
- return `<xml>
- <ToUserName><![CDATA[toUser]]></ToUserName>
- <FromUserName><![CDATA[fromUser]]></FromUserName>
- <CreateTime>12345678</CreateTime>
- <MsgType><![CDATA[music]]></MsgType>
- <Music>
- <Title><![CDATA[TITLE]]></Title>
- <Description><![CDATA[DESCRIPTION]]></Description>
- <MusicUrl><![CDATA[MUSIC_Url]]></MusicUrl>
- <HQMusicUrl><![CDATA[HQ_MUSIC_Url]]></HQMusicUrl>
- <ThumbMediaId><![CDATA[media_id]]></ThumbMediaId>
- </Music>
- </xml>`
- }
-
- func buildNewsMsg(ToUserName, title, description string, articles []Article) (msg string) {
- count := len(articles)
- if count <= 0 {
- log.Fatal("using empty article to build NewsMsg")
- msg = ""
- return
- }
-
- items := []string{}
- for _, a := range articles {
- s := buildArticleItem(a)
- items = append(items, s)
- }
- strItems := strings.Join(items, "")
-
- msg = fmt.Sprintf(newsMsgTemplate(),
- ToUserName,
- APIConfig.PublicAccountID,
- int32(time.Now().Unix()),
- count,
- strItems)
- return
- }
-
- func buildArticleItem(item Article) (article string) {
- template := `<item>
- <Title><![CDATA[%s]]></Title>
- <Description><![CDATA[%s]]></Description>
- <PicUrl><![CDATA[%s]]></PicUrl>
- <Url><![CDATA[%s]]></Url>
- </item>
- `
- article = fmt.Sprintf(template,
- item.title, item.description, item.picURL, item.url)
- return article
- }
-
- func newsMsgTemplate() string {
- return `<xml>
- <ToUserName><![CDATA[%s]]></ToUserName>
- <FromUserName><![CDATA[%s]]></FromUserName>
- <CreateTime>%d</CreateTime>
- <MsgType><![CDATA[news]]></MsgType>
- <ArticleCount>%d</ArticleCount>
- <Articles>
- %s
- </Articles>
- </xml>`
- }
|