|
- 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
- }
-
- //BuildLocationMsg doesn't work for build location message
- func BuildLocationMsg(long, lat, precision float64, ToUserName string) (xml string) {
- msg := buildLocationMsg()
- 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>`
- }
-
- //upload image to media as temp data, get mediaid and send it out
- func buildUploadPicMsg(ToUserName, path string) (msg string) {
-
- mediaID := uploadImage(path)
- msg = buildPicMsg(ToUserName, mediaID)
- return
- }
-
- 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 buildUploadVoiceMsg(ToUserName, path string) (msg string) {
- mediaID := uploadVoice(path)
- log.Println("get media id " + mediaID)
- msg = buildVoiceMsg(ToUserName, mediaID)
- return
- }
-
- 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 buildSampleMusicMsg(ToUserName string) (msg string) {
- thumbID := "AxEDlSNwJcs_0KnyiGnpAYiB1-sjITosWkU3VFsj62KuCyTQO-Fh1UH8d-pBmY1K"
- thumbID = "JZoNKZr9gzaI5ELBnFUljujiBfIwr4CtXHkZtQMjm-sLVD5PGOU_uvsaF3oNNFjp"
- thumbID = "5dlAsVZ8znWBuGLTjAFM8mIqapHiI0Cmazsvx4TmbsQXZk73RZz8AVnbZp6oSJZn" //jpg 200x200
- thumbID = "e2iNEiSxCX5TV1WbFd0TQJsw84YtISnam2Q_qEXDdT4" //永久素材的 ID
- url := "http://www.youtubeinmp3.com/download/get/?i=vNIuJKoAE46uz2RggRaKGFqQUVAqd0Td&e=92&progressType=button&color=008000"
- url = "http://agobe.yt-downloader.org/download.php?id=d7be28d3a1fafa69d7e464edb8186226"
- url = "http://www.sample-videos.com/audio/mp3/india-national-anthem.mp3"
- url = "http://google.com/"
- url = "http://m.creaders.net/travel/2017/05/11/1823175.html"
- url = "https://biukop.com.au/music.mp3" //real mp3
- //url = "http://mp.weixin.qq.com/s/Jo7rmlMZa_iO97eckWIzFg"
- msg = buildMusicMsg(ToUserName, thumbID, "音乐标杆出", "测试音乐缩略土月卡其", url, url)
- return
- }
-
- func buildMusicMsg(ToUserName, ThumbMediaID, title, description, url, hqURL string) (msg string) {
- msg = fmt.Sprintf(musicMsgTemplate(),
- ToUserName,
- APIConfig.PublicAccountID,
- int32(time.Now().Unix()),
- title,
- description,
- url,
- hqURL,
- ThumbMediaID)
- return
- }
- func musicMsgTemplate() string {
- return `<xml>
- <ToUserName><![CDATA[%s]]></ToUserName>
- <FromUserName><![CDATA[%s]]></FromUserName>
- <CreateTime>%d</CreateTime>
- <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>`
- }
-
- func buildSampleArticleMsg(ToUserName string) (msg string) {
- art := Article{}
- art.title = "bcti"
- art.description = "f;alsfjl;dsajfls;ajfl;sajl;fjdsal;fsdla;\nfjsdal;fjasd;lfdas;\n"
- art.picURL = "http://placehold.it/360x200"
- art.url = "http://doc.biukop.com.au/"
-
- articles := []Article{}
- articles = append(articles, art)
- articles = append(articles, art)
- articles = append(articles, art)
- msg = buildNewsMsg(ToUserName, "标题", "描述", articles)
- return
- }
-
- func buildNewsMsg(ToUserName, title, description string, articles []Article) (msg string) {
- count := 0
- items := []string{}
- for _, a := range articles {
- if count >= 8 {
- err := errors.New("too many articles, only take first 8")
- log.Println(err)
- break
- }
- s := buildArticleItem(a)
- items = append(items, s)
- count++
- }
- 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>`
- }
-
- func buildLocationMsg() string {
- template := `<xml>
- <ToUserName><![CDATA[oUN420bxqFqlx0ZQHciUOesZO3PE]]></ToUserName>
- <FromUserName><![CDATA[gh_f09231355c68]]></FromUserName>
- <CreateTime>1494124221</CreateTime>
- <MsgType><![CDATA[location]]></MsgType>
- <Location_X>23.134521</Location_X>
- <Location_Y>113.358803</Location_Y>
- <Scale>20</Scale>
- <Label><![CDATA[位置信息]]></Label>
- </xml> `
- return template
- }
|