Merge branch 'master' of https://e.coding.net/rosydev/baseapi
This commit is contained in:
@@ -109,7 +109,7 @@ func TestGetAfsService2(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestOrderShoudSettlementService2(t *testing.T) {
|
||||
result, err := api.OrderShoudSettlementService2("2230609970000292")
|
||||
result, err := api.OrderShoudSettlementService2("2305327970000571")
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ func TestGetPrintMsg(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetPrinterStatus(t *testing.T) {
|
||||
result, err := api.GetPrinterStatus("120220915001012")
|
||||
result, err := api.GetPrinterStatus("120220915001283")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -6,7 +6,7 @@ import (
|
||||
)
|
||||
|
||||
func TestAscriptionPlace(t *testing.T) {
|
||||
p, err := Find("15184316052")
|
||||
p, err := Find("13146872779")
|
||||
fmt.Println(p)
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
72
platformapi/uinapp/uin_app_test.go
Normal file
72
platformapi/uinapp/uin_app_test.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package uinapp
|
||||
|
||||
import (
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/globals"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
api = NewUinappApi(appId, appKey, appSecret, masterSecret)
|
||||
ios = "22d3c42f10cab7765c04ee5aee5ba068"
|
||||
android = "747bda2a61059284405e32a575a03c8f"
|
||||
)
|
||||
|
||||
func TestGetToken(t *testing.T) {
|
||||
err := api.GetUinAppToken()
|
||||
globals.SugarLogger.Debug("result := %v", err)
|
||||
}
|
||||
|
||||
func TestSendMsgAndroid(t *testing.T) {
|
||||
api.SendMsgByUinApp(SendMsgReq{
|
||||
RequestId: utils.Int64ToStr(time.Now().UnixNano()),
|
||||
GroupName: "",
|
||||
Audience: AudienceCid{CId: []string{android}},
|
||||
Settings: SendMsgSetting{},
|
||||
PushMessage: PushMessageDetail{
|
||||
Notification: PushMessageDetailNotification{
|
||||
Title: "测试消息推送[个推推送消息参数]",
|
||||
Body: "吃早饭了没得[个推推送消息参数]",
|
||||
BigText: "这是个什么东西[个推推送消息参数]",
|
||||
BigImage: "",
|
||||
Logo: "",
|
||||
LogoUrl: "",
|
||||
ChannelId: "",
|
||||
ChannelName: "",
|
||||
ChannelLevel: 0,
|
||||
ClickType: "startapp",
|
||||
Intent: "",
|
||||
Url: "",
|
||||
Payload: "",
|
||||
NotifyId: 0,
|
||||
RingName: "",
|
||||
BadgeAddNum: 0,
|
||||
ThreadId: "",
|
||||
},
|
||||
},
|
||||
PushChannel: PushChannelDetail{
|
||||
//Ios: IosApsDetail{},
|
||||
Android: AndroidPushChannelDetail{Ups: AndroidPushChannelUps{
|
||||
Notification: AndroidPushChannelNotification{
|
||||
Title: "测试消息推送[厂商推送消息参数]",
|
||||
Body: "吃早饭了没得[厂商推送消息参数]",
|
||||
ClickType: "startapp",
|
||||
Intent: "",
|
||||
Url: "",
|
||||
NotifyId: 0,
|
||||
},
|
||||
Transmission: "",
|
||||
Revoke: struct {
|
||||
OldTaskId string `json:"old_task_id"`
|
||||
}{},
|
||||
Options: struct {
|
||||
Constraint string `json:"constraint"`
|
||||
Key string `json:"key"`
|
||||
Value interface{} `json:"value"`
|
||||
}{},
|
||||
}},
|
||||
Mp: MpPushChannelDetail{},
|
||||
},
|
||||
})
|
||||
}
|
||||
180
platformapi/uinapp/uinapp_model.go
Normal file
180
platformapi/uinapp/uinapp_model.go
Normal file
@@ -0,0 +1,180 @@
|
||||
package uinapp
|
||||
|
||||
// AppID:dqxDP9HwHc5B1dd2db4ek2
|
||||
// AppKey:Iogz63Q1HL7R4dB8F4Kbn5
|
||||
// AppSecret:wX4n8IusDn7PfxkGmypzp5
|
||||
// MasterSecret:J7pU14SwCC7SoUntXJghj8
|
||||
|
||||
const (
|
||||
appKey = "Iogz63Q1HL7R4dB8F4Kbn5"
|
||||
masterSecret = "J7pU14SwCC7SoUntXJghj8"
|
||||
appId = "dqxDP9HwHc5B1dd2db4ek2"
|
||||
appSecret = "wX4n8IusDn7PfxkGmypzp5"
|
||||
|
||||
BaseUrl = "https://restapi.getui.com/v2/" // 基础路由
|
||||
GetTokenInterface = "/auth" // 获取token接口
|
||||
PushMsgByCid = "push/single/cid" // 通过cId发送消息
|
||||
)
|
||||
|
||||
// AppTokenRes 获取头肯返回值
|
||||
type AppTokenRes struct {
|
||||
Msg string `json:"msg"`
|
||||
Code int `json:"code"`
|
||||
Data struct {
|
||||
ExpireTime string `json:"expire_time"`
|
||||
Token string `json:"token"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
// AudienceCid 推送目标用户
|
||||
type AudienceCid struct {
|
||||
CId []string `json:"cid"` // 设备CID只能一个
|
||||
}
|
||||
|
||||
// SendMsgSetting 推送条件设置,详细解释见下方settings说明
|
||||
type SendMsgSetting struct {
|
||||
Ttl int64 `json:"ttl"` // 消息离线时间设置
|
||||
Strategy struct {
|
||||
DefaultSetting int64 `json:"default"` //1: 表示该消息在用户在线时推送个推通道,用户离线时推送厂商通道; 2: 表示该消息只通过厂商通道策略下发,不考虑用户是否在线; 3: 表示该消息只通过个推通道下发,不考虑用户是否在线; 4: 表示该消息优先从厂商通道下发,若消息内容在厂商通道代发失败后会从个推通道下发。
|
||||
Ios int64 `json:"ios"`
|
||||
Hw int64 `json:"hw"`
|
||||
Ho int64 `json:"ho"`
|
||||
Xm int64 `json:"xm"`
|
||||
Xmg int64 `json:"xmg"`
|
||||
Vv int64 `json:"vv"`
|
||||
Op int64 `json:"op"`
|
||||
Opg int64 `json:"opg"`
|
||||
Mz int64 `json:"mz"`
|
||||
St int64 `json:"st"`
|
||||
Wx int64 `json:"wx"`
|
||||
} `json:"strategy"` // 厂商通道策略
|
||||
}
|
||||
|
||||
// PushMessageDetailNotification 个推安卓消息
|
||||
type PushMessageDetailNotification struct {
|
||||
Title string `json:"title"` // 通知消息标题
|
||||
Body string `json:"body"` // 通知消息内容
|
||||
BigText string `json:"big_text"` // 长文本消息内容,通知消息+长文本样式,与big_image二选一,两个都填写时报错,长度 ≤ 512字
|
||||
BigImage string `json:"big_image"` // 大图的URL地址,通知消息+大图样式, 与big_text二选一,两个都填写时报错,URL长度 ≤ 1024字
|
||||
Logo string `json:"logo"` // 通知的图标名称,包含后缀名
|
||||
LogoUrl string `json:"logo_url"` // 通知图标URL地址
|
||||
ChannelId string `json:"channel_id"` // 通知渠道id
|
||||
ChannelName string `json:"channel_name"` // 通知渠道名称
|
||||
ChannelLevel int64 `json:"channel_level"` // 设置通知渠道重要性
|
||||
ClickType string `json:"click_type"` // 点击通知后续动作 intent:打开应用内特定页面, url:打开网页地址, payload:自定义消息内容启动应用, payload_custom:自定义消息内容不启动应用, startapp:打开应用首页, none:纯通知,无后续动作
|
||||
Intent string `json:"intent"` // click_type为intent时必填 点击通知打开应用特定页面
|
||||
Url string `json:"url"` // click_type为url时必填 点击通知栏消息时,唤起系统默认浏览器打开此链接。必须填写可访问的链接
|
||||
Payload string `json:"payload"` // click_type为payload/payload_custom时必填 点击通知时,附加自定义透传消息
|
||||
NotifyId int64 `json:"notify_id"` // 覆盖任务时会使用到该字段,两条消息的notify_id相同,新的消息会覆盖老的消息
|
||||
RingName string `json:"ring_name"` // 自定义铃声,请填写文件名,不包含后缀名(需要在客户端开发时嵌入),个推通道下发有效
|
||||
BadgeAddNum int64 `json:"badge_add_num"` // 角标, 必须大于0, 个推通道下发有效
|
||||
ThreadId string `json:"thread_id"` // 消息折叠分组,设置成相同thread_id的消息会被折叠(仅支持个推渠道下发的安卓消息)。目前与iOS的thread_id设置无关,安卓和iOS需要分别设置。
|
||||
}
|
||||
|
||||
// PushMessageDetail 个推推送消息参数
|
||||
type PushMessageDetail struct {
|
||||
Duration string `json:"duration"` // 手机端通知展示时间段,格式为毫秒时间戳段,两个时间的时间差必须大于10分钟
|
||||
Notification PushMessageDetailNotification `json:"notification"` // 通知消息内容,仅支持安卓系统,iOS系统不展示个推通知消息,与transmission、revoke三选一,都填写时报错
|
||||
Transmission string // 纯透传消息内容,安卓和iOS均支持,与notification、revoke 三选一,都填写时报错,长度 ≤ 3072字
|
||||
Revoke struct {
|
||||
OldTaskId string `json:"old_task_id"` // 需要撤回的taskId
|
||||
Force bool `json:"force"` // 在没有找到对应的taskId,是否把对应appId下所有的通知都撤回
|
||||
} `json:"revoke"` // 撤回消息时使用(仅撤回个推通道消息)
|
||||
}
|
||||
|
||||
// IosPushChannelAlert 厂推消息通知内容
|
||||
type IosPushChannelAlert struct {
|
||||
Title string `json:"title"` // 通知消息标题
|
||||
Body string `json:"body"` // 通知消息内容
|
||||
ActionLocKey string `json:"action-loc-key"` // (用于多语言支持)指定执行按钮所使用的Localizable.strings
|
||||
LocKey string `json:"loc-key"` // (用于多语言支持)指定Localizable.strings文件中相应的key
|
||||
LocArgs []string `json:"loc-args"` // 如果loc-key中使用了占位符,则在loc-args中指定各参数
|
||||
LaunchImage string `json:"launch-image"` // 指定启动界面图片名
|
||||
TitleLocKey string `json:"title-loc-key"` // (用于多语言支持)对于标题指定执行按钮所使用的Localizable.strings,仅支持iOS8.2以上版本
|
||||
TitleLocArgs []string `json:"title-loc-args"` // 对于标题,如果loc-key中使用的占位符,则在loc-args中指定各参数,仅支持iOS8.2以上版本
|
||||
Subtitle string `json:"subtitle"` // 通知子标题,仅支持iOS8.2以上版本
|
||||
SubtitleLocKey string `json:"subtitle-loc-key"` // 当前本地化文件中的子标题字符串的关键字,仅支持iOS8.2以上版本
|
||||
SubtitleLocArgs []string `json:"subtitle-loc-args"` // 当前本地化子标题内容中需要置换的变量参数 ,仅支持iOS8.2以上版本
|
||||
}
|
||||
|
||||
// IosPushChannelAps 推送通知消息内容
|
||||
type IosPushChannelAps struct {
|
||||
Alert IosPushChannelAlert `json:"alert"` // 通知消息
|
||||
ContentAvailable int64 `json:"content-available"` // 0表示普通通知消息(默认为0); 1表示静默推送(无通知栏消息),静默推送时不需要填写其他参数。苹果建议1小时最多推送3条静默消息
|
||||
Sound string // 自定义铃声,设置为包含后缀名的完整文件名,示例值:ring.mp3 系统铃声,设置为:default无声,设置为:com.gexin.ios.silence,或不填
|
||||
Category string `json:"category"` // 在客户端通知栏触发特定的action和button显示
|
||||
ThreadId string `json:"thread-id"` // ios的远程通知通过该属性对通知进行分组,仅支持iOS 12.0以上版本
|
||||
Timestamp string `json:"timestamp"` // type为liveactivity时必填
|
||||
Event string `json:"event"` // type为liveactivity时必填且值为update
|
||||
ContentState struct{} `json:"content-state"` // type为liveactivity时必填
|
||||
}
|
||||
|
||||
type IosApsDetail struct {
|
||||
NotifyType string `json:"type"` // notify默认通知消息 voip:voip语音推送,notify:apns通知消息,liveactivity:灵动岛推送(不支持p12证书)
|
||||
Aps IosPushChannelAps `json:"aps"` // 推送通知消息内容
|
||||
AutoBadge string `json:""` // 用于计算icon上显示的数字,还可以实现显示数字的自动增减,如“+1”、 “-1”、 “1” 等,计算结果将覆盖badge
|
||||
Payload string `json:"payload"` // 增加自定义的数据
|
||||
Multimedia []struct { // 多媒体设置
|
||||
Url string `json:"url"` // 多媒体资源地址
|
||||
TypeMultimedia int64 `json:"type"` // 资源类型(1.图片,2.音频,3.视频)
|
||||
OnlyWifi bool `json:"only_wifi"` // 是否只在wifi环境下加载,如果设置成true,但未使用wifi时,会展示成普通通知
|
||||
} `json:"multimedia"` // 多媒体设置
|
||||
ApnsCollapseId string `json:"apns-collapse-id"` // 使用相同的apns-collapse-id可以覆盖之前的消息
|
||||
}
|
||||
|
||||
type AndroidPushChannelUps struct {
|
||||
Notification AndroidPushChannelNotification `json:"notification"` // 通知消息内容,与transmission、revoke三选一,都填写时报错。若希望客户端离线时,直接在系统通知栏中展示通知栏消息,推荐使用此参数。
|
||||
Transmission string `json:"transmission"` // 透传消息内容,与notification、revoke 三选一,都填写时报错,长度 ≤ 3072字
|
||||
Revoke struct {
|
||||
OldTaskId string `json:"old_task_id"` // 需要撤回的taskId
|
||||
} // 撤回消息时使用(仅撤回厂商通道消息,支持的厂商有小米、VIVO),与notification、transmission三选一,都填写时报错(消息撤回请勿填写策略参数)
|
||||
Options struct {
|
||||
Constraint string `json:"constraint"` // 扩展内容对应厂商通道设置如:ALL,HW,HO,XM(小米国内),XMG(小米海外),VV,OP,OPG(OPPO海外),MZ,UPS(UPS的参数会影响UPS下面的所有机型,比如ST,SN等等)
|
||||
Key string `json:"key"` // 厂商内容扩展字段
|
||||
Value interface{} `json:"value"` // value的设置根据key值决定
|
||||
} // 第三方厂商扩展内容
|
||||
}
|
||||
|
||||
// AndroidPushChannelNotification 安卓厂推通知消息
|
||||
type AndroidPushChannelNotification struct {
|
||||
Title string `json:"title"` // 通知栏标题(长度建议取最小集)
|
||||
Body string `json:"body"` // 通知栏内容(长度建议取最小集)
|
||||
ClickType string `json:"click_type"` // 点击通知后续动作, 目前支持以下后续动作,intent:打开应用内特定页面(厂商都支持),url:打开网页地址(厂商都支持;华为/荣耀要求https协议,且游戏类应用不支持打开网页地址),startapp:打开应用首页(厂商都支持)
|
||||
Intent string `json:"intent"` // click_type为intent时必填
|
||||
Url string `json:"url"` // click_type为url时必填
|
||||
NotifyId int64 `json:"notify_id"` // 消息覆盖使用,两条消息的notify_id相同,新的消息会覆盖老的消息
|
||||
}
|
||||
|
||||
// AndroidPushChannelDetail 安卓厂推
|
||||
type AndroidPushChannelDetail struct {
|
||||
Ups AndroidPushChannelUps `json:"ups"` // android厂商通道推送消息内容
|
||||
}
|
||||
|
||||
// MpPushChannelDetail 小程序厂推
|
||||
type MpPushChannelDetail struct {
|
||||
Wx struct {
|
||||
TemplateId string `json:"template_id"` // 所需下发的订阅模板id
|
||||
Page string `json:"page"` // 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转
|
||||
MiniProgramState string `json:"mini_program_state"` // 跳转小程序类型:developer:开发版 trial:体验版formal:正式版
|
||||
Lang string `json:"lang"` // 进入小程序查看”的语言类型: zh_CN:简体中文en_US:英文zh_HK:繁体中文zh_TW:繁体中文
|
||||
Data interface{} `json:"data"` // 模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } }的Json对象
|
||||
} `json:"wx"` // 微信小程序通道推送消息内容
|
||||
|
||||
}
|
||||
|
||||
// PushChannelDetail 厂推消息说明
|
||||
type PushChannelDetail struct {
|
||||
Ios IosApsDetail `json:"ios"` // ios通道推送消息内容
|
||||
Android AndroidPushChannelDetail `json:"android"` // android通道推送消息内容
|
||||
Mp MpPushChannelDetail `json:"mp"` // miniProgram通道推送消息内容(只支持透传消息)
|
||||
}
|
||||
|
||||
// SendMsgReq 发送msg
|
||||
type SendMsgReq struct {
|
||||
RequestId string `json:"request_id"` // 请求唯一标识号,10-32位之间;如果request_id重复,会导致消息丢失
|
||||
GroupName string `json:"group_name"` // 任务组名称
|
||||
Audience AudienceCid `json:"audience"` // 推送目标用户
|
||||
Settings SendMsgSetting `json:"settings"` // 推送条件设置
|
||||
PushMessage PushMessageDetail `json:"push_message"` // 个推推送消息参数
|
||||
PushChannel PushChannelDetail `json:"push_channel"` // 厂商推送消息参数,包含ios消息参数,android厂商消息参数
|
||||
}
|
||||
37
platformapi/uinapp/uinapp_send_msg.go
Normal file
37
platformapi/uinapp/uinapp_send_msg.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package uinapp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type SendMsgRes struct {
|
||||
Code int64 `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Data struct {
|
||||
TaskId struct {
|
||||
Cid string `json:"cid"`
|
||||
}
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
func (a *API) SendMsgByUinApp(parma SendMsgReq) error {
|
||||
if err := a.CheckTokenIsExpire(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
result, err := a.AccessAPI(BaseUrl+a.appId, PushMsgByCid, http.MethodPost, utils.Struct2MapByJson(parma))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var sendMsgRes *SendMsgRes
|
||||
if err := utils.Map2StructByJson(result, &sendMsgRes, false); err != nil {
|
||||
return err
|
||||
}
|
||||
if sendMsgRes.Code != 200 {
|
||||
return errors.New(sendMsgRes.Msg)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
131
platformapi/uinapp/uinapp_token.go
Normal file
131
platformapi/uinapp/uinapp_token.go
Normal file
@@ -0,0 +1,131 @@
|
||||
package uinapp
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.rosy.net.cn/baseapi/platformapi"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type API struct {
|
||||
appId string `json:"app_id"`
|
||||
appKey string `json:"app_key"`
|
||||
appSecret string `json:"app_secret"`
|
||||
masterSecret string `json:"master_secret"`
|
||||
token string `json:"token"`
|
||||
expireTime string `json:"expire_time"`
|
||||
locker sync.RWMutex
|
||||
client *http.Client
|
||||
config *platformapi.APIConfig
|
||||
}
|
||||
|
||||
func NewUinappApi(appId, appKey, appSecret, masterSecret string, config ...*platformapi.APIConfig) *API {
|
||||
curConfig := platformapi.DefAPIConfig
|
||||
if len(config) > 0 {
|
||||
curConfig = *config[0]
|
||||
}
|
||||
if appId == "" || masterSecret == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &API{
|
||||
appId: appId,
|
||||
appKey: appKey,
|
||||
appSecret: appSecret,
|
||||
masterSecret: masterSecret,
|
||||
token: "",
|
||||
expireTime: "",
|
||||
locker: sync.RWMutex{},
|
||||
client: &http.Client{Timeout: curConfig.ClientTimeout},
|
||||
config: &curConfig,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *API) AccessAPI(baseUrl, actionApi, method string, bizParams map[string]interface{}) (retVal map[string]interface{}, err error) {
|
||||
// 序列化
|
||||
data, err := json.Marshal(bizParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 全路径请求参数
|
||||
fullURL := utils.GenerateGetURL(baseUrl, actionApi, nil)
|
||||
|
||||
// 发送请求
|
||||
sendUrl := func() *http.Request {
|
||||
var request *http.Request
|
||||
if http.MethodPost == method {
|
||||
request, _ = http.NewRequest(http.MethodPost, fullURL, strings.NewReader(string(data)))
|
||||
} else {
|
||||
request, _ = http.NewRequest(http.MethodGet, utils.GenerateGetURL(baseUrl, actionApi, bizParams), nil)
|
||||
}
|
||||
if actionApi != GetTokenInterface {
|
||||
request.Header.Set("token", a.token)
|
||||
}
|
||||
request.Header.Set("Content-Type", "application/json;charset=utf-8")
|
||||
return request
|
||||
}
|
||||
|
||||
// 数据解析
|
||||
dataMarshal := 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 {
|
||||
return "", err
|
||||
}
|
||||
if utils.MustInterface2Int64(jsonResult1["code"]) != 200 {
|
||||
errLevel = platformapi.ErrLevelGeneralFail
|
||||
err = utils.NewErrorCode(jsonResult1["msg"].(string), utils.Int64ToStr(utils.MustInterface2Int64(jsonResult1["code"])))
|
||||
}
|
||||
retVal = jsonResult1
|
||||
return errLevel, err
|
||||
}
|
||||
|
||||
err = platformapi.AccessPlatformAPIWithRetry(a.client, sendUrl, a.config, dataMarshal)
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
func (a *API) signParam(timestamp string) (sig string) {
|
||||
sig = a.appKey + timestamp + a.masterSecret
|
||||
signature := sha256.Sum256([]byte(sig))
|
||||
return hex.EncodeToString(signature[:])
|
||||
}
|
||||
|
||||
// GetUinAppToken 获取token
|
||||
func (a *API) GetUinAppToken() error {
|
||||
timestamp := utils.Int64ToStr(time.Now().UnixNano() / 1e6)
|
||||
sign := a.signParam(timestamp)
|
||||
result, err := a.AccessAPI(BaseUrl+a.appId, GetTokenInterface, http.MethodPost, map[string]interface{}{"timestamp": timestamp, "sign": sign, "appkey": a.appKey})
|
||||
fmt.Println(err.Error())
|
||||
if err != nil && !strings.Contains(err.Error(), "success") {
|
||||
return err
|
||||
}
|
||||
var appToken *AppTokenRes
|
||||
if err := utils.Map2StructByJson(result, &appToken, false); err != nil {
|
||||
return err
|
||||
}
|
||||
if appToken.Code != 0 && appToken.Msg != "success" {
|
||||
return errors.New(appToken.Msg)
|
||||
}
|
||||
a.token = appToken.Data.Token
|
||||
a.expireTime = appToken.Data.ExpireTime
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckTokenIsExpire 校验头肯是否过期
|
||||
// 注:鉴权接口每分钟最大调用量为100次,每天最大调用量为10万次,建议开发者妥善管理token,以免达到限制,影响推送.感觉不做缓存也够用了!
|
||||
func (a *API) CheckTokenIsExpire() error {
|
||||
// 没有token或者token过期了
|
||||
if a.token == "" || a.expireTime == "" || utils.Str2Int64(a.expireTime) < (time.Now().UnixNano()/1e6) {
|
||||
return a.GetUinAppToken()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user