作者 yangfu

个推 增加群推功能

1 package push 1 package push
2 2
3 /* 3 /*
4 -Map key 4 + PushType 推送类型
5 */ 5 */
6 -const () 6 +const (
  7 + PushToSingle = iota + 1 //单推
  8 + PushToList //群推
  9 +)
  10 +
  11 +/*
  12 + MsgType 消息类型 -> 决定发送的模板样式
  13 +*/
  14 +const (
  15 + SystemNotification = iota + 1 //系统消息
  16 +)
@@ -12,9 +12,11 @@ import ( @@ -12,9 +12,11 @@ import (
12 "time" 12 "time"
13 ) 13 )
14 14
15 -var ( 15 +const (
16 host = "https://restapi.getui.com" 16 host = "https://restapi.getui.com"
17 pushSingle = "push_single" 17 pushSingle = "push_single"
  18 + saveListBody = "save_list_body"
  19 + pushList = "push_list"
18 authSign = "auth_sign " 20 authSign = "auth_sign "
19 ) 21 )
20 22
@@ -25,6 +27,7 @@ var ( @@ -25,6 +27,7 @@ var (
25 expireSpan = time.Second * 3600 * 6 27 expireSpan = time.Second * 3600 * 6
26 ) 28 )
27 29
  30 +//GetuiNotification 个推消息推送
28 type GetuiNotification struct { 31 type GetuiNotification struct {
29 Options *push.Options 32 Options *push.Options
30 Request *httplib.BeegoHTTPRequest 33 Request *httplib.BeegoHTTPRequest
@@ -37,36 +40,133 @@ func (notify *GetuiNotification) Init(options ...push.Option) error { @@ -37,36 +40,133 @@ func (notify *GetuiNotification) Init(options ...push.Option) error {
37 } 40 }
38 return nil 41 return nil
39 } 42 }
40 -func (notify *GetuiNotification) Send(option map[string]interface{}) error {  
41 - token, err := notify.GetAuthToken() 43 +func (notify *GetuiNotification) Send(option map[string]interface{}) (err error) {
  44 + switch notify.Options.PushType {
  45 + case push.PushToSingle:
  46 + err = notify.pushToSingle(option)
  47 + case push.PushToList:
  48 + err = notify.pushToList(option)
  49 + default:
  50 + err = notify.pushToSingle(option)
  51 + }
42 if err != nil { 52 if err != nil {
43 return err 53 return err
44 } 54 }
  55 + return nil
  56 +}
  57 +
  58 +//pushToSingle 单推
  59 +func (notify *GetuiNotification) pushToSingle(option map[string]interface{}) (err error) {
  60 + var token string
  61 + if token, err = notify.GetAuthToken(); err != nil {
  62 + return err
  63 + }
45 64
46 var ( 65 var (
47 result *Result 66 result *Result
48 url = notify.Url(notify.Options.AppId, pushSingle) 67 url = notify.Url(notify.Options.AppId, pushSingle)
  68 + m = notify.Message(pushSingle)
49 ) 69 )
50 notify.Request = httplib.Post(url) 70 notify.Request = httplib.Post(url)
51 notify.Request.Header("authtoken", token) 71 notify.Request.Header("authtoken", token)
52 - notify.Request.JSONBody(notify.Message()) 72 + notify.Request.JSONBody(m)
53 if err = notify.Request.ToJSON(&result); err != nil { 73 if err = notify.Request.ToJSON(&result); err != nil {
54 return err 74 return err
55 } 75 }
56 - notify.print(url, notify.Message(), result, result) 76 + notify.print(url, m, result, result)
57 if err = handleResult(url, result); err != nil { 77 if err = handleResult(url, result); err != nil {
58 return err 78 return err
59 } 79 }
60 return nil 80 return nil
61 } 81 }
62 -func (notify *GetuiNotification) Message() interface{} {  
63 - //TODO:默认通知模板  
64 - m := NewNotificationTemplate(notify.Options) 82 +
  83 +//pushToList 群推
  84 +//步骤1.获取token
  85 +//步骤2.save_list_body保存消息共同体
  86 +//步骤3.push_list
  87 +func (notify *GetuiNotification) pushToList(option map[string]interface{}) (err error) {
  88 + var (
  89 + token string
  90 + taskId string
  91 + )
  92 + if token, err = notify.GetAuthToken(); err != nil {
  93 + return err
  94 + }
  95 + if taskId, err = notify.saveListBody(token, option); err != nil {
  96 + return err
  97 + }
  98 + var (
  99 + result *Result
  100 + url = notify.Url(notify.Options.AppId, pushList)
  101 + m = struct {
  102 + Cid []string `json:"cid"`
  103 + TaskId string `json:"taskid"`
  104 + NeedDetail bool `json:"need_detail"`
  105 + }{
  106 + Cid: notify.Options.ClientIds,
  107 + TaskId: taskId,
  108 + NeedDetail: true,
  109 + }
  110 + )
  111 + notify.Request = httplib.Post(url)
  112 + notify.Request.Header("authtoken", token)
  113 + notify.Request.JSONBody(m)
  114 + if err = notify.Request.ToJSON(&result); err != nil {
  115 + return err
  116 + }
  117 + notify.print(url, m, result, result)
  118 + if err = handleResult(url, result); err != nil {
  119 + return err
  120 + }
  121 + return nil
  122 +}
  123 +
  124 +//saveListBody 保存消息共同体
  125 +func (notify *GetuiNotification) saveListBody(token string, option map[string]interface{}) (taskId string, err error) {
  126 + var (
  127 + result *Result
  128 + url = notify.Url(notify.Options.AppId, saveListBody)
  129 + m = notify.Message(saveListBody)
  130 + )
  131 + notify.Request = httplib.Post(url)
  132 + notify.Request.Header("authtoken", token)
  133 + notify.Request.JSONBody(m)
  134 + if err = notify.Request.ToJSON(&result); err != nil {
  135 + return
  136 + }
  137 + notify.print(url, m, result, result)
  138 + if err = handleResult(url, result); err != nil {
  139 + return
  140 + }
  141 + taskId = result.TaskId
  142 + return
  143 +}
  144 +
  145 +//Message 组装消息体
  146 +func (notify *GetuiNotification) Message(method string) interface{} {
  147 + var m interface{}
  148 + switch notify.Options.MsgType {
  149 + case push.SystemNotification:
  150 + t := NewNotificationTemplate(notify.Options)
  151 + if method == saveListBody {
  152 + t.ClientId = ""
  153 + t.RequestId = ""
  154 + }
  155 + m = t
  156 + break
  157 + default:
  158 + m = NewNotificationTemplate(notify.Options)
  159 + break
  160 + }
65 return m 161 return m
66 } 162 }
  163 +
  164 +//Url 组装请求地址
67 func (notify *GetuiNotification) Url(param string, method string) string { 165 func (notify *GetuiNotification) Url(param string, method string) string {
68 return fmt.Sprintf("%v/v1/%v/%v", host, param, method) 166 return fmt.Sprintf("%v/v1/%v/%v", host, param, method)
69 } 167 }
  168 +
  169 +//GetAuthToken 获取token
70 func (notify *GetuiNotification) GetAuthToken() (token string, err error) { 170 func (notify *GetuiNotification) GetAuthToken() (token string, err error) {
71 if authtoken != "" && expire.Unix() > time.Now().Unix() { 171 if authtoken != "" && expire.Unix() > time.Now().Unix() {
72 token = authtoken 172 token = authtoken
@@ -100,6 +200,16 @@ func (notify *GetuiNotification) GetAuthToken() (token string, err error) { @@ -100,6 +200,16 @@ func (notify *GetuiNotification) GetAuthToken() (token string, err error) {
100 expire = time.Now().Add(expireSpan) 200 expire = time.Now().Add(expireSpan)
101 return 201 return
102 } 202 }
  203 +
  204 +//打印日志 debug_module=true print debug log
  205 +func (notify *GetuiNotification) print(url string, v interface{}, rsp interface{}, result *Result) {
  206 + if !notify.Options.DebugModule {
  207 + return
  208 + }
  209 + log.Error(fmt.Sprintf("【个推】 url:%v \n request:%v \n response:%v 结果:%v", url, utils.JsonAssertString(v), utils.JsonAssertString(rsp), result.Result))
  210 +}
  211 +
  212 +//处理结果
103 func handleResult(url string, result *Result) (err error) { 213 func handleResult(url string, result *Result) (err error) {
104 if strings.ToLower(result.Result) == "ok" { 214 if strings.ToLower(result.Result) == "ok" {
105 return 215 return
@@ -112,9 +222,3 @@ func sign(appkey, timestamp, mastersecret string) string { @@ -112,9 +222,3 @@ func sign(appkey, timestamp, mastersecret string) string {
112 sha.Write([]byte(appkey + timestamp + mastersecret)) 222 sha.Write([]byte(appkey + timestamp + mastersecret))
113 return fmt.Sprintf("%x", sha.Sum(nil)) 223 return fmt.Sprintf("%x", sha.Sum(nil))
114 } 224 }
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 -}  
@@ -17,7 +17,12 @@ func TestGetui(t *testing.T) { @@ -17,7 +17,12 @@ func TestGetui(t *testing.T) {
17 push.AppId("TkpBI4awmg9fBUx3NWKXS6"), 17 push.AppId("TkpBI4awmg9fBUx3NWKXS6"),
18 push.AppKey("5AjJeDOSOZ5ojQpXJFjhg9"), 18 push.AppKey("5AjJeDOSOZ5ojQpXJFjhg9"),
19 push.AppMasterSecret("9VnM8MaA6n84Y5VnOIaSvA"), 19 push.AppMasterSecret("9VnM8MaA6n84Y5VnOIaSvA"),
  20 + //单推
  21 + push.PushType(push.PushToSingle),
20 push.ClientId("b5fff5f6b0af551da5f381fa47991828"), 22 push.ClientId("b5fff5f6b0af551da5f381fa47991828"),
  23 + //群推
  24 + //push.PushType(push.PushToList),
  25 + //push.ClientIds([]string{"b5fff5f6b0af551da5f381fa47991828"}),
21 26
22 push.MsgType(1), 27 push.MsgType(1),
23 push.Title("测试 hello"), 28 push.Title("测试 hello"),
@@ -6,8 +6,8 @@ import ( @@ -6,8 +6,8 @@ import (
6 ) 6 )
7 7
8 type Template struct { 8 type Template struct {
9 - ClientId string `json:"cid"`  
10 - RequestId string `json:"requestid"` 9 + ClientId string `json:"cid,omitempty"`
  10 + RequestId string `json:"requestid,omitempty"`
11 Message *Message `json:"message"` 11 Message *Message `json:"message"`
12 } 12 }
13 13
@@ -87,7 +87,7 @@ func resolveMsgType(msgType int) string { @@ -87,7 +87,7 @@ func resolveMsgType(msgType int) string {
87 可选项:notification、link、notypopload、startactivity, transmission 87 可选项:notification、link、notypopload、startactivity, transmission
88 */ 88 */
89 switch msgType { 89 switch msgType {
90 - case 1: 90 + case push.SystemNotification:
91 return "notification" 91 return "notification"
92 92
93 } 93 }
@@ -6,8 +6,10 @@ type Options struct { @@ -6,8 +6,10 @@ type Options struct {
6 AppSecret string 6 AppSecret string
7 AppMasterSecret string 7 AppMasterSecret string
8 ClientId string 8 ClientId string
  9 + ClientIds []string
9 10
10 - MsgType int 11 + MsgType int //消息类型
  12 + PushType int //推送类型
11 13
12 Title string 14 Title string
13 Content string 15 Content string
@@ -52,6 +54,11 @@ func ClientId(clientId string) Option { @@ -52,6 +54,11 @@ func ClientId(clientId string) Option {
52 o.ClientId = clientId 54 o.ClientId = clientId
53 } 55 }
54 } 56 }
  57 +func ClientIds(clientId []string) Option {
  58 + return func(o *Options) {
  59 + o.ClientIds = clientId
  60 + }
  61 +}
55 62
56 //消息类型 63 //消息类型
57 func MsgType(msgType int) Option { 64 func MsgType(msgType int) Option {
@@ -60,6 +67,13 @@ func MsgType(msgType int) Option { @@ -60,6 +67,13 @@ func MsgType(msgType int) Option {
60 } 67 }
61 } 68 }
62 69
  70 +//推送类型
  71 +func PushType(pushType int) Option {
  72 + return func(o *Options) {
  73 + o.PushType = pushType
  74 + }
  75 +}
  76 +
63 //消息内容 77 //消息内容
64 func Title(title string) Option { 78 func Title(title string) Option {
65 return func(o *Options) { 79 return func(o *Options) {
@@ -3,15 +3,15 @@ package protocol @@ -3,15 +3,15 @@ package protocol
3 /*PushInfo 推送信息*/ 3 /*PushInfo 推送信息*/
4 type PushInfoRequest struct { 4 type PushInfoRequest struct {
5 Type int `json:"mmmType" valid:"Required"` 5 Type int `json:"mmmType" valid:"Required"`
6 - DeviceToken string `json:"deviceToken" valid:"Required"`  
7 - ClientId string `json:"clientId" valid:"Required"` 6 + DeviceToken string `json:"deviceToken" `
  7 + ClientId string `json:"clientId"`
8 AppKey string `json:"appKey" valid:"Required"` 8 AppKey string `json:"appKey" valid:"Required"`
9 Secret string `json:"secret" valid:"Required"` 9 Secret string `json:"secret" valid:"Required"`
10 AppId string `json:"appId" valid:"Required"` 10 AppId string `json:"appId" valid:"Required"`
11 11
12 Title string `json:"title" valid:"Required"` 12 Title string `json:"title" valid:"Required"`
13 Content string `json:"content" valid:"Required"` 13 Content string `json:"content" valid:"Required"`
14 - Ext map[string]interface{} 14 + Ext map[string]interface{} `json:"ext"`
15 } 15 }
16 type PushInfoResponse struct { 16 type PushInfoResponse struct {
17 } 17 }
@@ -11,6 +11,7 @@ var nsV1 *beego.Namespace @@ -11,6 +11,7 @@ var nsV1 *beego.Namespace
11 func init() { 11 func init() {
12 nsV1 := beego.NewNamespace("v1", 12 nsV1 := beego.NewNamespace("v1",
13 beego.NSNamespace("vod", beego.NSBefore(controllers.AllowOption), beego.NSInclude(&v1.VodController{})), 13 beego.NSNamespace("vod", beego.NSBefore(controllers.AllowOption), beego.NSInclude(&v1.VodController{})),
  14 + beego.NSNamespace("push", beego.NSBefore(controllers.AllowOption), beego.NSInclude(&v1.PushController{})),
14 //beego.NSNamespace("vod", beego.NSBefore(controllers.FilterComm), beego.NSBefore(controllers.AllowOption), beego.NSInclude(&v1.VodController{})), 15 //beego.NSNamespace("vod", beego.NSBefore(controllers.FilterComm), beego.NSBefore(controllers.AllowOption), beego.NSInclude(&v1.VodController{})),
15 ) 16 )
16 beego.SetStaticPath("/log", beego.AppConfig.String("aliyun_logs_access")) 17 beego.SetStaticPath("/log", beego.AppConfig.String("aliyun_logs_access"))
@@ -4,7 +4,6 @@ import ( @@ -4,7 +4,6 @@ import (
4 "gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log" 4 "gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log"
5 "openapi/internal/push" 5 "openapi/internal/push"
6 "openapi/internal/push/getui" 6 "openapi/internal/push/getui"
7 - "openapi/internal/push/umeng"  
8 "openapi/internal/utils" 7 "openapi/internal/utils"
9 "openapi/protocol" 8 "openapi/protocol"
10 ) 9 )
@@ -13,32 +12,23 @@ import ( @@ -13,32 +12,23 @@ import (
13 func PushInfo(header *protocol.RequestHeader, request *protocol.PushInfoRequest) (rsp *protocol.PushInfoResponse, err error) { 12 func PushInfo(header *protocol.RequestHeader, request *protocol.PushInfoRequest) (rsp *protocol.PushInfoResponse, err error) {
14 var ( 13 var (
15 sendData = make(map[string]interface{}) 14 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( 15 + options []push.Option = []push.Option{
30 push.DebugModule(true), 16 push.DebugModule(true),
31 -  
32 push.AppId(request.AppId), 17 push.AppId(request.AppId),
33 push.AppKey(request.AppKey), 18 push.AppKey(request.AppKey),
34 push.AppMasterSecret(request.Secret), 19 push.AppMasterSecret(request.Secret),
35 push.ClientId(request.ClientId), 20 push.ClientId(request.ClientId),
36 21
37 push.MsgType(request.Type), 22 push.MsgType(request.Type),
  23 + push.PushType(push.PushToSingle),
  24 +
38 push.Title(request.Title), 25 push.Title(request.Title),
39 push.Content(request.Content), 26 push.Content(request.Content),
40 push.TransmissionContent(utils.JsonAssertString(request.Ext)), 27 push.TransmissionContent(utils.JsonAssertString(request.Ext)),
  28 + }
41 ) 29 )
  30 + var pushService push.INotification = &getui.GetuiNotification{}
  31 + err = pushService.Init(options...)
42 if err != nil { 32 if err != nil {
43 log.Error(err) 33 log.Error(err)
44 return 34 return