222 lines
6.9 KiB
Go
222 lines
6.9 KiB
Go
package mtunionapi
|
||
|
||
import (
|
||
"crypto/md5"
|
||
"encoding/json"
|
||
"fmt"
|
||
"net/http"
|
||
"sort"
|
||
"strings"
|
||
|
||
"git.rosy.net.cn/baseapi/platformapi"
|
||
"git.rosy.net.cn/baseapi/utils"
|
||
)
|
||
|
||
const (
|
||
prodURL = "https://runion.meituan.com"
|
||
sigKey = "sign"
|
||
|
||
ActTypeQB = 1 //券包推广
|
||
)
|
||
|
||
type API struct {
|
||
platformapi.APICookie
|
||
|
||
appKey string
|
||
appSecret string
|
||
client *http.Client
|
||
config *platformapi.APIConfig
|
||
}
|
||
|
||
func New(appKey, appSecret string, config ...*platformapi.APIConfig) *API {
|
||
curConfig := platformapi.DefAPIConfig
|
||
if len(config) > 0 {
|
||
curConfig = *config[0]
|
||
}
|
||
return &API{
|
||
appKey: appKey,
|
||
appSecret: appSecret,
|
||
client: &http.Client{Timeout: curConfig.ClientTimeout},
|
||
config: &curConfig,
|
||
}
|
||
}
|
||
|
||
func (a *API) signParam(params map[string]interface{}) (sig string) {
|
||
var valueList []string
|
||
for k, v := range params {
|
||
if k != sigKey {
|
||
if str := fmt.Sprint(v); str != "" {
|
||
valueList = append(valueList, fmt.Sprintf("%s%s", k, str))
|
||
}
|
||
}
|
||
}
|
||
sort.Sort(sort.StringSlice(valueList))
|
||
valueList = append(valueList, fmt.Sprintf("%s", a.appSecret))
|
||
var valueList2 = make([]string, len(valueList)+1)
|
||
at := copy(valueList2, valueList[:0])
|
||
at += copy(valueList2[at:], []string{a.appSecret})
|
||
copy(valueList2[at:], valueList[0:])
|
||
sig = strings.Join(valueList2, "")
|
||
binSig := md5.Sum([]byte(sig))
|
||
sig = fmt.Sprintf("%x", binSig)
|
||
return sig
|
||
}
|
||
|
||
func (a *API) AccessAPI(action string, isPost bool, bizParams map[string]interface{}) (retVal map[string]interface{}, err error) {
|
||
params := make(map[string]interface{})
|
||
params["key"] = a.appKey
|
||
params = utils.MergeMaps(params, bizParams)
|
||
signStr := a.signParam(params)
|
||
params[sigKey] = signStr
|
||
fullURL := utils.GenerateGetURL(prodURL, action, nil)
|
||
err = platformapi.AccessPlatformAPIWithRetry(a.client,
|
||
func() *http.Request {
|
||
var request *http.Request
|
||
if !isPost {
|
||
request, _ = http.NewRequest(http.MethodGet, utils.GenerateGetURL(fullURL, "", params), nil)
|
||
} else {
|
||
request, _ = http.NewRequest(http.MethodPost, fullURL, strings.NewReader(utils.Map2URLValues(params).Encode()))
|
||
}
|
||
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 utils.MustInterface2Int64(jsonResult1["status"]) != 0 {
|
||
errLevel = platformapi.ErrLevelGeneralFail
|
||
err = utils.NewErrorCode(jsonResult1["des"].(string), utils.Int64ToStr(utils.MustInterface2Int64(jsonResult1["status"])))
|
||
}
|
||
retVal = jsonResult1
|
||
}
|
||
return errLevel, err
|
||
})
|
||
return retVal, err
|
||
}
|
||
|
||
func (a *API) AccessAPI2(action string, isPost bool, bizParams map[string]interface{}) (retVal map[string]interface{}, err error) {
|
||
params := make(map[string]interface{})
|
||
params["key"] = a.appKey
|
||
params = utils.MergeMaps(params, bizParams)
|
||
signStr := a.signParam(params)
|
||
params[sigKey] = signStr
|
||
fullURL := utils.GenerateGetURL(prodURL, action, nil)
|
||
err = platformapi.AccessPlatformAPIWithRetry(a.client,
|
||
func() *http.Request {
|
||
var request *http.Request
|
||
if !isPost {
|
||
request, _ = http.NewRequest(http.MethodGet, utils.GenerateGetURL(fullURL, "", params), nil)
|
||
} else {
|
||
request, _ = http.NewRequest(http.MethodPost, fullURL, strings.NewReader(utils.Map2URLValues(params).Encode()))
|
||
}
|
||
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 {
|
||
retVal = jsonResult1
|
||
}
|
||
return errLevel, err
|
||
})
|
||
return retVal, err
|
||
}
|
||
|
||
func (a *API) AccessStorePage(fullURL string, bizParams map[string]interface{}, isPost bool) (retVal map[string]interface{}, err error) {
|
||
if a.GetCookieCount() == 0 {
|
||
return nil, fmt.Errorf("需要设置Store Cookie才能使用此方法")
|
||
}
|
||
data, _ := json.Marshal(bizParams)
|
||
err = platformapi.AccessPlatformAPIWithRetry(a.client,
|
||
func() *http.Request {
|
||
var request *http.Request
|
||
if isPost {
|
||
request, _ = http.NewRequest(http.MethodPost, fullURL, strings.NewReader(string(data)))
|
||
request.Header.Set("Content-Type", "application/json;charset=utf-8")
|
||
} else {
|
||
request, _ = http.NewRequest(http.MethodGet, utils.GenerateGetURL(fullURL, "", bizParams), nil)
|
||
}
|
||
a.FillRequestCookies(request)
|
||
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 strings.Contains(bodyStr, "登录") || strings.Contains(bodyStr, "访问的内容") {
|
||
return platformapi.ErrLevelRecoverableErr, fmt.Errorf("cookie可能过期了!")
|
||
}
|
||
if err == nil {
|
||
if jsonResult1["error_response"] != nil {
|
||
errLevel = platformapi.ErrLevelGeneralFail
|
||
err = utils.NewErrorCode(jsonResult1["error_response"].(map[string]interface{})["zh_desc"].(string), jsonResult1["error_response"].(map[string]interface{})["code"].(string))
|
||
}
|
||
retVal = jsonResult1
|
||
}
|
||
return errLevel, err
|
||
})
|
||
return retVal, err
|
||
}
|
||
|
||
//https://union.meituan.com/v2/apiDetail?id=8
|
||
//https://runion.meituan.com/generateLink
|
||
func (a *API) MiniCode(actID int, userID string) (url string, err error) {
|
||
result, err := a.AccessAPI("miniCode", false, map[string]interface{}{
|
||
"sid": strings.ToLower(userID),
|
||
"actId": actID,
|
||
})
|
||
if err == nil {
|
||
if utils.MustInterface2Int64(result["status"]) != 0 {
|
||
return "", fmt.Errorf(result["des"].(string))
|
||
} else {
|
||
return result["data"].(string), err
|
||
}
|
||
}
|
||
return url, err
|
||
}
|
||
|
||
func (a *API) GenerateLink(actID, linkType int, userID string) (url string, err error) {
|
||
result, err := a.AccessAPI("generateLink", false, map[string]interface{}{
|
||
"sid": strings.ToLower(userID),
|
||
"actId": actID,
|
||
"linkType": linkType,
|
||
})
|
||
if err == nil {
|
||
if utils.MustInterface2Int64(result["status"]) != 0 {
|
||
return "", fmt.Errorf(result["des"].(string))
|
||
} else {
|
||
return result["data"].(string), err
|
||
}
|
||
}
|
||
return url, err
|
||
}
|
||
|
||
type ActivityListResult struct {
|
||
ID int `json:"id"`
|
||
ActName string `json:"actName"`
|
||
ActDes string `json:"actDes"`
|
||
URL string `json:"url"`
|
||
ActRule string `json:"actRule"`
|
||
Ratio string `json:"ratio"`
|
||
DateBound string `json:"dateBound"`
|
||
ActSrc string `json:"actSrc"`
|
||
}
|
||
|
||
//https://union.meituan.com/api/activity/list
|
||
func (a *API) ActivityList(actType, limit, offset int) (activityListResult []*ActivityListResult, err error) {
|
||
result, err := a.AccessStorePage("https://union.meituan.com/api/activity/list", map[string]interface{}{
|
||
"businessLine": 0,
|
||
"limit": limit,
|
||
"offset": offset,
|
||
}, true)
|
||
if err == nil {
|
||
utils.Map2StructByJson(result["data"].(map[string]interface{})["dataList"], &activityListResult, false)
|
||
}
|
||
return activityListResult, err
|
||
}
|