service/library/middleware/notif_sender.go

185 lines
5.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package middleware
import (
"fmt"
"service/apollostruct"
"service/app/mix/service"
"service/app/mix/service/logic"
"service/dbstruct"
"service/library/apollo"
"service/library/logger"
"service/api/consts"
notificationproto "service/api/proto/notification/proto"
goproto "google.golang.org/protobuf/proto"
"github.com/gin-gonic/gin"
)
var (
DefaultNotifSender gin.HandlerFunc
)
func InitNotifSender(_DefaultNotification *logic.Notification, _DefaultNotifBcstVers *logic.NotifBcstVers, _DefaultNotifBcstCenter *service.NotifBcstCenter) {
DefaultNotifSender = func(ctx *gin.Context) {
// 获取通知builder
notifBuildersObj, ok := ctx.Get("notif_builders")
if !ok {
return
}
notifBuilders := notifBuildersObj.([]*dbstruct.NotifBuilder)
for _, notifBuilder := range notifBuilders {
// 如果是取消推送,则更新推送状态为已取消
if CancelNotif(ctx, notifBuilder, _DefaultNotification) {
continue
}
// 如果是同步广播版本号,则进行同步
if SyncNotifBcstVers(ctx, notifBuilder, _DefaultNotifBcstVers) {
continue
}
// 组装通知
notification, err := AssembleNotification(notifBuilder)
if err != nil {
logger.Error("通知组装失败:%v", err)
continue
}
// 创建通知
err = _DefaultNotification.OpCreate(ctx, &notificationproto.OpCreateReq{
Notification: notification,
})
if err != nil {
logger.Error("通知创建失败:%v", err)
continue
}
// 将通知id暂存若暂存失败则不广播该条通知因业务无法再控制其停止
if notifBuilder.SetNid != nil {
err = notifBuilder.SetNid(ctx, notification.GetId())
if err != nil {
logger.Error("通知id暂存失败:%v", err)
continue
}
}
nids := make([]int64, 0)
nids = append(nids, notification.GetId())
// 广播通知
if notification.GetPushTime() == consts.Notification_PushTime_Instant {
err = _DefaultNotifBcstCenter.BcstNotifs(ctx, nids, notification.GetObjType(), notification.ObjMids)
if err != nil {
logger.Error("通知广播失败:%v", err)
continue
}
}
}
ctx.Next()
}
}
func NotifSender() gin.HandlerFunc {
return DefaultNotifSender
}
func CancelNotif(ctx *gin.Context, notifBuilder *dbstruct.NotifBuilder, notifService *logic.Notification) bool {
if notifBuilder.TemplateId == consts.CtrlNotifTemp_CancelNotif {
err := notifService.OpUpdate(ctx, &notificationproto.OpUpdateReq{
Notification: &dbstruct.Notification{
Id: goproto.Int64(notifBuilder.GetNid()),
Status: goproto.Int64(consts.Notification_Cancelled),
},
})
if err != nil {
logger.Error("_DefaultNotification OpUpdate failed : %v", err)
}
return true
}
return false
}
func SyncNotifBcstVers(ctx *gin.Context, notifBuilder *dbstruct.NotifBuilder, notifBcstVersService *logic.NotifBcstVers) bool {
objType := int64(-1)
if notifBuilder.TemplateId == consts.CtrlNotifTemp_SyncNotifBcstVersForUser {
objType = consts.Notification_ObjType_AllUser
} else if notifBuilder.TemplateId == consts.CtrlNotifTemp_SyncNotifBcstVersForStreamer {
objType = consts.Notification_ObjType_AllStreamer
}
if objType != -1 {
// 获取当前主播/用户全局广播的版本号(注意这个版本号-1才是当前数据库有的最新版本号
notifBcstVers, err := notifBcstVersService.GetNotifBcstVers(ctx, objType)
if err != nil {
logger.Error("GetNotifBcstVers fail, err: %v", err)
return true
}
// 获取该主播/用户已接收的全局广播版本号,并直接更新至最新的全局广播版本号
for _, mid := range notifBuilder.ObjMids {
_, err = notifBcstVersService.GetAndUpdateNotifBcstReceiveVers(ctx, mid, notifBcstVers.Vers)
if err != nil {
logger.Error("GetAndUpdateNotifBcstReceiveVers fail, err: %v", err)
return true
}
}
return true
} else {
return false
}
}
func AssembleNotification(notifBuilder *dbstruct.NotifBuilder) (*dbstruct.Notification, error) {
notification := &dbstruct.Notification{}
notification.SubMid = goproto.Int64(0)
// 从模板Id拿到模板信息
key := fmt.Sprint(notifBuilder.TemplateId)
cfg := apollostruct.NotifTemplateCfg{}
err := apollo.GetJson(key, &cfg, apollo.ApolloOpts().SetNamespace("notif_template"))
if err != nil {
logger.Error("Apollo read failed : %v", err)
return nil, err
}
// 通知接收人mids不为空则默认认为是自定义发送
if len(notifBuilder.ObjMids) > 0 {
notification.ObjMids = notifBuilder.ObjMids
notification.ObjType = goproto.Int64(consts.Notification_ObjType_Customized)
} else {
notification.ObjType = goproto.Int64(notifBuilder.ObjType)
}
// 消息类型
notification.NType = goproto.Int64(cfg.NType)
notification.NDesc = goproto.String(consts.NotifDescMap[cfg.NType])
// 拼装通知信息
msg := fmt.Sprintf(cfg.NotifTemplate, notifBuilder.TemplateParams...)
notification.Message = goproto.String(msg)
// 链接信息
if notifBuilder.Action != "" {
linkText := fmt.Sprintf(cfg.LinkTextTemplate, notifBuilder.LinkTextTemplateParams...)
notification.LinkText = goproto.String(linkText)
notification.Action = goproto.String(notifBuilder.Action)
notification.Thumbnail = notifBuilder.Thumbnail
notification.Params = goproto.String(notifBuilder.Params)
}
// 推送时间
notification.PushTime = goproto.Int64(notifBuilder.PushTime)
return notification, nil
}