作者 yangfu

个推 增加群推功能

package push
/*
Map key
PushType 推送类型
*/
const ()
const (
PushToSingle = iota + 1 //单推
PushToList //群推
)
/*
MsgType 消息类型 -> 决定发送的模板样式
*/
const (
SystemNotification = iota + 1 //系统消息
)
... ...
... ... @@ -12,10 +12,12 @@ import (
"time"
)
var (
host = "https://restapi.getui.com"
pushSingle = "push_single"
authSign = "auth_sign "
const (
host = "https://restapi.getui.com"
pushSingle = "push_single"
saveListBody = "save_list_body"
pushList = "push_list"
authSign = "auth_sign "
)
var (
... ... @@ -25,6 +27,7 @@ var (
expireSpan = time.Second * 3600 * 6
)
//GetuiNotification 个推消息推送
type GetuiNotification struct {
Options *push.Options
Request *httplib.BeegoHTTPRequest
... ... @@ -37,36 +40,133 @@ func (notify *GetuiNotification) Init(options ...push.Option) error {
}
return nil
}
func (notify *GetuiNotification) Send(option map[string]interface{}) error {
token, err := notify.GetAuthToken()
func (notify *GetuiNotification) Send(option map[string]interface{}) (err error) {
switch notify.Options.PushType {
case push.PushToSingle:
err = notify.pushToSingle(option)
case push.PushToList:
err = notify.pushToList(option)
default:
err = notify.pushToSingle(option)
}
if err != nil {
return err
}
return nil
}
//pushToSingle 单推
func (notify *GetuiNotification) pushToSingle(option map[string]interface{}) (err error) {
var token string
if token, err = notify.GetAuthToken(); err != nil {
return err
}
var (
result *Result
url = notify.Url(notify.Options.AppId, pushSingle)
m = notify.Message(pushSingle)
)
notify.Request = httplib.Post(url)
notify.Request.Header("authtoken", token)
notify.Request.JSONBody(m)
if err = notify.Request.ToJSON(&result); err != nil {
return err
}
notify.print(url, m, result, result)
if err = handleResult(url, result); err != nil {
return err
}
return nil
}
//pushToList 群推
//步骤1.获取token
//步骤2.save_list_body保存消息共同体
//步骤3.push_list
func (notify *GetuiNotification) pushToList(option map[string]interface{}) (err error) {
var (
token string
taskId string
)
if token, err = notify.GetAuthToken(); err != nil {
return err
}
if taskId, err = notify.saveListBody(token, option); err != nil {
return err
}
var (
result *Result
url = notify.Url(notify.Options.AppId, pushList)
m = struct {
Cid []string `json:"cid"`
TaskId string `json:"taskid"`
NeedDetail bool `json:"need_detail"`
}{
Cid: notify.Options.ClientIds,
TaskId: taskId,
NeedDetail: true,
}
)
notify.Request = httplib.Post(url)
notify.Request.Header("authtoken", token)
notify.Request.JSONBody(notify.Message())
notify.Request.JSONBody(m)
if err = notify.Request.ToJSON(&result); err != nil {
return err
}
notify.print(url, notify.Message(), result, result)
notify.print(url, m, result, result)
if err = handleResult(url, result); err != nil {
return err
}
return nil
}
func (notify *GetuiNotification) Message() interface{} {
//TODO:默认通知模板
m := NewNotificationTemplate(notify.Options)
//saveListBody 保存消息共同体
func (notify *GetuiNotification) saveListBody(token string, option map[string]interface{}) (taskId string, err error) {
var (
result *Result
url = notify.Url(notify.Options.AppId, saveListBody)
m = notify.Message(saveListBody)
)
notify.Request = httplib.Post(url)
notify.Request.Header("authtoken", token)
notify.Request.JSONBody(m)
if err = notify.Request.ToJSON(&result); err != nil {
return
}
notify.print(url, m, result, result)
if err = handleResult(url, result); err != nil {
return
}
taskId = result.TaskId
return
}
//Message 组装消息体
func (notify *GetuiNotification) Message(method string) interface{} {
var m interface{}
switch notify.Options.MsgType {
case push.SystemNotification:
t := NewNotificationTemplate(notify.Options)
if method == saveListBody {
t.ClientId = ""
t.RequestId = ""
}
m = t
break
default:
m = NewNotificationTemplate(notify.Options)
break
}
return m
}
//Url 组装请求地址
func (notify *GetuiNotification) Url(param string, method string) string {
return fmt.Sprintf("%v/v1/%v/%v", host, param, method)
}
//GetAuthToken 获取token
func (notify *GetuiNotification) GetAuthToken() (token string, err error) {
if authtoken != "" && expire.Unix() > time.Now().Unix() {
token = authtoken
... ... @@ -100,6 +200,16 @@ func (notify *GetuiNotification) GetAuthToken() (token string, err error) {
expire = time.Now().Add(expireSpan)
return
}
//打印日志 debug_module=true print debug log
func (notify *GetuiNotification) print(url string, v interface{}, rsp interface{}, result *Result) {
if !notify.Options.DebugModule {
return
}
log.Error(fmt.Sprintf("【个推】 url:%v \n request:%v \n response:%v 结果:%v", url, utils.JsonAssertString(v), utils.JsonAssertString(rsp), result.Result))
}
//处理结果
func handleResult(url string, result *Result) (err error) {
if strings.ToLower(result.Result) == "ok" {
return
... ... @@ -112,9 +222,3 @@ func sign(appkey, timestamp, mastersecret string) string {
sha.Write([]byte(appkey + timestamp + mastersecret))
return fmt.Sprintf("%x", sha.Sum(nil))
}
func (notify *GetuiNotification) print(url string, v interface{}, rsp interface{}, result *Result) {
if !notify.Options.DebugModule {
return
}
log.Error(fmt.Sprintf("【个推】 url:%v \n request:%v \n response:%v 结果:%v", url, utils.JsonAssertString(v), utils.JsonAssertString(rsp), result.Result))
}
... ...
... ... @@ -17,7 +17,12 @@ func TestGetui(t *testing.T) {
push.AppId("TkpBI4awmg9fBUx3NWKXS6"),
push.AppKey("5AjJeDOSOZ5ojQpXJFjhg9"),
push.AppMasterSecret("9VnM8MaA6n84Y5VnOIaSvA"),
//单推
push.PushType(push.PushToSingle),
push.ClientId("b5fff5f6b0af551da5f381fa47991828"),
//群推
//push.PushType(push.PushToList),
//push.ClientIds([]string{"b5fff5f6b0af551da5f381fa47991828"}),
push.MsgType(1),
push.Title("测试 hello"),
... ...
... ... @@ -6,8 +6,8 @@ import (
)
type Template struct {
ClientId string `json:"cid"`
RequestId string `json:"requestid"`
ClientId string `json:"cid,omitempty"`
RequestId string `json:"requestid,omitempty"`
Message *Message `json:"message"`
}
... ... @@ -87,7 +87,7 @@ func resolveMsgType(msgType int) string {
可选项:notification、link、notypopload、startactivity, transmission
*/
switch msgType {
case 1:
case push.SystemNotification:
return "notification"
}
... ...
... ... @@ -6,8 +6,10 @@ type Options struct {
AppSecret string
AppMasterSecret string
ClientId string
ClientIds []string
MsgType int
MsgType int //消息类型
PushType int //推送类型
Title string
Content string
... ... @@ -52,6 +54,11 @@ func ClientId(clientId string) Option {
o.ClientId = clientId
}
}
func ClientIds(clientId []string) Option {
return func(o *Options) {
o.ClientIds = clientId
}
}
//消息类型
func MsgType(msgType int) Option {
... ... @@ -60,6 +67,13 @@ func MsgType(msgType int) Option {
}
}
//推送类型
func PushType(pushType int) Option {
return func(o *Options) {
o.PushType = pushType
}
}
//消息内容
func Title(title string) Option {
return func(o *Options) {
... ...
... ... @@ -3,15 +3,15 @@ package protocol
/*PushInfo 推送信息*/
type PushInfoRequest struct {
Type int `json:"mmmType" valid:"Required"`
DeviceToken string `json:"deviceToken" valid:"Required"`
ClientId string `json:"clientId" valid:"Required"`
DeviceToken string `json:"deviceToken" `
ClientId string `json:"clientId"`
AppKey string `json:"appKey" valid:"Required"`
Secret string `json:"secret" valid:"Required"`
AppId string `json:"appId" valid:"Required"`
Title string `json:"title" valid:"Required"`
Content string `json:"content" valid:"Required"`
Ext map[string]interface{}
Title string `json:"title" valid:"Required"`
Content string `json:"content" valid:"Required"`
Ext map[string]interface{} `json:"ext"`
}
type PushInfoResponse struct {
}
... ...
... ... @@ -11,6 +11,7 @@ var nsV1 *beego.Namespace
func init() {
nsV1 := beego.NewNamespace("v1",
beego.NSNamespace("vod", beego.NSBefore(controllers.AllowOption), beego.NSInclude(&v1.VodController{})),
beego.NSNamespace("push", beego.NSBefore(controllers.AllowOption), beego.NSInclude(&v1.PushController{})),
//beego.NSNamespace("vod", beego.NSBefore(controllers.FilterComm), beego.NSBefore(controllers.AllowOption), beego.NSInclude(&v1.VodController{})),
)
beego.SetStaticPath("/log", beego.AppConfig.String("aliyun_logs_access"))
... ...
... ... @@ -4,7 +4,6 @@ import (
"gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log"
"openapi/internal/push"
"openapi/internal/push/getui"
"openapi/internal/push/umeng"
"openapi/internal/utils"
"openapi/protocol"
)
... ... @@ -12,33 +11,24 @@ import (
//推送信息
func PushInfo(header *protocol.RequestHeader, request *protocol.PushInfoRequest) (rsp *protocol.PushInfoResponse, err error) {
var (
sendData = make(map[string]interface{})
)
var pushService push.INotification = &getui.GetuiNotification{}
sendData = make(map[string]interface{})
options []push.Option = []push.Option{
push.DebugModule(true),
push.AppId(request.AppId),
push.AppKey(request.AppKey),
push.AppMasterSecret(request.Secret),
push.ClientId(request.ClientId),
sendData["DeviceType"] = header.DeviceType
sendData[umeng.AppKey] = request.AppKey
sendData[umeng.DeviceTokens] = request.DeviceToken
sendData[umeng.DisplayType] = umeng.Notification
sendData[umeng.Title] = request.Title
sendData[umeng.Text] = request.Content
sendData[umeng.Extra] = request.Ext
sendData[umeng.Type] = "unicast"
push.MsgType(request.Type),
push.PushType(push.PushToSingle),
err = pushService.Init(
push.DebugModule(true),
push.AppId(request.AppId),
push.AppKey(request.AppKey),
push.AppMasterSecret(request.Secret),
push.ClientId(request.ClientId),
push.MsgType(request.Type),
push.Title(request.Title),
push.Content(request.Content),
push.TransmissionContent(utils.JsonAssertString(request.Ext)),
push.Title(request.Title),
push.Content(request.Content),
push.TransmissionContent(utils.JsonAssertString(request.Ext)),
}
)
var pushService push.INotification = &getui.GetuiNotification{}
err = pushService.Init(options...)
if err != nil {
log.Error(err)
return
... ...