Files
say-it-backend/main.go
T
2020-11-16 21:52:54 +11:00

126 lines
2.8 KiB
Go

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)
}