Browse Source

add reverse:for v1.0.0 极光推送

tags/v1.0.0
huangjiajun 2 years ago
commit
15a13e5dd9
12 changed files with 744 additions and 0 deletions
  1. +8
    -0
      .idea/.gitignore
  2. +8
    -0
      .idea/modules.xml
  3. +6
    -0
      .idea/vcs.xml
  4. +9
    -0
      .idea/zyos_go_jg_push.iml
  5. +5
    -0
      go.mod
  6. +2
    -0
      go.sum
  7. +65
    -0
      hdl/jg_push.go
  8. +30
    -0
      hdl/push_test.go
  9. +90
    -0
      md/jg_push.go
  10. +328
    -0
      utils/convert.go
  11. +170
    -0
      utils/curl.go
  12. +23
    -0
      utils/serialize.go

+ 8
- 0
.idea/.gitignore View File

@@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/

+ 8
- 0
.idea/modules.xml View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/zyos_go_jg_push.iml" filepath="$PROJECT_DIR$/.idea/zyos_go_jg_push.iml" />
</modules>
</component>
</project>

+ 6
- 0
.idea/vcs.xml View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

+ 9
- 0
.idea/zyos_go_jg_push.iml View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

+ 5
- 0
go.mod View File

@@ -0,0 +1,5 @@
module code.fnuoos.com/go_rely_warehouse/zyos_go_jg_push.git

go 1.15

require github.com/syyongx/php2go v0.9.7

+ 2
- 0
go.sum View File

@@ -0,0 +1,2 @@
github.com/syyongx/php2go v0.9.7 h1:boZtLbm2xYbW49mX9M7Vq2zkVhBhv3fCqs2T16d2bGA=
github.com/syyongx/php2go v0.9.7/go.mod h1:meN2eIhhUoxOd2nMxbpe8g6cFPXI5O9/UAAuz7oDdzw=

+ 65
- 0
hdl/jg_push.go View File

@@ -0,0 +1,65 @@
package jg_push

import (
"code.fnuoos.com/go_rely_warehouse/zyos_go_jg_push.git/md"
jg_push_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_jg_push.git/utils"
"encoding/json"
"errors"
"fmt"
"github.com/syyongx/php2go"
)

func Send(appKey, appSecret string, param md.PushParam) (interface{}, error) {

if appKey == "" || appSecret == "" {
return nil, errors.New("配置未设置")
}
url := "https://api.jpush.cn/v3/push"
var iosAlert = md.PushIosAlert{Title: param.Title, Body: param.Content}
req := md.PushRequest{
Platform: param.Platform,
Audience: param.Audience,
Notification: struct {
Android md.PushAndroid `json:"android"`
Ios md.PushIos `json:"ios"`
}{
Android: md.PushAndroid{
Alert: param.Content,
Extras: param.Extras,
Title: param.Title,
},
Ios: md.PushIos{
Alert: iosAlert,
Extras: param.Extras,
Sound: "default",
},
},
Message: struct {
Extras interface{} `json:"extras"`
MsgContent string `json:"msg_content"`
}{
Extras: param.Extras,
MsgContent: param.Content,
},
Options: struct {
TimeToLive int `json:"time_to_live"`
}{
TimeToLive: 86400,
},
}
key := php2go.Base64Encode(appKey + ":" + appSecret)
headers := map[string]string{
"Content-Type": "application/json",
"Authorization": "Basic " + key,
}
b, err := json.Marshal(req)
if err != nil {
return nil, err
}
res, err := jg_push_utils.CurlPost(url, b, headers)
if err != nil {
return nil, err
}
fmt.Println(res)
return res, nil
}

+ 30
- 0
hdl/push_test.go View File

@@ -0,0 +1,30 @@
package jg_push

import (
"code.fnuoos.com/go_rely_warehouse/zyos_go_jg_push.git/md"
"encoding/json"
"testing"
)

func TestPush(t *testing.T) {
var aud = md.PushAudience{Alias: []string{"123456_736"}}
var extrasData = md.NextCommModData{}
extrasStr, _ := json.Marshal(extrasData)
var extras = md.SkipData{
SkipName: "测试",
SkipIdentifier: "pub.flutter.invite_friends",
RequiredLogin: "1",
RequiredTaobaoAuth: "0",
IsJump: "1",
Url: "",
Data: string(extrasStr),
}
var param = md.PushParam{
Platform: "all",
Audience: aud,
Title: "API推送",
Content: "哈哈哈哈",
Extras: extras,
}
Send("6033fc3e19543740413d19aa", "ca7db52b63f7833299042f6a", param)
}

+ 90
- 0
md/jg_push.go View File

@@ -0,0 +1,90 @@
package md

type PushAndroid struct {
Alert string `json:"alert"` //通知内容
//BuilderID int64 `json:"builder_id"` 通知栏样式 ID
Extras interface{} `json:"extras"`
Title string `json:"title"` //通知标题
}
type PushIos struct {
Alert interface{} `json:"alert"`
Extras interface{} `json:"extras"`
Sound string `json:"sound"`
}
type PushIosAlert struct {
Title string `json:"title"`
Body string `json:"body"`
}
type PushAudience struct {
Alias []string `json:"alias"`
}
type PushRequest struct {
Platform interface{} `json:"platform"` //推送平台设置 全部:all 安卓:android iOS:ios ["android", "ios","quickapp"]
Audience interface{} `json:"audience"` //全部:all 别名 {"alias" : [ "4314", "892", "4531"] }
Notification struct { //通知内容体,是被推送到客户端的内容。
Android PushAndroid `json:"android"`
Ios PushIos `json:"ios"`
} `json:"notification"`
Message struct {
Extras interface{} `json:"extras"`
MsgContent string `json:"msg_content"`
} `json:"message"`

Options struct {
TimeToLive int `json:"time_to_live"`
} `json:"options"`
}

type PushParam struct {
Platform interface{} `json:"platform"` //推送平台设置 全部:all 安卓:android iOS:ios ["android", "ios","quickapp"]
Audience interface{} `json:"audience"` //全部:all 别名 {"alias" : [ "4314", "892", "4531"] }
Title string `json:"title"`
Content string `json:"content"`
Extras interface{} `json:"extras"`
}

type SkipData struct {
SkipName string `json:"skip_name"`
SkipIdentifier string `json:"skip_identifier"`
RequiredLogin string `json:"required_login"`
RequiredTaobaoAuth string `json:"required_taobao_auth"`
IsJump string `json:"is_jump"`
Url string `json:"url"`
Data string `json:"data"`
}
type NextCommModData struct {
FromCoinId string `json:"from_coin_id"`
ToCoinId string `json:"to_coin_id"`
Url string `json:"url"`
AppId string `json:"app_id"`
StoreId string `json:"store_id"`
AlipayUrl string `json:"alipay_url"`
AlipayAppid string `json:"alipay_appid"`
ActivityId string `json:"activity_id"`
Id string `json:"id"`
AdName string `json:"ad_name"`
AndroidAdID string `json:"android_ad_id"`
AndroidMediaID string `json:"android_media_id"`
AutoClickAd string `json:"auto_click_ad"`
Autoplay string `json:"autoplay"`
BrandID string `json:"brand_id"`
Conditions string `json:"conditions"`
CreateAt string `json:"create_at"`
EndTime string `json:"end_time"`
Img string `json:"img"`
IosAdID string `json:"ios_ad_id"`
IosMediaID string `json:"ios_media_id"`
IsRecommend interface{} `json:"is_recommend"`
LevelLimitID string `json:"level_limit_id"`
LevelLimitName string `json:"level_limit_name"`
LevelWeight string `json:"level_weight"`
NeedLocation int64 `json:"need_location"`
SdkType string `json:"sdk_type"`
SourceType string `json:"source_type"`
StartTime string `json:"start_time"`
UpdateAt string `json:"update_at"`
VisitCount string `json:"visit_count"`
CountingDown string `json:"counting_down" `
LevelType string `json:"level_type"`
OpenType string `json:"open_type" ` //app 应用内打开 browser 系统浏览器打开
}

+ 328
- 0
utils/convert.go View File

@@ -0,0 +1,328 @@
package jg_push_utils

import (
"encoding/binary"
"encoding/json"
"fmt"
"math"
"strconv"
"strings"
)

func ToString(raw interface{}, e error) (res string) {
if e != nil {
return ""
}
return AnyToString(raw)
}

func ToInt64(raw interface{}, e error) int64 {
if e != nil {
return 0
}
return AnyToInt64(raw)
}
func Float64ToStrByPrec(f float64, prec int) string {
return strconv.FormatFloat(f, 'f', prec, 64)
}
func AnyToBool(raw interface{}) bool {
switch i := raw.(type) {
case float32, float64, int, int64, uint, uint8, uint16, uint32, uint64, int8, int16, int32:
return i != 0
case []byte:
return i != nil
case string:
if i == "false" {
return false
}
return i != ""
case error:
return false
case nil:
return true
}
val := fmt.Sprint(raw)
val = strings.TrimLeft(val, "&")
if strings.TrimLeft(val, "{}") == "" {
return false
}
if strings.TrimLeft(val, "[]") == "" {
return false
}
// ptr type
b, err := json.Marshal(raw)
if err != nil {
return false
}
if strings.TrimLeft(string(b), "\"\"") == "" {
return false
}
if strings.TrimLeft(string(b), "{}") == "" {
return false
}
return true
}

func AnyToInt64(raw interface{}) int64 {
switch i := raw.(type) {
case string:
res, _ := strconv.ParseInt(i, 10, 64)
return res
case []byte:
return BytesToInt64(i)
case int:
return int64(i)
case int64:
return i
case uint:
return int64(i)
case uint8:
return int64(i)
case uint16:
return int64(i)
case uint32:
return int64(i)
case uint64:
return int64(i)
case int8:
return int64(i)
case int16:
return int64(i)
case int32:
return int64(i)
case float32:
return int64(i)
case float64:
return int64(i)
case error:
return 0
case bool:
if i {
return 1
}
return 0
}
return 0
}

func AnyToString(raw interface{}) string {
switch i := raw.(type) {
case []byte:
return string(i)
case int:
return strconv.FormatInt(int64(i), 10)
case int64:
return strconv.FormatInt(i, 10)
case float32:
return Float64ToStr(float64(i))
case float64:
return Float64ToStr(i)
case uint:
return strconv.FormatInt(int64(i), 10)
case uint8:
return strconv.FormatInt(int64(i), 10)
case uint16:
return strconv.FormatInt(int64(i), 10)
case uint32:
return strconv.FormatInt(int64(i), 10)
case uint64:
return strconv.FormatInt(int64(i), 10)
case int8:
return strconv.FormatInt(int64(i), 10)
case int16:
return strconv.FormatInt(int64(i), 10)
case int32:
return strconv.FormatInt(int64(i), 10)
case string:
return i
case error:
return i.Error()
case bool:
return strconv.FormatBool(i)
}
return fmt.Sprintf("%#v", raw)
}

func AnyToFloat64(raw interface{}) float64 {
switch i := raw.(type) {
case []byte:
f, _ := strconv.ParseFloat(string(i), 64)
return f
case int:
return float64(i)
case int64:
return float64(i)
case float32:
return float64(i)
case float64:
return i
case uint:
return float64(i)
case uint8:
return float64(i)
case uint16:
return float64(i)
case uint32:
return float64(i)
case uint64:
return float64(i)
case int8:
return float64(i)
case int16:
return float64(i)
case int32:
return float64(i)
case string:
f, _ := strconv.ParseFloat(i, 64)
return f
case bool:
if i {
return 1
}
}
return 0
}

func ToByte(raw interface{}, e error) []byte {
if e != nil {
return []byte{}
}
switch i := raw.(type) {
case string:
return []byte(i)
case int:
return Int64ToBytes(int64(i))
case int64:
return Int64ToBytes(i)
case float32:
return Float32ToByte(i)
case float64:
return Float64ToByte(i)
case uint:
return Int64ToBytes(int64(i))
case uint8:
return Int64ToBytes(int64(i))
case uint16:
return Int64ToBytes(int64(i))
case uint32:
return Int64ToBytes(int64(i))
case uint64:
return Int64ToBytes(int64(i))
case int8:
return Int64ToBytes(int64(i))
case int16:
return Int64ToBytes(int64(i))
case int32:
return Int64ToBytes(int64(i))
case []byte:
return i
case error:
return []byte(i.Error())
case bool:
if i {
return []byte("true")
}
return []byte("false")
}
return []byte(fmt.Sprintf("%#v", raw))
}

func Int64ToBytes(i int64) []byte {
var buf = make([]byte, 8)
binary.BigEndian.PutUint64(buf, uint64(i))
return buf
}

func BytesToInt64(buf []byte) int64 {
return int64(binary.BigEndian.Uint64(buf))
}

func StrToInt(s string) int {
res, _ := strconv.Atoi(s)
return res
}

func StrToInt64(s string) int64 {
res, _ := strconv.ParseInt(s, 10, 64)
return res
}

func Float32ToByte(float float32) []byte {
bits := math.Float32bits(float)
bytes := make([]byte, 4)
binary.LittleEndian.PutUint32(bytes, bits)

return bytes
}

func ByteToFloat32(bytes []byte) float32 {
bits := binary.LittleEndian.Uint32(bytes)
return math.Float32frombits(bits)
}

func Float64ToByte(float float64) []byte {
bits := math.Float64bits(float)
bytes := make([]byte, 8)
binary.LittleEndian.PutUint64(bytes, bits)
return bytes
}

func ByteToFloat64(bytes []byte) float64 {
bits := binary.LittleEndian.Uint64(bytes)
return math.Float64frombits(bits)
}

func Float64ToStr(f float64) string {
return strconv.FormatFloat(f, 'f', 2, 64)
}
func Float64ToStrPrec1(f float64) string {
return strconv.FormatFloat(f, 'f', 1, 64)
}

func Float64ToStrPrec6(f float64) string {
return strconv.FormatFloat(f, 'f', 6, 64)
}

func Float32ToStr(f float32) string {
return Float64ToStr(float64(f))
}

func StrToFloat64(s string) float64 {
res, err := strconv.ParseFloat(s, 64)
if err != nil {
return 0
}
return res
}

func StrToFloat32(s string) float32 {
res, err := strconv.ParseFloat(s, 32)
if err != nil {
return 0
}
return float32(res)
}

func StrToBool(s string) bool {
b, _ := strconv.ParseBool(s)
return b
}

func BoolToStr(b bool) string {
if b {
return "true"
}
return "false"
}

func FloatToInt64(f float64) int64 {
return int64(f)
}

func IntToStr(i int) string {
return strconv.Itoa(i)
}

func Int64ToStr(i int64) string {
return strconv.FormatInt(i, 10)
}

+ 170
- 0
utils/curl.go View File

@@ -0,0 +1,170 @@
package jg_push_utils

import (
"bytes"
"crypto/tls"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"sort"
"strings"
"time"
)

var CurlDebug bool

func CurlGet(router string, header map[string]string) ([]byte, error) {
return curl(http.MethodGet, router, nil, header)
}

// 只支持form 与json 提交, 请留意body的类型, 支持string, []byte, map[string]string
func CurlPost(router string, body interface{}, header map[string]string) ([]byte, error) {
return curl(http.MethodPost, router, body, header)
}

func CurlPut(router string, body interface{}, header map[string]string) ([]byte, error) {
return curl(http.MethodPut, router, body, header)
}

// 只支持form 与json 提交, 请留意body的类型, 支持string, []byte, map[string]string
func CurlPatch(router string, body interface{}, header map[string]string) ([]byte, error) {
return curl(http.MethodPatch, router, body, header)
}

// CurlDelete is curl delete
func CurlDelete(router string, body interface{}, header map[string]string) ([]byte, error) {
return curl(http.MethodDelete, router, body, header)
}

func curl(method, router string, body interface{}, header map[string]string) ([]byte, error) {
var reqBody io.Reader
contentType := "application/json"
switch v := body.(type) {
case string:
reqBody = strings.NewReader(v)
case []byte:
reqBody = bytes.NewReader(v)
case map[string]string:
val := url.Values{}
for k, v := range v {
val.Set(k, v)
}
reqBody = strings.NewReader(val.Encode())
contentType = "application/x-www-form-urlencoded"
case map[string]interface{}:
val := url.Values{}
for k, v := range v {
val.Set(k, v.(string))
}
reqBody = strings.NewReader(val.Encode())
contentType = "application/x-www-form-urlencoded"
}
if header == nil {
header = map[string]string{"Content-Type": contentType}
}
if _, ok := header["Content-Type"]; !ok {
header["Content-Type"] = contentType
}
resp, er := CurlReq(method, router, reqBody, header)
if er != nil {
return nil, er
}
res, err := ioutil.ReadAll(resp.Body)
if CurlDebug {
blob := SerializeStr(body)
if contentType != "application/json" {
blob = HttpBuild(body)
}
fmt.Printf("\n\n=====================\n[url]: %s\n[time]: %s\n[method]: %s\n[content-type]: %v\n[req_header]: %s\n[req_body]: %#v\n[resp_err]: %v\n[resp_header]: %v\n[resp_body]: %v\n=====================\n\n",
router,
time.Now().Format("2006-01-02 15:04:05.000"),
method,
contentType,
HttpBuildQuery(header),
blob,
err,
SerializeStr(resp.Header),
string(res),
)
}
resp.Body.Close()
return res, err
}

func CurlReq(method, router string, reqBody io.Reader, header map[string]string) (*http.Response, error) {
req, _ := http.NewRequest(method, router, reqBody)
if header != nil {
for k, v := range header {
req.Header.Set(k, v)
}
}
// 绕过github等可能因为特征码返回503问题
// https://www.imwzk.com/posts/2021-03-14-why-i-always-get-503-with-golang/
defaultCipherSuites := []uint16{0xc02f, 0xc030, 0xc02b, 0xc02c, 0xcca8, 0xcca9, 0xc013, 0xc009,
0xc014, 0xc00a, 0x009c, 0x009d, 0x002f, 0x0035, 0xc012, 0x000a}
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
CipherSuites: append(defaultCipherSuites[8:], defaultCipherSuites[:8]...),
},
},
// 获取301重定向
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
return client.Do(req)
}

// 组建get请求参数,sortAsc true为小到大,false为大到小,nil不排序 a=123&b=321
func HttpBuildQuery(args map[string]string, sortAsc ...bool) string {
str := ""
if len(args) == 0 {
return str
}
if len(sortAsc) > 0 {
keys := make([]string, 0, len(args))
for k := range args {
keys = append(keys, k)
}
if sortAsc[0] {
sort.Strings(keys)
} else {
sort.Sort(sort.Reverse(sort.StringSlice(keys)))
}
for _, k := range keys {
str += "&" + k + "=" + args[k]
}
} else {
for k, v := range args {
str += "&" + k + "=" + v
}
}
return str[1:]
}

func HttpBuild(body interface{}, sortAsc ...bool) string {
params := map[string]string{}
if args, ok := body.(map[string]interface{}); ok {
for k, v := range args {
params[k] = AnyToString(v)
}
return HttpBuildQuery(params, sortAsc...)
}
if args, ok := body.(map[string]string); ok {
for k, v := range args {
params[k] = AnyToString(v)
}
return HttpBuildQuery(params, sortAsc...)
}
if args, ok := body.(map[string]int); ok {
for k, v := range args {
params[k] = AnyToString(v)
}
return HttpBuildQuery(params, sortAsc...)
}
return AnyToString(body)
}

+ 23
- 0
utils/serialize.go View File

@@ -0,0 +1,23 @@
package jg_push_utils

import (
"encoding/json"
)

func Serialize(data interface{}) []byte {
res, err := json.Marshal(data)
if err != nil {
return []byte{}
}
return res
}

func Unserialize(b []byte, dst interface{}) {
if err := json.Unmarshal(b, dst); err != nil {
dst = nil
}
}

func SerializeStr(data interface{}, arg ...interface{}) string {
return string(Serialize(data))
}

Loading…
Cancel
Save