package service
|
|
import (
|
"car-service/extend/util"
|
"encoding/json"
|
"errors"
|
"fmt"
|
"github.com/astaxie/beego"
|
"sync"
|
"time"
|
)
|
var latestToken *TokenResult
|
var lock sync.RWMutex
|
func getCacheToken() string {
|
lock.Lock()
|
defer lock.Unlock()
|
if latestToken != nil {
|
return latestToken.Token
|
}
|
return ""
|
}
|
func updateToken(newT *TokenResult) {
|
lock.Lock()
|
defer lock.Unlock()
|
latestToken = newT
|
}
|
|
func init() {
|
newToken, err := RefreshToken()
|
if err == nil {
|
updateToken(newToken)
|
}
|
ticker := time.NewTicker(time.Hour * 20)
|
go func() {
|
for {
|
select {
|
case <-ticker.C:
|
if t,err := RefreshToken();err == nil {
|
updateToken(t)
|
}
|
default:
|
time.Sleep(time.Second * 5)
|
}
|
}
|
}()
|
}
|
|
type PushResult struct {
|
Code int `json:"code"`
|
Msg string `json:"msg"`
|
Data interface{} `json:"data"`
|
}
|
|
type TokenResult struct {
|
ExpireTime string `json:"expire_time"`
|
Token string `json:"token"`
|
}
|
|
func Push(title string, msg string) (bool,error) {
|
appId := beego.AppConfig.String("pushAppId")
|
baseUrl := beego.AppConfig.String("pushBaseUrl") + appId
|
retryTimes := 0
|
ReTry:
|
token := getCacheToken()
|
if token == "" {
|
return false, errors.New("token is nil")
|
}
|
url := baseUrl+"/push/all"
|
reqBody := map[string]interface{} {
|
"request_id": time.Now().Format("20060102150405") + util.GenValidateCode(6),
|
"settings":map[string]int {
|
"ttl": 8 * 3600 * 1000,
|
},
|
"audience": "all",
|
"push_message": map[string]map[string]string {
|
"notification": {
|
"title": title,
|
"body": msg,
|
"click_type": "url",
|
"url": "http://baidu.com",
|
},
|
},
|
"push_channel": map[string]map[string]map[string]map[string]string {
|
"android": {
|
"ups": {
|
"notification": {
|
"title": title,
|
"body": msg,
|
"click_type": "url",
|
"url": "http://baidu.com",
|
},
|
},
|
},
|
},
|
}
|
header := map[string]string {
|
"token": token,
|
}
|
b, err := util.DoPostRequest(url, util.CONTENT_TYPE_UTF8_JSON, reqBody, nil, header)
|
if err !=nil {
|
fmt.Println("DoPost err:", err)
|
return false, err
|
}
|
var result PushResult
|
err = json.Unmarshal(b, &result)
|
if err != nil {
|
fmt.Println("unmarshal err:", err)
|
return false, err
|
}
|
if result.Code == 0 {
|
return true, nil
|
} else if result.Code == 10001 { //token过期
|
if retryTimes <=3 {
|
newToken, err := RefreshToken()
|
if err == nil {
|
updateToken(newToken)
|
retryTimes++
|
goto ReTry
|
}
|
}
|
} else {
|
fmt.Println("推送结果:", result)
|
}
|
|
return false, errors.New("推送失败")
|
}
|
|
func RefreshToken() (*TokenResult,error) {
|
appId := beego.AppConfig.String("pushAppId")
|
appKey := beego.AppConfig.String("pushAppKey")
|
masterSecret := beego.AppConfig.String("pushMasterSecret")
|
baseUrl := beego.AppConfig.String("pushBaseUrl") + appId
|
url := baseUrl +"/auth"
|
timestamp := fmt.Sprintf("%v", time.Now().UnixNano() / 1e6)
|
sign := util.Sha256(appKey + timestamp + masterSecret)
|
reqBody := map[string]interface{} {
|
"sign": sign,
|
"timestamp": timestamp,
|
"appkey": appKey,
|
}
|
b, err := util.DoPostRequest(url, util.CONTENT_TYPE_UTF8_JSON, reqBody, nil, nil)
|
if err !=nil {
|
fmt.Println("DoPost err:", err)
|
return nil, err
|
}
|
var result PushResult
|
err = json.Unmarshal(b, &result)
|
if err != nil {
|
fmt.Println("unmarshal err:", err)
|
return nil, err
|
}
|
if result.Code == 0 {
|
db, err := json.Marshal(result.Data)
|
if err != nil {
|
fmt.Println("marshal err:", err)
|
return nil, err
|
}
|
var t TokenResult
|
err = json.Unmarshal(db, &t)
|
if err != nil {
|
fmt.Println("unmarshal err:", err)
|
return nil, err
|
}
|
return &t, nil
|
}
|
return nil, errors.New("获取unipush平台token失败")
|
}
|