| package main | |||||
| import ( | |||||
| "os" | |||||
| ) | |||||
| func getFileSize(s string) (size int64, err error) { | |||||
| f, err := os.Open(s) | |||||
| if err != nil { | |||||
| size = 0 | |||||
| return | |||||
| } | |||||
| fi, err := f.Stat() | |||||
| if err == nil { | |||||
| size = fi.Size() | |||||
| } else { | |||||
| size = 0 | |||||
| } | |||||
| return | |||||
| } |
| package main | |||||
| import ( | |||||
| "encoding/json" | |||||
| "fmt" | |||||
| ) | |||||
| //MediaID : json response for uploading media | |||||
| type MediaID struct { | |||||
| Type string `json:"type"` | |||||
| MediaID string `json:"media_id"` | |||||
| CreateAt int64 `json:"created_at"` | |||||
| } | |||||
| func uploadImage(filename string) (mediaid string) { | |||||
| url, _ := getPostImageURL() | |||||
| jstr, _ := postFileForm(filename, url, "media") | |||||
| //{"type":"TYPE","media_id":"MEDIA_ID","created_at":123456789} | |||||
| var m = MediaID{} | |||||
| json.Unmarshal([]byte(jstr), &m) | |||||
| return | |||||
| } | |||||
| func checkImageSanity() bool { | |||||
| //check file size should < 2M | |||||
| fmt.Println(" should check image file size") | |||||
| return true | |||||
| } | |||||
| func getPostImageURL() (url string, err error) { | |||||
| return getMediaPostURL("image") | |||||
| } | |||||
| func getPostVoiceURL() (url string, err error) { | |||||
| return getMediaPostURL("voice") | |||||
| } | |||||
| func getPostVideoURL() (url string, err error) { | |||||
| return getMediaPostURL("video") | |||||
| } | |||||
| func getPostThumbURL() (url string, err error) { | |||||
| return getMediaPostURL("thumb") | |||||
| } | |||||
| func getMediaPostURL(t string) (url string, err error) { | |||||
| atk, err := GetAccessToken() | |||||
| if err != nil { | |||||
| url = "" | |||||
| } else { | |||||
| url = fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=%s", atk, t) | |||||
| } | |||||
| return | |||||
| } |
| return | 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) { | func signMsg(content string) (xml string, timestamp int32, nonce int32, signature string) { | ||||
| timestamp = int32(time.Now().Unix()) | timestamp = int32(time.Now().Unix()) | ||||
| nonce = rand.Int31() | nonce = rand.Int31() | ||||
| </Articles> | </Articles> | ||||
| </xml>` | </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 | |||||
| } |
| } | } | ||||
| if h.MsgType == "event" { | if h.MsgType == "event" { | ||||
| a := ReadEventMsg(d) | a := ReadEventMsg(d) | ||||
| reply, _ = BuildTextMsg(a.Event+"/"+a.EventKey, h.FromUserName) | |||||
| if a.Event == "LOCATION" { | |||||
| reply = BuildLocationMsg(0, 0, 0, h.FromUserName) | |||||
| fmt.Printf("output %s", reply) | |||||
| } else { | |||||
| reply, _ = BuildTextMsg(a.Event+"/"+a.EventKey, h.FromUserName) | |||||
| } | |||||
| } | } | ||||
| w.Header().Set("Content-Type", "text/xml; charset=utf-8") | w.Header().Set("Content-Type", "text/xml; charset=utf-8") | ||||
| fmt.Fprint(w, reply) | fmt.Fprint(w, reply) |
| package main | |||||
| import ( | |||||
| "bytes" | |||||
| "fmt" | |||||
| "io" | |||||
| "io/ioutil" | |||||
| "mime/multipart" | |||||
| "net/http" | |||||
| "os" | |||||
| ) | |||||
| //post a file to a url | |||||
| func postFileForm(filename string, targetURL string, formFieldName string) (strJSON string, err error) { | |||||
| bodyBuf := &bytes.Buffer{} | |||||
| bodyWriter := multipart.NewWriter(bodyBuf) | |||||
| // this step is very important | |||||
| fileWriter, err := bodyWriter.CreateFormFile(formFieldName, filename) | |||||
| if err != nil { | |||||
| fmt.Println(err) | |||||
| return "", err | |||||
| } | |||||
| // open file handle | |||||
| fh, err := os.Open(filename) | |||||
| if err != nil { | |||||
| fmt.Println(err) | |||||
| return "", err | |||||
| } | |||||
| //iocopy | |||||
| _, err = io.Copy(fileWriter, fh) | |||||
| if err != nil { | |||||
| return "", err | |||||
| } | |||||
| contentType := bodyWriter.FormDataContentType() | |||||
| bodyWriter.Close() | |||||
| resp, err := http.Post(targetURL, contentType, bodyBuf) | |||||
| if err != nil { | |||||
| return "", err | |||||
| } | |||||
| defer resp.Body.Close() | |||||
| r, err := ioutil.ReadAll(resp.Body) | |||||
| strJSON = string(r) | |||||
| if err != nil { | |||||
| return "", err | |||||
| } | |||||
| fmt.Println(resp.Status) | |||||
| fmt.Println(string(strJSON)) | |||||
| return strJSON, nil | |||||
| } |
| package main | |||||
| import ( | |||||
| "fmt" | |||||
| "testing" | |||||
| ) | |||||
| func TestUploadImage(t *testing.T) { | |||||
| SetupConfig() | |||||
| mediaID := uploadImage("media_for_test/640x480.jpg") | |||||
| fmt.Printf("get MediaID: %s ", mediaID) | |||||
| } |
| {"access_token":"XAdcyDrlCjqXUsaaK90JVatDMHQ6O23QILWmeIfLMHz2dwSfz9nrnhP0uRsFJQ0V3tKiINDqiVv1_3Z8votOLqIdg760ZWjQSnmQUk9u_Rl2YaMxzHYetLm7Upgi8A1SRYRjAFABIB","expires_in":7200,"created_at":"2017-05-05T16:03:55.521390518+10:00"} | |||||
| {"access_token":"-6lyvdFk4jKGE1H0UZBPAzHXz793OXyuXmbjqtdWC0TXFY8KmSUwcL_2dRYYi6k0kp2HwMukFVTKnd1PvfoZrrAjM6dXegRGf1wKQpvobx7C-Zdf-1REcM_BvO9GBJkgQNKeAGAAXU","expires_in":7200,"created_at":"2017-05-07T17:02:29.012072846+10:00"} |