// // {"access_token":"s0wf65p-KMzvYtH8qPu2qSX_EXLE2NaBgFHl7MZwedc7Kv_hdO0FG1QeUmBYJAGmQqJinPwFr67MRZwJee4rDnGVwhbuIfKs29N4ZJSXFP8fbAheuas08UuRe13UsdCtWSMcAFAGCW","expires_in":7200} // package main import ( "encoding/json" "fmt" "io/ioutil" "log" "net/http" "time" ) //SaveToPath : where the AuthToken json file is stored //const SaveToPath = "/tmp/wechat_hitxy_token" //AuthToken Access Token, for temporary access WechatAPI type AuthToken struct { AccessToken string `json:"access_token"` ExpireIn int64 `json:"expires_in"` Time time.Time `json:"created_at"` } //WechatAccessToken Global AccessToken var WechatAccessToken AuthToken //GetAccessToken returns a valid access_token for wechat_api // the token is auomatically renewed if it's about to expire // if error happens, return empty string and error // if success, return token string and nil func GetAccessToken() (string, error) { t, err := readTokenFromFile(APIConfig.AuthTokenSaveTo) if isAuthTokenExpired(t) { t, err = renewAuthToken() if err != nil { log.Fatal("Cannot renew AccessToken from Wechat Server:") log.Fatal(err) return "", err // cannot get token } } WechatAccessToken = t return t.AccessToken, nil } func isAuthTokenExpired(t AuthToken) bool { seconds := fmt.Sprintf("%ds", t.ExpireIn) //7200s duration, _ := time.ParseDuration(seconds) expire := t.Time.Add(duration) return time.Now().After(expire) } //save token to perminant storage func writeTokenToFile(body []byte, path string) { log.Printf("writing authtoken to %s\r\n", path) ioutil.WriteFile(path, body, 0600) } //read token from permenant storage func readTokenFromFile(path string) (AuthToken, error) { var m AuthToken log.Printf("read authtoke from %s\r\n", path) body, err := ioutil.ReadFile(path) json.Unmarshal(body, &m) return m, err } //issue web request to get token from wechat func renewAuthToken() (AuthToken, error) { //url := "http://vimeo.com/api/v2/brad/info.json" url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", APIConfig.Appid, APIConfig.AppSecret) var myClient = &http.Client{Timeout: 20 * time.Second} log.Println("renew access token from Internet api.weixin.qq.com") r, err := myClient.Get(url) if err != nil { log.Fatal("http access api.weixin.qq.com failed") log.Fatal(err) return AuthToken{}, err } defer r.Body.Close() var t AuthToken err = json.NewDecoder(r.Body).Decode(&t) if err != nil { return AuthToken{}, err } t.Time = time.Now() b, _ := json.Marshal(&t) writeTokenToFile(b, APIConfig.AuthTokenSaveTo) return t, nil } // //debugged http response // func dummy() { // var body []byte // var response *http.Response // var request *http.Request // url := "http://vimeo.com/api/v2/brad/info.json" // request, err := http.NewRequest("GET", url, nil) // if err == nil { // request.Header.Add("Content-Type", "application/json") // //debug(httputil.DumpRequestOut(request, true)) // response, err = (&http.Client{}).Do(request) // } // if err == nil { // defer response.Body.Close() // //debug(httputil.DumpResponse(response, true)) // body, err = ioutil.ReadAll(response.Body) // //json.NewDecoder(response.Body).Decode(m) // } // if err == nil { // writeTokenToFile(body, "/tmp/wechat_hitxy_token") // //m.Time = time.Now() // } else { // log.Fatalf("ERROR: %s", err) // } // }