From e80afa610dd657af787b33aab03ffba15c0884c0 Mon Sep 17 00:00:00 2001 From: wangchuxiao Date: Wed, 21 Dec 2022 16:46:16 +0800 Subject: [PATCH] getui --- internal/cron_task/clear_msg.go | 25 +++---- internal/push/getui/push.go | 127 ++++++++++++++++++++++---------- pkg/common/db/RedisModel.go | 10 +++ 3 files changed, 112 insertions(+), 50 deletions(-) diff --git a/internal/cron_task/clear_msg.go b/internal/cron_task/clear_msg.go index d51e798de..51d0af7fc 100644 --- a/internal/cron_task/clear_msg.go +++ b/internal/cron_task/clear_msg.go @@ -7,11 +7,12 @@ import ( "Open_IM/pkg/common/log" server_api_params "Open_IM/pkg/proto/sdk_ws" "Open_IM/pkg/utils" - goRedis "github.com/go-redis/redis/v8" - "github.com/golang/protobuf/proto" "math" "strconv" "strings" + + goRedis "github.com/go-redis/redis/v8" + "github.com/golang/protobuf/proto" ) const oldestList = 0 @@ -105,6 +106,8 @@ func deleteMongoMsg(operationID string, ID string, index int64, delStruct *delMs if len(msgs.Msg) > db.GetSingleGocMsgNum() { log.NewWarn(operationID, utils.GetSelfFuncName(), "msgs too large", len(msgs.Msg), msgs.UID) } + lastMsgSendTime := msgs.Msg[len(msgs.Msg)-1].SendTime + var hasMsgDoNotNeedDel bool for i, msg := range msgs.Msg { // 找到列表中不需要删除的消息了, 表示为递归到最后一个块 @@ -130,20 +133,16 @@ func deleteMongoMsg(operationID string, ID string, index int64, delStruct *delMs } // 递归结束 return msgPb.Seq, nil - } else { - if !msgListIsFull(msgs) { - - } } } // 该列表中消息全部为老消息并且列表满了, 加入删除列表继续递归 - lastMsgPb := &server_api_params.MsgData{} - err = proto.Unmarshal(msgs.Msg[len(msgs.Msg)-1].Msg, lastMsgPb) - if err != nil { - log.NewError(operationID, utils.GetSelfFuncName(), err.Error(), len(msgs.Msg)-1, msgs.UID) - return 0, utils.Wrap(err, "proto.Unmarshal failed") - } - delStruct.minSeq = lastMsgPb.Seq + // lastMsgPb := &server_api_params.MsgData{} + // err = proto.Unmarshal(msgs.Msg[len(msgs.Msg)-1].Msg, lastMsgPb) + // if err != nil { + // log.NewError(operationID, utils.GetSelfFuncName(), err.Error(), len(msgs.Msg)-1, msgs.UID) + // return 0, utils.Wrap(err, "proto.Unmarshal failed") + // } + // delStruct.minSeq = lastMsgPb.Seq if msgListIsFull(msgs) { log.NewDebug(operationID, "msg list is full", msgs.UID) delStruct.delUidList = append(delStruct.delUidList, msgs.UID) diff --git a/internal/push/getui/push.go b/internal/push/getui/push.go index 5e7786e6a..ef179231f 100644 --- a/internal/push/getui/push.go +++ b/internal/push/getui/push.go @@ -26,8 +26,10 @@ var ( ) const ( - PushURL = "/push/single/alias" - AuthURL = "/auth" + PushURL = "/push/single/alias" + AuthURL = "/auth" + TaskURL = "/push/list/message" + BatchPushURL = "/push/list/alias" ) func init() { @@ -53,9 +55,16 @@ type AuthResp struct { Token string `json:"token"` } +type TaskResp struct { + TaskID string `json:"taskID"` +} + type PushReq struct { RequestID string `json:"request_id"` - Audience struct { + Settings struct { + TTL int32 `json:"ttl"` + } `json:"settings"` + Audience struct { Alias []string `json:"alias"` } `json:"audience"` PushMessage struct { @@ -66,6 +75,8 @@ type PushReq struct { Ios Ios `json:"ios"` Android Android `json:"android"` } `json:"push_channel"` + IsAsync bool `json:"is_async"` + Taskid string `json:"taskid"` } type Ios struct { @@ -121,7 +132,7 @@ func (g *Getui) Push(userIDList []string, title, detailContent, operationID stri token, err := db.DB.GetGetuiToken() log.NewDebug(operationID, utils.GetSelfFuncName(), "token:", token) if err != nil { - log.NewError(operationID, utils.OperationIDGenerator(), "GetGetuiToken failed", err.Error()) + log.NewError(operationID, utils.GetSelfFuncName(), "GetGetuiToken failed", err.Error()) } if token == "" || err != nil { token, err = g.getTokenAndSave2Redis(operationID) @@ -130,12 +141,9 @@ func (g *Getui) Push(userIDList []string, title, detailContent, operationID stri return "", utils.Wrap(err, "") } } - pushReq := PushReq{ - RequestID: utils.OperationIDGenerator(), - Audience: struct { - Alias []string `json:"alias"` - }{Alias: []string{userIDList[0]}}, - } + + var pushReq PushReq + pushResp := PushResp{} pushReq.PushMessage.Notification = Notification{ Title: title, Body: detailContent, @@ -143,34 +151,57 @@ func (g *Getui) Push(userIDList []string, title, detailContent, operationID stri ChannelID: config.Config.Push.Getui.ChannelID, ChannelName: config.Config.Push.Getui.ChannelName, } - pushReq.PushChannel.Ios.Aps.Sound = "default" - pushReq.PushChannel.Ios.Aps.Alert = Alert{ - Title: title, - Body: title, + if len(userIDList) > 1 { + taskID, err := db.DB.GetGetuiTaskID() + log.NewDebug(operationID, utils.GetSelfFuncName(), "token:", token) + if err != nil { + log.NewError(operationID, utils.GetSelfFuncName(), "GetGetuiTaskID failed", err.Error()) + } + if taskID == "" || err != nil { + taskID, err = g.GetTaskIDAndSave2Redis(operationID, token, pushReq) + if err != nil { + log.NewError(operationID, utils.GetSelfFuncName(), "GetTaskIDAndSave2Redis failed", err.Error()) + return "", utils.Wrap(err, "") + } + } + pushReq.IsAsync = true + pushReq.Taskid = taskID + err = g.request(BatchPushURL, pushReq, token, &pushResp, operationID) + } else { + pushReq := PushReq{ + RequestID: utils.OperationIDGenerator(), + Audience: struct { + Alias []string `json:"alias"` + }{Alias: []string{userIDList[0]}}, + } + pushReq.PushChannel.Ios.Aps.Sound = "default" + pushReq.PushChannel.Ios.Aps.Alert = Alert{ + Title: title, + Body: title, + } + pushReq.PushChannel.Android.Ups.Notification = Notification{ + Title: title, + Body: title, + ClickType: "startapp", + } + pushReq.PushChannel.Android.Ups.Options = Options{ + HW: struct { + DefaultSound bool `json:"/message/android/notification/default_sound"` + ChannelID string `json:"/message/android/notification/channel_id"` + Sound string `json:"/message/android/notification/sound"` + Importance string `json:"/message/android/notification/importance"` + }{ChannelID: "RingRing4", Sound: "/raw/ring001", Importance: "NORMAL"}, + XM: struct { + ChannelID string `json:"/extra.channel_id"` + }{ChannelID: "high_system"}, + VV: struct { + Classification int "json:\"/classification\"" + }{ + Classification: 1, + }, + } + err = g.request(PushURL, pushReq, token, &pushResp, operationID) } - pushReq.PushChannel.Android.Ups.Notification = Notification{ - Title: title, - Body: title, - ClickType: "startapp", - } - pushReq.PushChannel.Android.Ups.Options = Options{ - HW: struct { - DefaultSound bool `json:"/message/android/notification/default_sound"` - ChannelID string `json:"/message/android/notification/channel_id"` - Sound string `json:"/message/android/notification/sound"` - Importance string `json:"/message/android/notification/importance"` - }{ChannelID: "RingRing4", Sound: "/raw/ring001", Importance: "NORMAL"}, - XM: struct { - ChannelID string `json:"/extra.channel_id"` - }{ChannelID: "high_system"}, - VV: struct { - Classification int "json:\"/classification\"" - }{ - Classification: 1, - }, - } - pushResp := PushResp{} - err = g.request(PushURL, pushReq, token, &pushResp, operationID) switch err { case TokenExpireError: token, err = g.getTokenAndSave2Redis(operationID) @@ -209,6 +240,15 @@ func (g *Getui) Auth(operationID string, timeStamp int64) (token string, expireT return respAuth.Token, int64(expire), err } +func (g *Getui) GetTaskID(operationID, token string, pushReq PushReq) (string, error) { + respTask := TaskResp{} + err := g.request(TaskURL, pushReq, token, &respTask, operationID) + if err != nil { + return "", utils.Wrap(err, "") + } + return respTask.TaskID, nil +} + func (g *Getui) request(url string, content interface{}, token string, returnStruct interface{}, operationID string) error { con, err := json.Marshal(content) if err != nil { @@ -257,3 +297,16 @@ func (g *Getui) getTokenAndSave2Redis(operationID string) (token string, err err } return token, nil } + +func (g *Getui) GetTaskIDAndSave2Redis(operationID, token string, pushReq PushReq) (taskID string, err error) { + pushReq.Settings.TTL = 1000 * 60 * 60 * 24 + taskID, err = g.GetTaskID(operationID, token, pushReq) + if err != nil { + return "", utils.Wrap(err, "GetTaskIDAndSave2Redis failed") + } + err = db.DB.SetGetuiTaskID(taskID, 60*60*23) + if err != nil { + return "", utils.Wrap(err, "Auth failed") + } + return token, nil +} diff --git a/pkg/common/db/RedisModel.go b/pkg/common/db/RedisModel.go index a0eab5c30..9e1a5096c 100644 --- a/pkg/common/db/RedisModel.go +++ b/pkg/common/db/RedisModel.go @@ -28,6 +28,7 @@ const ( uidPidToken = "UID_PID_TOKEN_STATUS:" conversationReceiveMessageOpt = "CON_RECV_MSG_OPT:" getuiToken = "GETUI_TOKEN" + getuiTaskID = "GETUI_TASK_ID" messageCache = "MESSAGE_CACHE:" SignalCache = "SIGNAL_CACHE:" SignalListCache = "SIGNAL_LIST_CACHE:" @@ -397,6 +398,15 @@ func (d *DataBases) GetGetuiToken() (string, error) { return result, err } +func (d *DataBases) SetGetuiTaskID(taskID string, expireTime int64) error { + return d.RDB.Set(context.Background(), getuiTaskID, taskID, time.Duration(expireTime)*time.Second).Err() +} + +func (d *DataBases) GetGetuiTaskID() (string, error) { + result, err := d.RDB.Get(context.Background(), getuiTaskID).Result() + return result, err +} + func (d *DataBases) SetSendMsgStatus(status int32, operationID string) error { return d.RDB.Set(context.Background(), sendMsgFailedFlag+operationID, status, time.Hour*24).Err() }