feat: msg filter and search system account

pull/3151/head
icey-yu 7 months ago
parent a3c43a49d8
commit 70721836b6

@ -3,14 +3,7 @@ beforeSendSingleMsg:
enable: false
timeout: 5
failedContinue: true
# Only the contentType in allowedTypes will send the callback.
# Supports two formats: a single type or a range. The range is defined by the lower and upper bounds connected with a hyphen ("-").
# e.g. allowedTypes: [1, 100, 200-500, 600-700] means that only contentType within the range
# {1, 100} [200, 500] [600, 700] will be allowed through the filter.
# If not set, all contentType messages will through this filter.
allowedTypes: []
# Only the contentType not in deniedTypes will send the callback.
# Supports two formats, same as allowedTypes.
# If not set, all contentType messages will through this filter.
deniedTypes: []
beforeUpdateUserInfoEx:
@ -23,31 +16,30 @@ afterUpdateUserInfoEx:
afterSendSingleMsg:
enable: false
timeout: 5
# Only the senID/recvID specified in attentionIds will send the callback
# Only the recvID specified in attentionIds will send the callback
# if not set, all user messages will be callback
attentionIds: []
# See beforeSendSingleMsg comment.
allowedTypes: []
deniedTypes: []
beforeSendGroupMsg:
enable: false
timeout: 5
failedContinue: true
# See beforeSendSingleMsg comment.
allowedTypes: []
deniedTypes: []
beforeMsgModify:
enable: false
timeout: 5
failedContinue: true
# See beforeSendSingleMsg comment.
allowedTypes: []
deniedTypes: []
afterSendGroupMsg:
enable: false
timeout: 5
# Only the recvID specified in attentionIds will send the callback
# if not set, all user messages will be callback
attentionIds: []
# See beforeSendSingleMsg comment.
allowedTypes: []
deniedTypes: []
afterUserOnline:
enable: false

@ -12,7 +12,7 @@ require (
github.com/gorilla/websocket v1.5.1
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/mitchellh/mapstructure v1.5.0
github.com/openimsdk/protocol v0.0.72-alpha.71
github.com/openimsdk/protocol v0.0.72-alpha.72
github.com/openimsdk/tools v0.0.50-alpha.70
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.18.0
@ -219,3 +219,7 @@ require (
golang.org/x/crypto v0.27.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)
replace (
github.com/openimsdk/protocol v0.0.72-alpha.72 => C:\App\Project\protocol
)

@ -349,6 +349,7 @@ github.com/openimsdk/gomake v0.0.15-alpha.2 h1:5Q8yl8ezy2yx+q8/ucU/t4kJnDfCzNOrk
github.com/openimsdk/gomake v0.0.15-alpha.2/go.mod h1:PndCozNc2IsQIciyn9mvEblYWZwJmAI+06z94EY+csI=
github.com/openimsdk/protocol v0.0.72-alpha.71 h1:R3utzOlqepaJWTAmnfJi4ccUM/XIoFasSyjQMOipM70=
github.com/openimsdk/protocol v0.0.72-alpha.71/go.mod h1:WF7EuE55vQvpyUAzDXcqg+B+446xQyEba0X35lTINmw=
github.com/openimsdk/protocol v0.0.72-alpha.72/go.mod h1:WF7EuE55vQvpyUAzDXcqg+B+446xQyEba0X35lTINmw=
github.com/openimsdk/tools v0.0.50-alpha.70 h1:pyqWkJzXbELWU9KKAsWkj3g0flJYNsDTcjR5SLFQAZU=
github.com/openimsdk/tools v0.0.50-alpha.70/go.mod h1:B+oqV0zdewN7OiEHYJm+hW+8/Te7B8tHHgD8rK5ZLZk=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=

@ -1,11 +1,13 @@
package msg
import (
"strconv"
"strings"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/protocol/constant"
pbchat "github.com/openimsdk/protocol/msg"
"github.com/openimsdk/tools/utils/datautil"
"strconv"
"strings"
)
const (
@ -13,28 +15,50 @@ const (
)
func filterAfterMsg(msg *pbchat.SendMsgReq, after *config.AfterConfig) bool {
return filterMsg(msg, after.AttentionIds, after.AllowedTypes, after.DeniedTypes)
return filterMsg(msg, after.AttentionIds, after.DeniedTypes)
}
func filterBeforeMsg(msg *pbchat.SendMsgReq, before *config.BeforeConfig) bool {
return filterMsg(msg, nil, before.AllowedTypes, before.DeniedTypes)
return filterMsg(msg, nil, before.DeniedTypes)
}
func filterMsg(msg *pbchat.SendMsgReq, attentionIds, allowedTypes, deniedTypes []string) bool {
func filterMsg(msg *pbchat.SendMsgReq, attentionIds []string, deniedTypes []int32) bool {
// According to the attentionIds configuration, only some users are sent
if len(attentionIds) != 0 && !datautil.Contains([]string{msg.MsgData.SendID, msg.MsgData.RecvID}, attentionIds...) {
if len(attentionIds) != 0 && !datautil.Contain(msg.MsgData.RecvID, attentionIds...) {
return false
}
if len(allowedTypes) != 0 && !isInInterval(msg.MsgData.ContentType, allowedTypes) {
if defaultDeniedTypes(msg.MsgData.ContentType) {
return false
}
if len(deniedTypes) != 0 && isInInterval(msg.MsgData.ContentType, deniedTypes) {
if len(deniedTypes) != 0 && datautil.Contain(msg.MsgData.ContentType, deniedTypes...) {
return false
}
//if len(allowedTypes) != 0 && !isInInterval(msg.MsgData.ContentType, allowedTypes) {
// return false
//}
//if len(deniedTypes) != 0 && isInInterval(msg.MsgData.ContentType, deniedTypes) {
// return false
//}
return true
}
func isInInterval(contentType int32, interval []string) bool {
func defaultDeniedTypes(contentType int32) bool {
if contentType >= constant.NotificationBegin && contentType <= constant.NotificationEnd {
return true
}
if contentType == constant.Typing {
return true
}
return false
}
// isInInterval if data is in interval
// Supports two formats: a single type or a range. The range is defined by the lower and upper bounds connected with a hyphen ("-")
// e.g. [1, 100, 200-500, 600-700] means that only data within the range
// {1, 100} [200, 500] [600, 700] will return true.
func isInInterval(data int32, interval []string) bool {
for _, v := range interval {
if strings.Contains(v, separator) {
// is interval
@ -50,7 +74,7 @@ func isInInterval(contentType int32, interval []string) bool {
if err != nil {
continue
}
if datautil.BetweenEq(int(contentType), bottom, top) {
if datautil.BetweenEq(int(data), bottom, top) {
return true
}
} else {
@ -58,7 +82,7 @@ func isInInterval(contentType int32, interval []string) bool {
if err != nil {
continue
}
if int(contentType) == iv {
if int(data) == iv {
return true
}
}

@ -566,7 +566,7 @@ func (s *userServer) SearchNotificationAccount(ctx context.Context, req *pbuser.
}
// Convert users to response format
resp := s.userModelToResp(users, req.Pagination)
resp := s.userModelToResp(users, req.Pagination, req.AppManagerLevel)
if resp.Total != 0 {
return resp, nil
}
@ -576,17 +576,24 @@ func (s *userServer) SearchNotificationAccount(ctx context.Context, req *pbuser.
if err != nil {
return nil, err
}
resp = s.userModelToResp(users, req.Pagination)
resp = s.userModelToResp(users, req.Pagination, req.AppManagerLevel)
return resp, nil
}
// If no keyword, find users with notification settings
users, err = s.db.FindNotification(ctx, constant.AppNotificationAdmin)
if req.AppManagerLevel != nil {
users, err = s.db.FindNotification(ctx, *req.AppManagerLevel)
if err != nil {
return nil, err
}
} else {
users, err = s.db.FindSystemAccount(ctx)
if err != nil {
return nil, err
}
}
resp := s.userModelToResp(users, req.Pagination)
resp := s.userModelToResp(users, req.Pagination, req.AppManagerLevel)
return resp, nil
}
@ -625,11 +632,16 @@ func (s *userServer) genUserID() string {
return string(data)
}
func (s *userServer) userModelToResp(users []*tablerelation.User, pagination pagination.Pagination) *pbuser.SearchNotificationAccountResp {
func (s *userServer) userModelToResp(users []*tablerelation.User, pagination pagination.Pagination, appManagerLevel *int32) *pbuser.SearchNotificationAccountResp {
accounts := make([]*pbuser.NotificationAccountInfo, 0)
var total int64
for _, v := range users {
if v.AppMangerLevel >= constant.AppNotificationAdmin && !datautil.Contain(v.UserID, s.config.Share.IMAdminUserID...) {
if appManagerLevel != nil {
if v.AppMangerLevel != *appManagerLevel {
continue
}
}
temp := &pbuser.NotificationAccountInfo{
UserID: v.UserID,
FaceURL: v.FaceURL,

@ -367,16 +367,14 @@ type BeforeConfig struct {
Enable bool `mapstructure:"enable"`
Timeout int `mapstructure:"timeout"`
FailedContinue bool `mapstructure:"failedContinue"`
AllowedTypes []string `mapstructure:"allowedTypes"`
DeniedTypes []string `mapstructure:"deniedTypes"`
DeniedTypes []int32 `mapstructure:"deniedTypes"`
}
type AfterConfig struct {
Enable bool `mapstructure:"enable"`
Timeout int `mapstructure:"timeout"`
AttentionIds []string `mapstructure:"attentionIds"`
AllowedTypes []string `mapstructure:"allowedTypes"`
DeniedTypes []string `mapstructure:"deniedTypes"`
DeniedTypes []int32 `mapstructure:"deniedTypes"`
}
type Share struct {

@ -20,6 +20,7 @@ import (
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
"github.com/openimsdk/protocol/constant"
"github.com/openimsdk/tools/db/pagination"
"github.com/openimsdk/tools/db/tx"
"github.com/openimsdk/tools/utils/datautil"
@ -37,8 +38,10 @@ type UserDatabase interface {
Find(ctx context.Context, userIDs []string) (users []*model.User, err error)
// Find userInfo By Nickname
FindByNickname(ctx context.Context, nickname string) (users []*model.User, err error)
// Find notificationAccounts
FindNotification(ctx context.Context, level int64) (users []*model.User, err error)
// FindNotification find system account by level
FindNotification(ctx context.Context, level int32) (users []*model.User, err error)
// FindSystemAccount find all system account
FindSystemAccount(ctx context.Context) (users []*model.User, err error)
// Create Insert multiple external guarantees that the userID is not repeated and does not exist in the storage
Create(ctx context.Context, users []*model.User) (err error)
// UpdateByMap update (zero value) external guarantee userID exists
@ -139,6 +142,10 @@ func (u *userDatabase) FindNotification(ctx context.Context, level int64) (users
return u.userDB.TakeNotification(ctx, level)
}
func (u *userDatabase) FindSystemAccount(ctx context.Context) (users []*model.User, err error) {
return u.userDB.TakeGTEAppManagerLevel(ctx, constant.AppNotificationAdmin)
}
// Create Insert multiple external guarantees that the userID is not repeated and does not exist in the storage.
func (u *userDatabase) Create(ctx context.Context, users []*model.User) (err error) {
return u.tx.Transaction(ctx, func(ctx context.Context) error {

@ -16,9 +16,10 @@ package mgo
import (
"context"
"time"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
"time"
"github.com/openimsdk/protocol/user"
"github.com/openimsdk/tools/db/mongoutil"
@ -71,6 +72,10 @@ func (u *UserMgo) TakeNotification(ctx context.Context, level int64) (user []*mo
return mongoutil.Find[*model.User](ctx, u.coll, bson.M{"app_manger_level": level})
}
func (u *UserMgo) TakeGTEAppManagerLevel(ctx context.Context, level int64) (user []*model.User, err error) {
return mongoutil.Find[*model.User](ctx, u.coll, bson.M{"app_manager_level": bson.M{"$gte": level}})
}
func (u *UserMgo) TakeByNickname(ctx context.Context, nickname string) (user []*model.User, err error) {
return mongoutil.Find[*model.User](ctx, u.coll, bson.M{"nickname": nickname})
}

@ -16,10 +16,11 @@ package database
import (
"context"
"time"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
"github.com/openimsdk/protocol/user"
"github.com/openimsdk/tools/db/pagination"
"time"
)
type User interface {
@ -28,6 +29,7 @@ type User interface {
Find(ctx context.Context, userIDs []string) (users []*model.User, err error)
Take(ctx context.Context, userID string) (user *model.User, err error)
TakeNotification(ctx context.Context, level int64) (user []*model.User, err error)
TakeGTEAppManagerLevel(ctx context.Context, level int64) (user []*model.User, err error)
TakeByNickname(ctx context.Context, nickname string) (user []*model.User, err error)
Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*model.User, err error)
PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*model.User, err error)

Loading…
Cancel
Save