| @@ -12,31 +12,36 @@ import ( | |||
| "time" | |||
| ) | |||
| //SaveToPath : where the authtoken json file is stored | |||
| const SaveToPath = "/tmp/wechat_hitxy_token" | |||
| //SaveToPath : where the AuthToken json file is stored | |||
| //const SaveToPath = "/tmp/wechat_hitxy_token" | |||
| type authToken struct { | |||
| //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("/tmp/wechat_hitxy_token") | |||
| t, err := readTokenFromFile(APIConfig.AuthTokenSaveTo) | |||
| if isAuthTokenExpired(t) { | |||
| t, err = renewAuthtoken() | |||
| t, err = renewAuthToken() | |||
| if err != nil { | |||
| return "", err // cannot get token | |||
| } | |||
| } | |||
| WechatAccessToken = t | |||
| return t.AccessToken, nil | |||
| } | |||
| func isAuthTokenExpired(t authToken) bool { | |||
| func isAuthTokenExpired(t AuthToken) bool { | |||
| seconds := fmt.Sprintf("%ds", t.ExpireIn) //7200s | |||
| duration, _ := time.ParseDuration(seconds) | |||
| expire := t.Time.Add(duration) | |||
| @@ -45,13 +50,13 @@ func isAuthTokenExpired(t authToken) bool { | |||
| //save token to perminant storage | |||
| func writeTokenToFile(body []byte, path string) { | |||
| log.Printf("writing authtoke to %s\r\n", path) | |||
| 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 | |||
| 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) | |||
| @@ -59,26 +64,26 @@ func readTokenFromFile(path string) (authToken, error) { | |||
| } | |||
| //issue web request to get token from wechat | |||
| func renewAuthtoken() (authToken, error) { | |||
| 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} | |||
| r, err := myClient.Get(url) | |||
| if err != nil { | |||
| return authToken{}, err | |||
| return AuthToken{}, err | |||
| } | |||
| defer r.Body.Close() | |||
| var t authToken | |||
| var t AuthToken | |||
| err = json.NewDecoder(r.Body).Decode(&t) | |||
| if err != nil { | |||
| return authToken{}, err | |||
| return AuthToken{}, err | |||
| } | |||
| t.Time = time.Now() | |||
| b, _ := json.Marshal(&t) | |||
| writeTokenToFile(b, SaveToPath) | |||
| writeTokenToFile(b, APIConfig.AuthTokenSaveTo) | |||
| return t, nil | |||
| } | |||