diff --git a/platformapi/ebaiapi/activity_test.go b/platformapi/ebaiapi/activity_test.go index e5274a90..f794133b 100644 --- a/platformapi/ebaiapi/activity_test.go +++ b/platformapi/ebaiapi/activity_test.go @@ -70,7 +70,7 @@ func TestActivityUpdate(t *testing.T) { } func TestActivityGet(t *testing.T) { - activityInfo, err := api.ActivityGet(3000000000517188, "", testShopBaiduID, 0) + activityInfo, err := api.ActivityGet(0, "", 0, 0) if err != nil { t.Fatal(err) } else { diff --git a/platformapi/mtwmapi/act.go b/platformapi/mtwmapi/act.go index f6b62ff3..b980408a 100644 --- a/platformapi/mtwmapi/act.go +++ b/platformapi/mtwmapi/act.go @@ -529,3 +529,27 @@ func (a *API) InStoreCouponList(poiCode string, pageNum, pageSize int) (couponAc } return couponActList, err } + +type GetByAppPoiCodeAndTypeResult struct { + ActName string `json:"act_name"` + ActType int `json:"act_type"` + ActStatus int `json:"act_status"` + ActCount int `json:"act_count"` + ItemCount int `json:"item_count"` + StartTime int `json:"start_time"` + EndTime int `json:"end_time"` +} + +// 查询门店内活动信息 +// https://developer.waimai.meituan.com/home/docDetail/444 +func (a *API) GetByAppPoiCodeAndType(appPoiCode string, status, actType int) (getByAppPoiCodeAndTypeResult []*GetByAppPoiCodeAndTypeResult, err error) { + result, err := a.AccessAPI("act/all/get/byAppPoiCodeAndType", true, map[string]interface{}{ + KeyAppPoiCode: appPoiCode, + "status": status, + "type": actType, + }) + if err == nil { + err = utils.Map2StructByJson(result, &getByAppPoiCodeAndTypeResult, false) + } + return getByAppPoiCodeAndTypeResult, err +} diff --git a/platformapi/mtwmapi/act_test.go b/platformapi/mtwmapi/act_test.go index 5c3c14af..17dea3e0 100644 --- a/platformapi/mtwmapi/act_test.go +++ b/platformapi/mtwmapi/act_test.go @@ -112,3 +112,11 @@ func TestParseErr4RetailDiscountDelete(t *testing.T) { failedList := ParseErr4RetailDiscountDelete(errExt) t.Log(utils.Format4Output(failedList, false)) } + +func TestGetByAppPoiCodeAndType(t *testing.T) { + result, err := api.GetByAppPoiCodeAndType("9375120", 1, 1) + if err != nil { + t.Fatal(err) + } + t.Log(utils.Format4Output(result, false)) +} diff --git a/platformapi/unipushapi/unipushapi.go b/platformapi/unipushapi/unipushapi.go new file mode 100644 index 00000000..14cf7557 --- /dev/null +++ b/platformapi/unipushapi/unipushapi.go @@ -0,0 +1,222 @@ +package unipushapi + +import ( + "crypto/sha256" + "encoding/hex" + "encoding/json" + "fmt" + "net/http" + "strings" + "sync" + "time" + + "git.rosy.net.cn/baseapi" + "git.rosy.net.cn/baseapi/platformapi" + "git.rosy.net.cn/baseapi/utils" +) + +const ( + prodURL = "https://restapi.getui.com/v2" + + authAction = "auth" + successOffLine = "successed_offline" + successONLine = "successed_online" +) + +type TokenInfo struct { + ExpireTime string `json:"expire_time"` + Token string `json:"token"` +} + +type API struct { + token string + appID string + appKey string + appSecret string + masterSecret string + + client *http.Client + config *platformapi.APIConfig + locker sync.RWMutex +} + +func New(appID, appKey, appSecret, masterSecret string, config ...*platformapi.APIConfig) *API { + curConfig := platformapi.DefAPIConfig + if len(config) > 0 { + curConfig = *config[0] + } + return &API{ + appID: appID, + appKey: appKey, + appSecret: appSecret, + masterSecret: masterSecret, + + client: &http.Client{Timeout: curConfig.ClientTimeout}, + config: &curConfig, + } +} + +func (a *API) signParam(appKey string, time int64, masterSecret string) (sig string) { + //方法一: + //创建一个基于SHA256算法的hash.Hash接口的对象 + hash := sha256.New() + //输入数据 + hash.Write([]byte(appKey + utils.Int64ToStr(time) + masterSecret)) + //计算哈希值 + bytes := hash.Sum(nil) + //将字符串编码为16进制格式,返回字符串 + hashCode := hex.EncodeToString(bytes) + //返回哈希值 + return hashCode +} + +func (a *API) AccessAPI(action string, bizParams map[string]interface{}) (retVal map[string]interface{}, err error) { + params := make(map[string]interface{}) + time := time.Now().UnixNano() / 1e6 + params["timestamp"] = utils.Int64ToStr(time) + params["appkey"] = a.appKey + params["sign"] = a.signParam(a.appKey, time, a.masterSecret) + result, _ := json.MarshalIndent(params, "", " ") + fullURL := utils.GenerateGetURL(prodURL+"/"+a.appID, action, nil) + err = platformapi.AccessPlatformAPIWithRetry(a.client, + func() *http.Request { + request, _ := http.NewRequest(http.MethodPost, fullURL, strings.NewReader(string(result))) + if action != authAction { + request.Header.Set("token", a.CBGetToken()) + } + request.Header.Set("Content-Type", "application/json;charset=utf-8") + return request + }, + a.config, + func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) { + if jsonResult1 == nil { + return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil") + } + if err == nil { + if jsonResult1["msg"].(string) != "success" { + errLevel = platformapi.ErrLevelGeneralFail + err = utils.NewErrorCode(jsonResult1["msg"].(string), utils.Int64ToStr(utils.MustInterface2Int64(jsonResult1["code"]))) + baseapi.SugarLogger.Debugf("unipush AccessAPI failed, jsonResult1:%s", utils.Format4Output(jsonResult1, true)) + } + retVal = jsonResult1["data"].(map[string]interface{}) + } + return errLevel, err + }) + return retVal, err +} + +func (a *API) AccessAPI2(action string, bizParams map[string]interface{}) (retVal map[string]interface{}, err error) { + result, _ := json.MarshalIndent(bizParams, "", " ") + fullURL := utils.GenerateGetURL(prodURL+"/"+a.appID, action, nil) + err = platformapi.AccessPlatformAPIWithRetry(a.client, + func() *http.Request { + request, _ := http.NewRequest(http.MethodPost, fullURL, strings.NewReader(string(result))) + request.Header.Set("token", a.CBGetToken()) + request.Header.Set("Content-Type", "application/json;charset=utf-8") + return request + }, + a.config, + func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) { + if jsonResult1 == nil { + return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil") + } + if err == nil { + if jsonResult1["msg"].(string) != "success" { + errLevel = platformapi.ErrLevelGeneralFail + err = utils.NewErrorCode(jsonResult1["msg"].(string), utils.Int64ToStr(utils.MustInterface2Int64(jsonResult1["code"]))) + baseapi.SugarLogger.Debugf("unipush AccessAPI failed, jsonResult1:%s", utils.Format4Output(jsonResult1, true)) + } + retVal = jsonResult1 + } + return errLevel, err + }) + return retVal, err +} + +func (a *API) CBSetToken(newToken string) bool { + curToken := a.CBGetToken() + if curToken != newToken { + a.locker.Lock() + defer a.locker.Unlock() + a.token = newToken + return true + } + return false +} + +func (a *API) CBGetToken() string { + a.locker.RLock() + defer a.locker.RUnlock() + return a.token +} + +func (a *API) CBRetrieveToken() (tokenInfo *TokenInfo, err error) { + result, err := a.AccessAPI("auth", nil) + if err != nil { + return nil, err + } + tokenInfo = &TokenInfo{ + Token: utils.Interface2String(result["token"]), + ExpireTime: utils.Interface2String(result["expire_time"]), + } + a.CBSetToken(tokenInfo.Token) + return tokenInfo, nil +} + +type PushMsg struct { + Notificatio Notification `json:"notification"` +} + +type Notification struct { + Title string `json:"title"` + Body string `json:"body"` + ClickType string `json:"click_type"` + URL string `json:"url"` +} + +type Audience struct { + CID []string `json:"cid"` +} + +type Settings struct { + TTL int `json:"ttl"` +} + +type Transmission struct { + Transmission string `json:"transmission"` +} + +func (a *API) PushToSingle(cid string, transmission bool, notification *Notification) (status string, err error) { + params := map[string]interface{}{ + "request_id": utils.GetUUID(), + "audience": &Audience{ + []string{cid}, + }, + } + if !transmission { + params["push_message"] = &PushMsg{ + Notificatio: Notification{ + Title: notification.Title, + Body: notification.Body, + ClickType: "startapp", //打开应用首页 + }, + } + } else { + params["push_message"] = &Transmission{ + Transmission: notification.Body, + } + } + result2, err := a.AccessAPI2("push/single/cid", params) + if err != nil { + return "", err + } else { + for _, v := range result2["data"].(map[string]interface{}) { + for _, vv := range v.(map[string]interface{}) { + if vv.(string) != "" { + status = vv.(string) + } + } + } + } + return status, nil +} diff --git a/platformapi/unipushapi/unipushapi_test.go b/platformapi/unipushapi/unipushapi_test.go new file mode 100644 index 00000000..0782f7dc --- /dev/null +++ b/platformapi/unipushapi/unipushapi_test.go @@ -0,0 +1,43 @@ +package unipushapi + +import ( + "testing" + + "git.rosy.net.cn/baseapi" + "git.rosy.net.cn/baseapi/utils" + "go.uber.org/zap" +) + +var ( + api *API + sugarLogger *zap.SugaredLogger +) + +func init() { + logger, _ := zap.NewDevelopment() + sugarLogger = logger.Sugar() + baseapi.Init(sugarLogger) + api = New("5lyyrvHODG6wC8Sdr3a9h", "iFrkUDmR2g5eqQpfh2kQ57", "WTn53qd6WAAdLMXfmXvzb7", "dGZcR0XGGg7H5Pd7FR3n47") + api.CBSetToken("d6b5f133d8dbc7f2890bc500dee848f1ac191a32f2d2fba39b0dcb2e52aa4265") + // ef364b677911fa64d41a25d22d5e155065c4898046be65ddd627fa6c8cd87c2e +} + +func TestCBRetrieveToken(t *testing.T) { + result, err := api.CBRetrieveToken() + if err != nil { + t.Fatal(err.Error()) + } + t.Log(utils.Format4Output(result, false)) +} + +func TestPushToSingle(t *testing.T) { + result, err := api.PushToSingle("4fde99c9bd3d2ab317023f429f9ef62b", true, &Notification{ + Title: "测试", + Body: "测测测", + }) + if err != nil { + t.Fatal(err.Error()) + } + t.Log(utils.Format4Output(result, false)) + // RASS_0911_1517001ff419d4699a0be17ac3f04a54 +}