2024-01-29 22:13:11 +08:00
|
|
|
package push
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
2024-07-12 16:26:05 +08:00
|
|
|
"git.u8t.cn/open/gosdk/util"
|
2024-01-29 22:13:11 +08:00
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
"github.com/smbrave/goutil"
|
|
|
|
"github.com/spf13/cast"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2024-05-09 21:31:47 +08:00
|
|
|
var (
|
2024-05-10 11:33:50 +08:00
|
|
|
ErrCidNotExist = errors.New("cid not exist")
|
2024-05-09 21:31:47 +08:00
|
|
|
)
|
|
|
|
|
2024-01-29 22:13:11 +08:00
|
|
|
type GetuiConfig struct {
|
|
|
|
AppId string
|
|
|
|
AppKey string
|
|
|
|
MasterSecret string
|
2024-03-04 11:48:28 +08:00
|
|
|
XMChannelId string
|
2024-01-29 22:13:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
type GetuiStatus struct {
|
|
|
|
Status string
|
|
|
|
LastLoginTime int64
|
|
|
|
}
|
|
|
|
|
|
|
|
type GetuiDetail struct {
|
|
|
|
ClientAppId string
|
|
|
|
PackageName string
|
|
|
|
DeviceToken string
|
|
|
|
PhoneType int
|
|
|
|
PhoneModel string
|
|
|
|
NotificationSwitch bool
|
|
|
|
CreateTime int64
|
|
|
|
LoginFreq int
|
|
|
|
Brand string
|
|
|
|
}
|
|
|
|
|
|
|
|
type GetuiMessage struct {
|
2024-02-29 21:00:48 +08:00
|
|
|
Cid string
|
2024-05-21 16:41:48 +08:00
|
|
|
Title string //通知消息标题,长度 ≤ 50字
|
|
|
|
Message string //通知消息内容,长度 ≤ 256字
|
2024-02-29 21:00:48 +08:00
|
|
|
NotifyId string
|
2024-03-01 11:41:45 +08:00
|
|
|
Intent string
|
2024-01-29 22:13:11 +08:00
|
|
|
}
|
|
|
|
|
2024-03-04 10:57:37 +08:00
|
|
|
type GetuiPushRsp struct {
|
2024-03-04 12:06:36 +08:00
|
|
|
TaskId string `json:"task_id"`
|
|
|
|
Status string `json:"status"`
|
2024-03-04 10:57:37 +08:00
|
|
|
}
|
|
|
|
|
2024-01-29 22:13:11 +08:00
|
|
|
type Getui struct {
|
|
|
|
config *GetuiConfig
|
|
|
|
token string
|
|
|
|
tokenExpire int64
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewGetui(c *GetuiConfig) *Getui {
|
|
|
|
return &Getui{
|
|
|
|
config: c,
|
|
|
|
tokenExpire: 0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *Getui) getResult(rspBody []byte) (map[string]interface{}, error) {
|
|
|
|
result := make(map[string]interface{})
|
|
|
|
if err := json.Unmarshal(rspBody, &result); err != nil {
|
|
|
|
log.Errorf("json[%s] error :%s", string(rspBody), err.Error())
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
code := cast.ToInt(result["code"])
|
2024-06-25 19:19:10 +08:00
|
|
|
msg := cast.ToString(result["msg"])
|
|
|
|
data := cast.ToStringMap(result["data"])
|
|
|
|
|
|
|
|
if code == 20001 && msg == "successed_ignore" {
|
|
|
|
return data, nil
|
|
|
|
}
|
|
|
|
|
2024-01-29 22:13:11 +08:00
|
|
|
if code != 0 {
|
|
|
|
log.Errorf("json[%s] rsp error", string(rspBody))
|
|
|
|
return nil, errors.New(string(rspBody))
|
|
|
|
}
|
|
|
|
return data, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *Getui) Token() string {
|
|
|
|
nowTime := time.Now().Unix()
|
|
|
|
if nowTime < g.tokenExpire {
|
|
|
|
return g.token
|
|
|
|
}
|
|
|
|
|
|
|
|
timestamp := cast.ToString(time.Now().UnixMilli())
|
|
|
|
signStr := fmt.Sprintf("%s%s%s", g.config.AppKey, timestamp, g.config.MasterSecret)
|
|
|
|
reqUrl := fmt.Sprintf("https://restapi.getui.com/v2/%s/auth", g.config.AppId)
|
|
|
|
params := make(map[string]string)
|
|
|
|
params["timestamp"] = timestamp
|
|
|
|
params["appkey"] = g.config.AppKey
|
|
|
|
params["sign"] = util.Sha256(signStr)
|
|
|
|
reqBody, _ := json.Marshal(params)
|
2024-06-25 16:50:22 +08:00
|
|
|
rspBody, err := HttpPostJson(reqUrl, nil, reqBody)
|
2024-01-29 22:13:11 +08:00
|
|
|
if err != nil {
|
2024-05-09 21:31:47 +08:00
|
|
|
log.Errorf("http post [%s] error :%s", string(reqBody), err.Error())
|
2024-01-29 22:13:11 +08:00
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
result, err := g.getResult(rspBody)
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("get Result error :%s", err.Error())
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
token := cast.ToString(result["token"])
|
|
|
|
tokenExpire := cast.ToInt64(result["expire_time"])
|
|
|
|
g.token = token
|
2024-03-10 21:34:39 +08:00
|
|
|
g.tokenExpire = tokenExpire / 1000
|
2024-01-29 22:13:11 +08:00
|
|
|
return g.token
|
|
|
|
}
|
|
|
|
|
2024-03-04 10:57:37 +08:00
|
|
|
func (g *Getui) Push(req *GetuiMessage) (*GetuiPushRsp, error) {
|
2024-05-21 16:48:45 +08:00
|
|
|
if len(req.Title) > 50 {
|
|
|
|
req.Title = string([]rune(req.Title)[:16])
|
|
|
|
}
|
|
|
|
if len(req.Message) > 256 {
|
|
|
|
req.Message = string([]rune(req.Message)[:80])
|
|
|
|
}
|
2024-01-29 22:13:11 +08:00
|
|
|
reqUrl := fmt.Sprintf("https://restapi.getui.com/v2/%s/push/single/cid", g.config.AppId)
|
|
|
|
|
|
|
|
params := make(map[string]interface{})
|
|
|
|
params["request_id"] = time.Now().Format("20060102150405") + "_" + goutil.RandomStr(6)
|
|
|
|
params["settings"] = map[string]interface{}{
|
|
|
|
"ttl": 2 * 3600 * 24 * 1000,
|
|
|
|
}
|
|
|
|
params["audience"] = map[string]interface{}{
|
|
|
|
"cid": []string{req.Cid},
|
|
|
|
}
|
|
|
|
params["push_message"] = map[string]interface{}{
|
|
|
|
"notification": map[string]interface{}{
|
|
|
|
"title": req.Title,
|
|
|
|
"body": req.Message,
|
|
|
|
"channel_level": 4,
|
2024-03-01 11:41:45 +08:00
|
|
|
"click_type": "intent",
|
2024-02-29 21:00:48 +08:00
|
|
|
"notify_id": cast.ToInt64(req.NotifyId),
|
2024-03-01 11:41:45 +08:00
|
|
|
"intent": req.Intent,
|
2024-01-29 22:13:11 +08:00
|
|
|
},
|
|
|
|
}
|
2024-02-29 19:58:49 +08:00
|
|
|
params["push_channel"] = map[string]interface{}{
|
|
|
|
"android": map[string]interface{}{
|
|
|
|
"ups": map[string]interface{}{
|
|
|
|
"notification": map[string]interface{}{
|
|
|
|
"title": req.Title,
|
|
|
|
"body": req.Message,
|
2024-03-01 11:41:45 +08:00
|
|
|
"click_type": "intent",
|
2024-02-29 21:00:48 +08:00
|
|
|
"notify_id": cast.ToInt64(req.NotifyId),
|
2024-03-01 11:41:45 +08:00
|
|
|
"intent": req.Intent,
|
2024-02-29 19:58:49 +08:00
|
|
|
},
|
2024-03-04 11:48:28 +08:00
|
|
|
"options": map[string]interface{}{
|
|
|
|
"ALL": map[string]interface{}{
|
|
|
|
"channel": "default",
|
|
|
|
},
|
|
|
|
"XM": map[string]interface{}{
|
|
|
|
"/extra.channel_id": g.config.XMChannelId,
|
|
|
|
},
|
2024-03-04 14:19:20 +08:00
|
|
|
"VV": map[string]interface{}{
|
|
|
|
"/category": "ACCOUNT",
|
|
|
|
},
|
2024-03-04 11:48:28 +08:00
|
|
|
},
|
2024-02-29 19:58:49 +08:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
2024-05-09 20:34:55 +08:00
|
|
|
reqBody, err := json.Marshal(params)
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("json.Marshal error :%s", err.Error())
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2024-06-25 16:50:22 +08:00
|
|
|
rspBody, err := HttpPostJson(reqUrl, map[string]string{"token": g.Token()}, reqBody)
|
2024-01-29 22:13:11 +08:00
|
|
|
if err != nil {
|
|
|
|
log.Errorf("goutil http post error :%s", err.Error())
|
2024-03-04 10:57:37 +08:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
data, err := g.getResult(rspBody)
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("get result[%s] error :%s", rspBody, err.Error())
|
|
|
|
return nil, err
|
2024-01-29 22:13:11 +08:00
|
|
|
}
|
|
|
|
|
2024-03-04 10:57:37 +08:00
|
|
|
rsp := new(GetuiPushRsp)
|
|
|
|
for taskId, task := range data {
|
|
|
|
rsp.TaskId = taskId
|
|
|
|
cidStatus := cast.ToStringMap(task)
|
|
|
|
for _, v := range cidStatus {
|
|
|
|
rsp.Status = cast.ToString(v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rsp, nil
|
2024-01-29 22:13:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (g *Getui) GetUserStatus(cid string) (*GetuiStatus, error) {
|
|
|
|
reqUrl := fmt.Sprintf("https://restapi.getui.com/v2/%s/user/status/%s", g.config.AppId, cid)
|
2024-06-25 16:50:22 +08:00
|
|
|
rspBody, err := HttpGet(reqUrl, map[string]string{
|
2024-01-29 22:13:11 +08:00
|
|
|
"token": g.Token(),
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
2024-03-27 18:48:16 +08:00
|
|
|
log.Warningf("goutil http get error :%s", err.Error())
|
2024-01-29 22:13:11 +08:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
result, err := g.getResult(rspBody)
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("get result[%s] error :%s", string(rspBody), err.Error())
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if _, ok := result[cid]; !ok {
|
2024-05-10 11:33:50 +08:00
|
|
|
return nil, ErrCidNotExist
|
2024-01-29 22:13:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
status := new(GetuiStatus)
|
|
|
|
cidResult := cast.ToStringMap(result[cid])
|
|
|
|
status.Status = cast.ToString(cidResult["status"])
|
|
|
|
status.Status = cast.ToString(cidResult["status"])
|
|
|
|
status.LastLoginTime = cast.ToInt64(cidResult["last_login_time"]) / 1000
|
|
|
|
return status, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *Getui) GetUserDetail(cid string) (*GetuiDetail, error) {
|
|
|
|
reqUrl := fmt.Sprintf("https://restapi.getui.com/v2/%s/user/detail/%s", g.config.AppId, cid)
|
2024-06-25 16:50:22 +08:00
|
|
|
rspBody, err := HttpGet(reqUrl, map[string]string{
|
2024-01-29 22:13:11 +08:00
|
|
|
"token": g.Token(),
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("goutil http get error :%s", err.Error())
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
result, err := g.getResult(rspBody)
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("get result[%s] error :%s", string(rspBody), err.Error())
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
validCids := cast.ToStringMap(result["validCids"])
|
|
|
|
if _, ok := validCids[cid]; !ok {
|
2024-05-10 11:33:50 +08:00
|
|
|
return nil, ErrCidNotExist
|
2024-01-29 22:13:11 +08:00
|
|
|
}
|
|
|
|
cidDetail := cast.ToStringMap(validCids[cid])
|
|
|
|
|
|
|
|
detail := new(GetuiDetail)
|
|
|
|
detail.ClientAppId = cast.ToString(cidDetail["client_app_id"])
|
|
|
|
detail.PackageName = cast.ToString(cidDetail["package_name"])
|
|
|
|
detail.DeviceToken = cast.ToString(cidDetail["device_token"])
|
|
|
|
detail.PhoneModel = cast.ToString(cidDetail["phone_model"])
|
|
|
|
detail.Brand = cast.ToString(cidDetail["brand"])
|
|
|
|
detail.PhoneType = cast.ToInt(cidDetail["phone_type"])
|
|
|
|
detail.LoginFreq = cast.ToInt(cidDetail["login_freq"])
|
|
|
|
detail.NotificationSwitch = cast.ToBool(cidDetail["notification_switch"])
|
|
|
|
|
|
|
|
return detail, nil
|
|
|
|
}
|