正在显示
13 个修改的文件
包含
696 行增加
和
1 行删除
controllers/v1/push.go
0 → 100644
| 1 | +package v1 | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "encoding/json" | ||
| 5 | + "gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log" | ||
| 6 | + "openapi/controllers" | ||
| 7 | + "openapi/protocol" | ||
| 8 | + "openapi/services/push" | ||
| 9 | +) | ||
| 10 | + | ||
| 11 | +type PushController struct { | ||
| 12 | + controllers.BaseController | ||
| 13 | +} | ||
| 14 | + | ||
| 15 | +//推送信息 PushInfo | ||
| 16 | +// @router /pushInfo [post] | ||
| 17 | +func (this *PushController) PushInfo() { | ||
| 18 | + var msg *protocol.ResponseMessage | ||
| 19 | + defer func() { | ||
| 20 | + this.Resp(msg) | ||
| 21 | + }() | ||
| 22 | + var request *protocol.PushInfoRequest | ||
| 23 | + if err := json.Unmarshal(this.ByteBody, &request); err != nil { | ||
| 24 | + log.Error(err) | ||
| 25 | + msg = protocol.BadRequestParam(1) | ||
| 26 | + return | ||
| 27 | + } | ||
| 28 | + if b, m := this.Valid(request); !b { | ||
| 29 | + msg = m | ||
| 30 | + return | ||
| 31 | + } | ||
| 32 | + header := controllers.GetRequestHeader(this.Ctx) | ||
| 33 | + msg = protocol.NewReturnResponse(push.PushInfo(header, request)) | ||
| 34 | +} |
internal/push/getui/getui.go
0 → 100644
| 1 | +package getui | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "crypto/sha256" | ||
| 5 | + "fmt" | ||
| 6 | + "github.com/astaxie/beego/httplib" | ||
| 7 | + "gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log" | ||
| 8 | + "openapi/internal/push" | ||
| 9 | + "openapi/internal/utils" | ||
| 10 | + "strings" | ||
| 11 | + "sync" | ||
| 12 | + "time" | ||
| 13 | +) | ||
| 14 | + | ||
| 15 | +var ( | ||
| 16 | + host = "https://restapi.getui.com" | ||
| 17 | + pushSingle = "push_single" | ||
| 18 | + authSign = "auth_sign " | ||
| 19 | +) | ||
| 20 | + | ||
| 21 | +var ( | ||
| 22 | + authtoken = "" | ||
| 23 | + expire time.Time | ||
| 24 | + authMux sync.RWMutex | ||
| 25 | + expireSpan = time.Second * 3600 * 6 | ||
| 26 | +) | ||
| 27 | + | ||
| 28 | +type GetuiNotification struct { | ||
| 29 | + Options *push.Options | ||
| 30 | + Request *httplib.BeegoHTTPRequest | ||
| 31 | +} | ||
| 32 | + | ||
| 33 | +func (notify *GetuiNotification) Init(options ...push.Option) error { | ||
| 34 | + notify.Options = &push.Options{} | ||
| 35 | + for _, o := range options { | ||
| 36 | + o(notify.Options) | ||
| 37 | + } | ||
| 38 | + return nil | ||
| 39 | +} | ||
| 40 | +func (notify *GetuiNotification) Send(option map[string]interface{}) error { | ||
| 41 | + token, err := notify.GetAuthToken() | ||
| 42 | + if err != nil { | ||
| 43 | + return err | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + var ( | ||
| 47 | + result *Result | ||
| 48 | + url = notify.Url(notify.Options.AppId, pushSingle) | ||
| 49 | + ) | ||
| 50 | + notify.Request = httplib.Post(url) | ||
| 51 | + notify.Request.Header("authtoken", token) | ||
| 52 | + notify.Request.JSONBody(notify.Message()) | ||
| 53 | + if err = notify.Request.ToJSON(&result); err != nil { | ||
| 54 | + return err | ||
| 55 | + } | ||
| 56 | + notify.print(url, notify.Message(), result, result) | ||
| 57 | + if err = handleResult(url, result); err != nil { | ||
| 58 | + return err | ||
| 59 | + } | ||
| 60 | + return nil | ||
| 61 | +} | ||
| 62 | +func (notify *GetuiNotification) Message() interface{} { | ||
| 63 | + //TODO:默认通知模板 | ||
| 64 | + m := NewNotificationTemplate(notify.Options) | ||
| 65 | + return m | ||
| 66 | +} | ||
| 67 | +func (notify *GetuiNotification) Url(param string, method string) string { | ||
| 68 | + return fmt.Sprintf("%v/v1/%v/%v", host, param, method) | ||
| 69 | +} | ||
| 70 | +func (notify *GetuiNotification) GetAuthToken() (token string, err error) { | ||
| 71 | + if authtoken != "" && expire.Unix() > time.Now().Unix() { | ||
| 72 | + token = authtoken | ||
| 73 | + return | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + authMux.Lock() | ||
| 77 | + defer authMux.Unlock() | ||
| 78 | + url := notify.Url(notify.Options.AppId, authSign) | ||
| 79 | + notify.Request = httplib.Post(strings.TrimSpace(url)) | ||
| 80 | + req := &AuthSignRequest{ | ||
| 81 | + Timestamp: fmt.Sprintf("%v", time.Now().Unix()*1000), //"1589797286000",// | ||
| 82 | + AppKey: notify.Options.AppKey, | ||
| 83 | + } | ||
| 84 | + req.Sign = sign(req.AppKey, req.Timestamp, notify.Options.AppMasterSecret) | ||
| 85 | + _, err = notify.Request.JSONBody(req) | ||
| 86 | + if err != nil { | ||
| 87 | + return | ||
| 88 | + } | ||
| 89 | + var rsp *AuthSignResponse | ||
| 90 | + err = notify.Request.ToJSON(&rsp) | ||
| 91 | + notify.print(url, req, rsp, rsp.Result) | ||
| 92 | + if err != nil { | ||
| 93 | + return | ||
| 94 | + } | ||
| 95 | + if err = handleResult(url, rsp.Result); err != nil { | ||
| 96 | + return | ||
| 97 | + } | ||
| 98 | + authtoken = rsp.AuthToken | ||
| 99 | + token = rsp.AuthToken | ||
| 100 | + expire = time.Now().Add(expireSpan) | ||
| 101 | + return | ||
| 102 | +} | ||
| 103 | +func handleResult(url string, result *Result) (err error) { | ||
| 104 | + if strings.ToLower(result.Result) == "ok" { | ||
| 105 | + return | ||
| 106 | + } | ||
| 107 | + err = fmt.Errorf("grequest fail,url:%v error:%v", url, result.Result) | ||
| 108 | + return err | ||
| 109 | +} | ||
| 110 | +func sign(appkey, timestamp, mastersecret string) string { | ||
| 111 | + sha := sha256.New() | ||
| 112 | + sha.Write([]byte(appkey + timestamp + mastersecret)) | ||
| 113 | + return fmt.Sprintf("%x", sha.Sum(nil)) | ||
| 114 | +} | ||
| 115 | +func (notify *GetuiNotification) print(url string, v interface{}, rsp interface{}, result *Result) { | ||
| 116 | + if !notify.Options.DebugModule { | ||
| 117 | + return | ||
| 118 | + } | ||
| 119 | + log.Error(fmt.Sprintf("【个推】 url:%v \n request:%v \n response:%v 结果:%v", url, utils.JsonAssertString(v), utils.JsonAssertString(rsp), result.Result)) | ||
| 120 | +} |
internal/push/getui/getui_test.go
0 → 100644
| 1 | +package getui | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "openapi/internal/push" | ||
| 5 | + "testing" | ||
| 6 | +) | ||
| 7 | + | ||
| 8 | +func TestGetui(t *testing.T) { | ||
| 9 | + var param = make(map[string]interface{}) | ||
| 10 | + param["A"] = "A1" | ||
| 11 | + param["B"] = 2 | ||
| 12 | + param["C"] = struct{ Id int }{Id: 10} | ||
| 13 | + notification := &GetuiNotification{} | ||
| 14 | + err := notification.Init( | ||
| 15 | + push.DebugModule(true), | ||
| 16 | + | ||
| 17 | + push.AppId("TkpBI4awmg9fBUx3NWKXS6"), | ||
| 18 | + push.AppKey("5AjJeDOSOZ5ojQpXJFjhg9"), | ||
| 19 | + push.AppMasterSecret("9VnM8MaA6n84Y5VnOIaSvA"), | ||
| 20 | + push.ClientId("b5fff5f6b0af551da5f381fa47991828"), | ||
| 21 | + | ||
| 22 | + push.MsgType(1), | ||
| 23 | + push.Title("测试 hello"), | ||
| 24 | + push.Content("hello content"), | ||
| 25 | + | ||
| 26 | + push.TransmissionContent("扩展1111"), | ||
| 27 | + push.Extra(param), | ||
| 28 | + ) | ||
| 29 | + if err != nil { | ||
| 30 | + t.Fatal(err) | ||
| 31 | + } | ||
| 32 | + err = notification.Send(param) | ||
| 33 | + if err != nil { | ||
| 34 | + t.Fatal(err) | ||
| 35 | + } | ||
| 36 | +} |
internal/push/getui/model.go
0 → 100644
| 1 | +package getui | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "gitlab.fjmaimaimai.com/mmm-go/gocomm/identity/uid" | ||
| 5 | + "openapi/internal/push" | ||
| 6 | +) | ||
| 7 | + | ||
| 8 | +type Template struct { | ||
| 9 | + ClientId string `json:"cid"` | ||
| 10 | + RequestId string `json:"requestid"` | ||
| 11 | + Message *Message `json:"message"` | ||
| 12 | +} | ||
| 13 | + | ||
| 14 | +//1.消息模板 | ||
| 15 | +type NotificationTemplate struct { | ||
| 16 | + *Template | ||
| 17 | + Notification *Notification `json:"notification"` | ||
| 18 | +} | ||
| 19 | + | ||
| 20 | +//2.透传模板 | ||
| 21 | +type TransmissionTemplate struct{} | ||
| 22 | + | ||
| 23 | +type Notification struct { | ||
| 24 | + Style *Style `json:"style"` | ||
| 25 | + *Transmission | ||
| 26 | +} | ||
| 27 | +type Message struct { | ||
| 28 | + AppKey string `json:"appkey"` | ||
| 29 | + IsOffline bool `json:"is_offline"` | ||
| 30 | + MsgType string `json:"msgtype"` | ||
| 31 | +} | ||
| 32 | +type Transmission struct { | ||
| 33 | + TransmissionType bool `json:"transmission_type"` | ||
| 34 | + TransmissionContent string `json:"transmission_content,omitempty"` | ||
| 35 | + DurationBegin string `json:"duration_begin,omitempty"` | ||
| 36 | + DurationEnd string `json:"duration_end,omitempty"` | ||
| 37 | +} | ||
| 38 | + | ||
| 39 | +func (o *Transmission) SetTransmissionType(t bool) { | ||
| 40 | + o.TransmissionType = t | ||
| 41 | +} | ||
| 42 | +func (o *Transmission) SetTransmissionContent(s string) { | ||
| 43 | + o.TransmissionContent = s | ||
| 44 | +} | ||
| 45 | +func (o *Transmission) SetDuration(begin, end string) { | ||
| 46 | + o.DurationBegin = begin | ||
| 47 | + o.DurationEnd = end | ||
| 48 | +} | ||
| 49 | + | ||
| 50 | +//1.新建单推 | ||
| 51 | +func NewNotificationTemplate(options *push.Options) *NotificationTemplate { | ||
| 52 | + return &NotificationTemplate{ | ||
| 53 | + Template: NewTemplate(options), | ||
| 54 | + Notification: &Notification{ | ||
| 55 | + Style: (&Style{}).SetStyle0(options), | ||
| 56 | + Transmission: NewTransmission(options), | ||
| 57 | + }, | ||
| 58 | + } | ||
| 59 | +} | ||
| 60 | +func NewTemplate(options *push.Options) *Template { | ||
| 61 | + return &Template{ | ||
| 62 | + Message: NewMessage(options), | ||
| 63 | + ClientId: options.ClientId, | ||
| 64 | + RequestId: genRequestId(), | ||
| 65 | + } | ||
| 66 | +} | ||
| 67 | +func NewTransmission(options *push.Options) *Transmission { | ||
| 68 | + t := &Transmission{} | ||
| 69 | + if len(options.TransmissionContent) == 0 { | ||
| 70 | + t.SetTransmissionType(false) | ||
| 71 | + return t | ||
| 72 | + } | ||
| 73 | + t.SetTransmissionType(true) | ||
| 74 | + t.SetTransmissionContent(options.TransmissionContent) | ||
| 75 | + return t | ||
| 76 | +} | ||
| 77 | +func NewMessage(options *push.Options) *Message { | ||
| 78 | + return &Message{ | ||
| 79 | + AppKey: options.AppKey, | ||
| 80 | + IsOffline: true, | ||
| 81 | + MsgType: resolveMsgType(options.MsgType), | ||
| 82 | + } | ||
| 83 | +} | ||
| 84 | +func resolveMsgType(msgType int) string { | ||
| 85 | + /* | ||
| 86 | + 消息应用类型, | ||
| 87 | + 可选项:notification、link、notypopload、startactivity, transmission | ||
| 88 | + */ | ||
| 89 | + switch msgType { | ||
| 90 | + case 1: | ||
| 91 | + return "notification" | ||
| 92 | + | ||
| 93 | + } | ||
| 94 | + return "notification" | ||
| 95 | +} | ||
| 96 | +func genRequestId() string { | ||
| 97 | + return uid.NewV1().StringNoDash() | ||
| 98 | +} | ||
| 99 | + | ||
| 100 | +//样式 0:系统样式 1:个推样式 4:纯图样式 6:展开通知样式 | ||
| 101 | +type Style struct { | ||
| 102 | + Type int `json:"type"` //样式类型 | ||
| 103 | + Text string `json:"text"` //通知内容 | ||
| 104 | + Title string `json:"title"` //通知标题 | ||
| 105 | + Logo string `json:"logo,omitempty"` //通知的图标名称,包含后缀名(需要在客户端开发时嵌入),如“push.png” | ||
| 106 | + //IsRing bool `json:"is_ring"` //收到通知是否响铃:true响铃,false不响铃。默认响铃 | ||
| 107 | + //IsVibrate bool `json:"is_vibrate"` //收到通知是否振动:true振动,false不振动。默认振动 | ||
| 108 | +} | ||
| 109 | + | ||
| 110 | +func (s *Style) SetStyle0(options *push.Options) *Style { | ||
| 111 | + s.Type = 0 | ||
| 112 | + s.Title = options.Title | ||
| 113 | + s.Text = options.Content | ||
| 114 | + s.Logo = "push.png" //TODO:设置Logo地址 | ||
| 115 | + return s | ||
| 116 | +} | ||
| 117 | + | ||
| 118 | +//认证请求/应答 | ||
| 119 | +type AuthSignRequest struct { | ||
| 120 | + Sign string `json:"sign"` | ||
| 121 | + Timestamp string `json:"timestamp"` | ||
| 122 | + AppKey string `json:"appkey"` | ||
| 123 | +} | ||
| 124 | +type AuthSignResponse struct { | ||
| 125 | + *Result | ||
| 126 | + AuthToken string `json:"auth_token"` | ||
| 127 | +} | ||
| 128 | + | ||
| 129 | +type Result struct { | ||
| 130 | + Result string `json:"result"` | ||
| 131 | + TaskId string `json:"taskid"` | ||
| 132 | + Status string `json:"status"` | ||
| 133 | + Desc string `json:"desc"` | ||
| 134 | +} |
internal/push/model.go
0 → 100644
| 1 | +package push | ||
| 2 | + | ||
| 3 | +type Options struct { | ||
| 4 | + AppId string | ||
| 5 | + AppKey string | ||
| 6 | + AppSecret string | ||
| 7 | + AppMasterSecret string | ||
| 8 | + ClientId string | ||
| 9 | + | ||
| 10 | + MsgType int | ||
| 11 | + | ||
| 12 | + Title string | ||
| 13 | + Content string | ||
| 14 | + Extra interface{} //扩展数据 | ||
| 15 | + TransmissionContent string //透传内容 | ||
| 16 | + | ||
| 17 | + DebugModule bool | ||
| 18 | +} | ||
| 19 | +type Option func(o *Options) | ||
| 20 | + | ||
| 21 | +//个推appId | ||
| 22 | +func AppId(id string) Option { | ||
| 23 | + return func(o *Options) { | ||
| 24 | + o.AppId = id | ||
| 25 | + } | ||
| 26 | +} | ||
| 27 | + | ||
| 28 | +//个推appKey | ||
| 29 | +func AppKey(key string) Option { | ||
| 30 | + return func(o *Options) { | ||
| 31 | + o.AppKey = key | ||
| 32 | + } | ||
| 33 | +} | ||
| 34 | + | ||
| 35 | +//个推appSecret | ||
| 36 | +func AppSecret(secret string) Option { | ||
| 37 | + return func(o *Options) { | ||
| 38 | + o.AppSecret = secret | ||
| 39 | + } | ||
| 40 | +} | ||
| 41 | + | ||
| 42 | +//个推appMasterSecret | ||
| 43 | +func AppMasterSecret(secret string) Option { | ||
| 44 | + return func(o *Options) { | ||
| 45 | + o.AppMasterSecret = secret | ||
| 46 | + } | ||
| 47 | +} | ||
| 48 | + | ||
| 49 | +//个推 app clientId | ||
| 50 | +func ClientId(clientId string) Option { | ||
| 51 | + return func(o *Options) { | ||
| 52 | + o.ClientId = clientId | ||
| 53 | + } | ||
| 54 | +} | ||
| 55 | + | ||
| 56 | +//消息类型 | ||
| 57 | +func MsgType(msgType int) Option { | ||
| 58 | + return func(o *Options) { | ||
| 59 | + o.MsgType = msgType | ||
| 60 | + } | ||
| 61 | +} | ||
| 62 | + | ||
| 63 | +//消息内容 | ||
| 64 | +func Title(title string) Option { | ||
| 65 | + return func(o *Options) { | ||
| 66 | + o.Title = title | ||
| 67 | + } | ||
| 68 | +} | ||
| 69 | +func Content(content string) Option { | ||
| 70 | + return func(o *Options) { | ||
| 71 | + o.Content = content | ||
| 72 | + } | ||
| 73 | +} | ||
| 74 | +func Extra(extra interface{}) Option { | ||
| 75 | + return func(o *Options) { | ||
| 76 | + o.Extra = extra | ||
| 77 | + } | ||
| 78 | +} | ||
| 79 | +func TransmissionContent(content string) Option { | ||
| 80 | + return func(o *Options) { | ||
| 81 | + o.TransmissionContent = content | ||
| 82 | + } | ||
| 83 | +} | ||
| 84 | +func DebugModule(module bool) Option { | ||
| 85 | + return func(o *Options) { | ||
| 86 | + o.DebugModule = module | ||
| 87 | + } | ||
| 88 | +} | ||
| 89 | + | ||
| 90 | +const ( | ||
| 91 | + Message = iota + 1 | ||
| 92 | + Notification | ||
| 93 | +) |
internal/push/push.go
0 → 100644
| @@ -28,7 +28,7 @@ func (a UMAppAuth) GetAppAuth(appName string) *AppAuth { | @@ -28,7 +28,7 @@ func (a UMAppAuth) GetAppAuth(appName string) *AppAuth { | ||
| 28 | if auth, ok := a[appName]; ok { | 28 | if auth, ok := a[appName]; ok { |
| 29 | return auth | 29 | return auth |
| 30 | } | 30 | } |
| 31 | - return nil | 31 | + return a.GetAppAuth(ProjectDefault) |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | type AppAuth struct { | 34 | type AppAuth struct { |
internal/push/umeng/umeng.go
0 → 100644
| 1 | +package umeng | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "crypto/md5" | ||
| 5 | + "encoding/json" | ||
| 6 | + "fmt" | ||
| 7 | + "github.com/astaxie/beego/httplib" | ||
| 8 | + "io/ioutil" | ||
| 9 | + "net/http" | ||
| 10 | + "openapi/internal/push" | ||
| 11 | + "strings" | ||
| 12 | + "time" | ||
| 13 | +) | ||
| 14 | + | ||
| 15 | +var ( | ||
| 16 | + Host = "http://msg.umeng.com" | ||
| 17 | + ApiSend = "/api/send" | ||
| 18 | + UploadPath = "/upload" | ||
| 19 | +) | ||
| 20 | + | ||
| 21 | +var FiledErrorFormat = "缺少字段:%v" | ||
| 22 | +var FiledErrorFormatFunc = func(filed string) error { | ||
| 23 | + return fmt.Errorf(FiledErrorFormat, filed) | ||
| 24 | +} | ||
| 25 | + | ||
| 26 | +const ( | ||
| 27 | + AppKey = "appkey" | ||
| 28 | + Timestamp = "timestamp" | ||
| 29 | + Type = "type" | ||
| 30 | + ProductionMode = "production_mode" | ||
| 31 | + DeviceTokens = "device_tokens" | ||
| 32 | + Payload = "payload" | ||
| 33 | + Policy = "policy" | ||
| 34 | + Description = "description" | ||
| 35 | + | ||
| 36 | + DisplayType = "displayType" | ||
| 37 | + Body = "body" | ||
| 38 | + Ticker = "ticker" // 必填,通知栏提示文字 | ||
| 39 | + Title = "title" // 必填,通知标题 | ||
| 40 | + Text = "text" //必填,通知文字描述 | ||
| 41 | + /* | ||
| 42 | + // 可选,默认为"go_app",值可以为: | ||
| 43 | + // "go_app": 打开应用 | ||
| 44 | + // "go_url": 跳转到URL | ||
| 45 | + // "go_activity": 打开特定的activity | ||
| 46 | + // "go_custom": 用户自定义内容。 | ||
| 47 | + */ | ||
| 48 | + AfterOpen = "after_open" | ||
| 49 | + Extra = "extra" | ||
| 50 | +) | ||
| 51 | + | ||
| 52 | +const ( | ||
| 53 | + Message = "message" | ||
| 54 | + Notification = "notification" | ||
| 55 | +) | ||
| 56 | +const ( | ||
| 57 | + ExpireSpan = time.Second * 60 * 60 * 24 | ||
| 58 | +) | ||
| 59 | + | ||
| 60 | +type SetPayload func(msg *UnicastMsg, option map[string]interface{}) error | ||
| 61 | + | ||
| 62 | +type UmengNotification struct { | ||
| 63 | + Auth *Auth | ||
| 64 | + Request *httplib.BeegoHTTPRequest | ||
| 65 | +} | ||
| 66 | + | ||
| 67 | +func (notify *UmengNotification) Init(options ...push.Option) error { | ||
| 68 | + return nil | ||
| 69 | +} | ||
| 70 | +func (notify *UmengNotification) Send(option map[string]interface{}) error { | ||
| 71 | + var ( | ||
| 72 | + setPayload SetPayload = SetAndroidPayload | ||
| 73 | + body []byte | ||
| 74 | + err error | ||
| 75 | + httpRsp *http.Response | ||
| 76 | + ret = make(map[string]interface{}) | ||
| 77 | + data []byte | ||
| 78 | + ) | ||
| 79 | + if option["DeviceType"].(int) == 1 { | ||
| 80 | + setPayload = SetAndroidPayload | ||
| 81 | + } | ||
| 82 | + if body, err = notify.PostBody(option, setPayload); err != nil { | ||
| 83 | + return err | ||
| 84 | + } | ||
| 85 | + notify.Request = httplib.Post(notify.Url(ApiSend, body)) | ||
| 86 | + notify.Request.Body(body) | ||
| 87 | + | ||
| 88 | + if httpRsp, err = notify.Request.DoRequest(); err != nil { | ||
| 89 | + return err | ||
| 90 | + } | ||
| 91 | + data, err = ioutil.ReadAll(httpRsp.Body) | ||
| 92 | + defer httpRsp.Body.Close() | ||
| 93 | + if err != nil { | ||
| 94 | + return err | ||
| 95 | + } | ||
| 96 | + if err = json.Unmarshal(data, &ret); err != nil { | ||
| 97 | + return err | ||
| 98 | + } | ||
| 99 | + if status, ok := ret["ret"]; ok { | ||
| 100 | + if strings.EqualFold(fmt.Sprintf("%v", status), "SUCCESS") { | ||
| 101 | + return nil | ||
| 102 | + } | ||
| 103 | + return fmt.Errorf("response:%v fail", ret) | ||
| 104 | + } | ||
| 105 | + return fmt.Errorf("response:%v invaild", ret) | ||
| 106 | +} | ||
| 107 | +func (notify *UmengNotification) PostBody(option map[string]interface{}, setPayload SetPayload) (body []byte, err error) { | ||
| 108 | + var postData = new(UnicastMsg) | ||
| 109 | + postData.AppKey = notify.Auth.AppKey | ||
| 110 | + postData.Timestamp = fmt.Sprintf("%v", time.Now().Unix()) | ||
| 111 | + postData.ProductionMode = fmt.Sprintf("%v", true) | ||
| 112 | + postData.Type = fmt.Sprintf("%v", option[Type]) | ||
| 113 | + postData.DeviceTokens = fmt.Sprintf("%v", option[DeviceTokens]) | ||
| 114 | + postData.Policy = MsgPolicy{ExpireTime: time.Now().Add(ExpireSpan).Format("2006-01-02 15:04:05")} | ||
| 115 | + if err = setPayload(postData, option); err != nil { | ||
| 116 | + return | ||
| 117 | + } | ||
| 118 | + postData.Description = fmt.Sprintf("%v", option[Title]) | ||
| 119 | + if body, err = json.Marshal(postData); err != nil { | ||
| 120 | + return | ||
| 121 | + } | ||
| 122 | + return | ||
| 123 | +} | ||
| 124 | +func (notify *UmengNotification) Url(method string, body []byte) string { | ||
| 125 | + var url string = fmt.Sprintf("%v%v", Host, method) | ||
| 126 | + sign := fmt.Sprintf("%x", md5.Sum([]byte("POST"+url+string(body)+notify.Auth.AppMasterSecret))) | ||
| 127 | + url = fmt.Sprintf("%v?sign=%v", url, sign) | ||
| 128 | + return url | ||
| 129 | +} | ||
| 130 | + | ||
| 131 | +type UnicastMsg struct { | ||
| 132 | + AppKey string `json:"appkey"` | ||
| 133 | + Timestamp string `json:"timestamp"` | ||
| 134 | + Type string `json:"type"` //发送类型 单播 列播... | ||
| 135 | + ProductionMode string `json:"production_mode"` | ||
| 136 | + DeviceTokens string `json:"device_tokens"` | ||
| 137 | + Payload MsgPayload `json:"payload"` | ||
| 138 | + Policy MsgPolicy `json:"policy"` | ||
| 139 | + Description string `json:"description"` | ||
| 140 | +} | ||
| 141 | +type MsgPayload map[string]interface{} | ||
| 142 | +type MsgPolicy struct { | ||
| 143 | + ExpireTime string `json:"expire_time"` | ||
| 144 | +} | ||
| 145 | + | ||
| 146 | +//设置payload | ||
| 147 | +func SetAndroidPayload(msg *UnicastMsg, option map[string]interface{}) error { | ||
| 148 | + msg.Payload = make(map[string]interface{}) | ||
| 149 | + var ( | ||
| 150 | + displayType string | ||
| 151 | + ok bool | ||
| 152 | + ) | ||
| 153 | + if _, ok = option[DisplayType]; !ok { | ||
| 154 | + return FiledErrorFormatFunc(DisplayType) | ||
| 155 | + } | ||
| 156 | + displayType = option[DisplayType].(string) | ||
| 157 | + switch displayType { | ||
| 158 | + case Message: | ||
| 159 | + break | ||
| 160 | + case Notification: | ||
| 161 | + var payloadBody = make(map[string]interface{}) | ||
| 162 | + //if _,ok =option[Title];!ok{ | ||
| 163 | + // return FiledErrorFormatFunc(Title) | ||
| 164 | + //} | ||
| 165 | + //if _,ok =option[Text];!ok{ | ||
| 166 | + // return FiledErrorFormatFunc(Text) | ||
| 167 | + //} | ||
| 168 | + //if _,ok =option[Extra];ok{ | ||
| 169 | + // payloadBody[Extra]=option[Extra] | ||
| 170 | + //} | ||
| 171 | + payloadBody[Ticker] = option[Title] | ||
| 172 | + payloadBody[Title] = option[Title] | ||
| 173 | + payloadBody[Text] = option[Text] | ||
| 174 | + payloadBody[AfterOpen] = "go_app" | ||
| 175 | + msg.Payload[Body] = payloadBody | ||
| 176 | + break | ||
| 177 | + default: | ||
| 178 | + return FiledErrorFormatFunc(DisplayType) | ||
| 179 | + break | ||
| 180 | + } | ||
| 181 | + return nil | ||
| 182 | +} |
| @@ -90,6 +90,13 @@ func JsonUnmarshal(jsonData string, v interface{}) { | @@ -90,6 +90,13 @@ func JsonUnmarshal(jsonData string, v interface{}) { | ||
| 90 | } | 90 | } |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | +func JsonAssertString(v interface{}) string { | ||
| 94 | + if data, e := json.Marshal(v); e == nil { | ||
| 95 | + return string(data) | ||
| 96 | + } | ||
| 97 | + return "" | ||
| 98 | +} | ||
| 99 | + | ||
| 93 | //深度拷贝 | 100 | //深度拷贝 |
| 94 | func DeepCopy(dst, src interface{}) error { | 101 | func DeepCopy(dst, src interface{}) error { |
| 95 | var buf bytes.Buffer | 102 | var buf bytes.Buffer |
protocol/push.go
0 → 100644
| 1 | +package protocol | ||
| 2 | + | ||
| 3 | +/*PushInfo 推送信息*/ | ||
| 4 | +type PushInfoRequest struct { | ||
| 5 | + Type int `json:"mmmType" valid:"Required"` | ||
| 6 | + DeviceToken string `json:"deviceToken" valid:"Required"` | ||
| 7 | + ClientId string `json:"clientId" valid:"Required"` | ||
| 8 | + AppKey string `json:"appKey" valid:"Required"` | ||
| 9 | + Secret string `json:"secret" valid:"Required"` | ||
| 10 | + AppId string `json:"appId" valid:"Required"` | ||
| 11 | + | ||
| 12 | + Title string `json:"title" valid:"Required"` | ||
| 13 | + Content string `json:"content" valid:"Required"` | ||
| 14 | + Ext map[string]interface{} | ||
| 15 | +} | ||
| 16 | +type PushInfoResponse struct { | ||
| 17 | +} |
| @@ -7,6 +7,14 @@ import ( | @@ -7,6 +7,14 @@ import ( | ||
| 7 | 7 | ||
| 8 | func init() { | 8 | func init() { |
| 9 | 9 | ||
| 10 | + beego.GlobalControllerRouter["openapi/controllers/v1:PushController"] = append(beego.GlobalControllerRouter["openapi/controllers/v1:PushController"], | ||
| 11 | + beego.ControllerComments{ | ||
| 12 | + Method: "PushInfo", | ||
| 13 | + Router: `/pushInfo`, | ||
| 14 | + AllowHTTPMethods: []string{"post"}, | ||
| 15 | + MethodParams: param.Make(), | ||
| 16 | + Params: nil}) | ||
| 17 | + | ||
| 10 | beego.GlobalControllerRouter["openapi/controllers/v1:VodController"] = append(beego.GlobalControllerRouter["openapi/controllers/v1:VodController"], | 18 | beego.GlobalControllerRouter["openapi/controllers/v1:VodController"] = append(beego.GlobalControllerRouter["openapi/controllers/v1:VodController"], |
| 11 | beego.ControllerComments{ | 19 | beego.ControllerComments{ |
| 12 | Method: "CreateUploadImage", | 20 | Method: "CreateUploadImage", |
services/push/push.go
0 → 100644
| 1 | +package push | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log" | ||
| 5 | + "openapi/internal/push" | ||
| 6 | + "openapi/internal/push/getui" | ||
| 7 | + "openapi/internal/push/umeng" | ||
| 8 | + "openapi/internal/utils" | ||
| 9 | + "openapi/protocol" | ||
| 10 | +) | ||
| 11 | + | ||
| 12 | +//推送信息 | ||
| 13 | +func PushInfo(header *protocol.RequestHeader, request *protocol.PushInfoRequest) (rsp *protocol.PushInfoResponse, err error) { | ||
| 14 | + var ( | ||
| 15 | + sendData = make(map[string]interface{}) | ||
| 16 | + ) | ||
| 17 | + | ||
| 18 | + var pushService push.INotification = &getui.GetuiNotification{} | ||
| 19 | + | ||
| 20 | + sendData["DeviceType"] = header.DeviceType | ||
| 21 | + sendData[umeng.AppKey] = request.AppKey | ||
| 22 | + sendData[umeng.DeviceTokens] = request.DeviceToken | ||
| 23 | + sendData[umeng.DisplayType] = umeng.Notification | ||
| 24 | + sendData[umeng.Title] = request.Title | ||
| 25 | + sendData[umeng.Text] = request.Content | ||
| 26 | + sendData[umeng.Extra] = request.Ext | ||
| 27 | + sendData[umeng.Type] = "unicast" | ||
| 28 | + | ||
| 29 | + err = pushService.Init( | ||
| 30 | + push.DebugModule(true), | ||
| 31 | + | ||
| 32 | + push.AppId(request.AppId), | ||
| 33 | + push.AppKey(request.AppKey), | ||
| 34 | + push.AppMasterSecret(request.Secret), | ||
| 35 | + push.ClientId(request.ClientId), | ||
| 36 | + | ||
| 37 | + push.MsgType(request.Type), | ||
| 38 | + push.Title(request.Title), | ||
| 39 | + push.Content(request.Content), | ||
| 40 | + push.TransmissionContent(utils.JsonAssertString(request.Ext)), | ||
| 41 | + ) | ||
| 42 | + if err != nil { | ||
| 43 | + log.Error(err) | ||
| 44 | + return | ||
| 45 | + } | ||
| 46 | + if err = pushService.Send(sendData); err != nil { | ||
| 47 | + log.Error(err) | ||
| 48 | + return | ||
| 49 | + } | ||
| 50 | + rsp = &protocol.PushInfoResponse{} | ||
| 51 | + return | ||
| 52 | +} |
-
请 注册 或 登录 后发表评论