package main import ( "io/ioutil" "net/http" "os" "time" "net/url" "encoding/json" "github.com/gin-gonic/gin" log "github.com/sirupsen/logrus" ) type Token struct { AccessToken string `json:"access_token"` ExpiresIn int `json:"expires_in"` RefreshToken string `json:"refresh_token"` BaseTime time.Time ExpiresTime time.Time } type ViewToken struct { Token string ExpiresTime int64 } var ( clientId string clientSecret string token *Token ) func init() { loadToken() clientId = os.Getenv("CLIENT_ID") clientSecret = os.Getenv("CLIENT_SECRET") if clientId == "" || clientSecret == "" { log.Fatal("Please set environment variable CLIENT_ID and CLIENT_SECRET") } if shouldFetchToken() { fetchToken() } log.Info("Say-it is ready to go!") } func main() { router := gin.Default() router.GET("/", landing) router.GET("/api/token", fetchTokenHandler) router.Run() } func landing(c *gin.Context) { c.JSON(200, gin.H{"msg": "Hello, I am say-it. Please go to https://github.com/wahyd4/say-it-backend to get more details."}) } func fetchTokenHandler(c *gin.Context) { if time.Now().After(token.ExpiresTime) { log.Info("Token expires, try to refresh one.") fetchToken() } if token != nil { c.JSON(200, ViewToken{Token: token.AccessToken, ExpiresTime: token.ExpiresTime.Unix()}) return } c.JSON(404, gin.H{"message": "No Available Token, please concat the Admin: wahyd4@gmail.com. Thanks!"}) } func fetchToken() { log.Info("Start fetching token") params := url.Values{} params.Add("grant_type", "client_credentials") params.Add("client_id", clientId) params.Add("client_secret", clientSecret) resp, err := http.PostForm("https://openapi.baidu.com/oauth/2.0/token", params) if err != nil { log.Errorln("Fetch Baidu access token failed" + err.Error()) } defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) if resp.Status != "200 OK" { log.Errorln("The response of fetch Baidu access token not success: " + string(body)) return } var t Token err = json.Unmarshal(body, &t) if err != nil { log.Warn("Unmarshal json failed: " + err.Error()) } t.BaseTime = time.Now() t.ExpiresTime = t.BaseTime.Add(time.Second * time.Duration(t.ExpiresIn)) writeToFile(&t) token = &t } func writeToFile(token *Token) { log.Info("Write updated token to file") tokenJSON, _ := json.Marshal(token) ioutil.WriteFile("./token.json", tokenJSON, 0644) } func loadToken() { log.Info("Loading token from local file") tokenString, err := ioutil.ReadFile("./token.json") if err != nil { log.Warn("Load json file failed, maybe there " + err.Error()) return } var t Token json.Unmarshal(tokenString, &t) token = &t } func shouldFetchToken() bool { return token == nil || token.AccessToken == "" || time.Now().After(token.ExpiresTime) }