這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
/* *@author 菠菜君 *@Version 0.2 *@time 2013-10-29 *@golang實現公眾平台API引擎開發模式 *@青島程式員 訂閱號qdprogrammer *@Golang 訂閱號gostock *@關於青島程式員的技術,創業,生活 分享。 *@開源 https://github.com/philsong/ */package mainimport ("crypto/sha1""encoding/xml""fmt""io""io/ioutil""log""net/http""sort""strings""time")const (TOKEN = "gostock"Text = "text"Location = "location"Image = "image"Link = "link"Event = "event"Music = "music"News = "news")type msgBase struct {ToUserName stringFromUserName stringCreateTime time.DurationMsgType stringContent string}type Request struct {XMLName xml.Name `xml:"xml"`msgBase // base structLocation_X, Location_Y float32Scale intLabel stringPicUrl stringMsgId int}type Response struct {XMLName xml.Name `xml:"xml"`msgBaseArticleCount int `xml:",omitempty"`Articles []*item `xml:"Articles>item,omitempty"`FuncFlag int}type item struct {XMLName xml.Name `xml:"item"`Title stringDescription stringPicUrl stringUrl string}func weixinEvent(w http.ResponseWriter, r *http.Request) {if weixinCheckSignature(w, r) == false {fmt.Println("auth failed, attached?")return}fmt.Println("auth success, parse POST")defer r.Body.Close()body, err := ioutil.ReadAll(r.Body)if err != nil {log.Fatal(err)return}fmt.Println(string(body))var wreq *Requestif wreq, err = DecodeRequest(body); err != nil {log.Fatal(err)return}wresp, err := dealwith(wreq)if err != nil {log.Fatal(err)return}data, err := wresp.Encode()if err != nil {fmt.Printf("error:%v\n", err)return}fmt.Println(string(data))fmt.Fprintf(w, string(data))return}func dealwith(req *Request) (resp *Response, err error) {resp = NewResponse()resp.ToUserName = req.FromUserNameresp.FromUserName = req.ToUserNameresp.MsgType = Textif req.MsgType == Event {if req.Content == "subscribe" {resp.Content = "歡迎關注訂閱號qdprogrammer, 分享青島程式員的技術,創業,生活。"return resp, nil}}if req.MsgType == Text {if strings.Trim(strings.ToLower(req.Content), " ") == "help" {resp.Content = "歡迎關注訂閱號qdprogrammer, 分享青島程式員的技術,創業,生活。"return resp, nil}resp.Content = "親,菠菜君已經收到您的訊息, 將儘快回複您."} else if req.MsgType == Image {var a itema.Description = "雅蠛蝶。。。^_^^_^1024你懂的"a.Title = "雅蠛蝶圖文測試"a.PicUrl = "http://static.yaliam.com/gwz.jpg"a.Url = "http://blog.csdn.net/songbohr"resp.MsgType = Newsresp.ArticleCount = 1resp.Articles = append(resp.Articles, &a)resp.FuncFlag = 1} else {resp.Content = "暫時還不支援其他的類型"}return resp, nil}func weixinAuth(w http.ResponseWriter, r *http.Request) {if weixinCheckSignature(w, r) == true {var echostr string = strings.Join(r.Form["echostr"], "")fmt.Fprintf(w, echostr)}}func weixinHandler(w http.ResponseWriter, r *http.Request) {if r.Method == "GET" {fmt.Println("GET begin...")weixinAuth(w, r)fmt.Println("GET END...")} else {fmt.Println("POST begin...")weixinEvent(w, r)fmt.Println("POST END...")}}func main() {http.HandleFunc("/check", weixinHandler)//http.HandleFunc("/", action)port := "80"println("Listening on port ", port, "...")err := http.ListenAndServe(":"+port, nil) //設定監聽的連接埠if err != nil {log.Fatal("ListenAndServe: ", err)}}func str2sha1(data string) string {t := sha1.New()io.WriteString(t, data)return fmt.Sprintf("%x", t.Sum(nil))}func weixinCheckSignature(w http.ResponseWriter, r *http.Request) bool {r.ParseForm()fmt.Println(r.Form)var signature string = strings.Join(r.Form["signature"], "")var timestamp string = strings.Join(r.Form["timestamp"], "")var nonce string = strings.Join(r.Form["nonce"], "")tmps := []string{TOKEN, timestamp, nonce}sort.Strings(tmps)tmpStr := tmps[0] + tmps[1] + tmps[2]tmp := str2sha1(tmpStr)if tmp == signature {return true}return false}func DecodeRequest(data []byte) (req *Request, err error) {req = &Request{}if err = xml.Unmarshal(data, req); err != nil {return}req.CreateTime *= time.Secondreturn}func NewResponse() (resp *Response) {resp = &Response{}resp.CreateTime = time.Duration(time.Now().Unix())return}func (resp Response) Encode() (data []byte, err error) {resp.CreateTime = time.Duration(time.Now().Unix())data, err = xml.Marshal(resp)return}