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" intent := "intent:#Intent;action=android.intent.action.oppopush;launchFlags=0x14000000;component=uni.UNIEDF0B5C/io.dcloud.PandoraEntry;S.UP-OL-SU=true;S.title="+title+";S.content="+msg+";S.payload=test;end" 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": "intent", "intent": intent, }, }, "push_channel": map[string]map[string]map[string]map[string]string { "android": { "ups": { "notification": { "title": title, "body": msg, "click_type": "intent", "intent": intent, }, }, }, }, } 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失败") }