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 = "" + "" + content + "" + "" + signature + "" + "" + strTimestamp + "" + "" + strNonce + "" + "" 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 ` %d ` } //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 ` %d ` } 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 ` %d ` } 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 ` %d ` } func buildSampleMusicMsg(ToUserName string) (msg string) { thumbID := "AxEDlSNwJcs_0KnyiGnpAYiB1-sjITosWkU3VFsj62KuCyTQO-Fh1UH8d-pBmY1K" thumbID = "JZoNKZr9gzaI5ELBnFUljujiBfIwr4CtXHkZtQMjm-sLVD5PGOU_uvsaF3oNNFjp" 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/" msg = buildMusicMsg(ToUserName, thumbID, "音乐标杆出", "fkd;ajf;daf说明动卡及另附;dasjfsda", 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 ` %d <![CDATA[%s]]> ` } 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 := ` <![CDATA[%s]]> ` article = fmt.Sprintf(template, item.title, item.description, item.picURL, item.url) return article } func newsMsgTemplate() string { return ` %d %d %s ` } func buildLocationMsg() string { template := ` 1494124221 23.134521 113.358803 20 ` return template }