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 enable: false
timeout: 5 timeout: 5
failedContinue: true 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. # 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. # If not set, all contentType messages will through this filter.
deniedTypes: [] deniedTypes: []
beforeUpdateUserInfoEx: beforeUpdateUserInfoEx:
@ -23,31 +16,30 @@ afterUpdateUserInfoEx:
afterSendSingleMsg: afterSendSingleMsg:
enable: false enable: false
timeout: 5 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 # if not set, all user messages will be callback
attentionIds: [] attentionIds: []
# See beforeSendSingleMsg comment. # See beforeSendSingleMsg comment.
allowedTypes: []
deniedTypes: [] deniedTypes: []
beforeSendGroupMsg: beforeSendGroupMsg:
enable: false enable: false
timeout: 5 timeout: 5
failedContinue: true failedContinue: true
# See beforeSendSingleMsg comment. # See beforeSendSingleMsg comment.
allowedTypes: []
deniedTypes: [] deniedTypes: []
beforeMsgModify: beforeMsgModify:
enable: false enable: false
timeout: 5 timeout: 5
failedContinue: true failedContinue: true
# See beforeSendSingleMsg comment. # See beforeSendSingleMsg comment.
allowedTypes: []
deniedTypes: [] deniedTypes: []
afterSendGroupMsg: afterSendGroupMsg:
enable: false enable: false
timeout: 5 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. # See beforeSendSingleMsg comment.
allowedTypes: []
deniedTypes: [] deniedTypes: []
afterUserOnline: afterUserOnline:
enable: false enable: false

@ -12,7 +12,7 @@ require (
github.com/gorilla/websocket v1.5.1 github.com/gorilla/websocket v1.5.1
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/mitchellh/mapstructure v1.5.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/openimsdk/tools v0.0.50-alpha.70
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.18.0 github.com/prometheus/client_golang v1.18.0
@ -219,3 +219,7 @@ require (
golang.org/x/crypto v0.27.0 // indirect golang.org/x/crypto v0.27.0 // indirect
gopkg.in/ini.v1 v1.67.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/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 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.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 h1:pyqWkJzXbELWU9KKAsWkj3g0flJYNsDTcjR5SLFQAZU=
github.com/openimsdk/tools v0.0.50-alpha.70/go.mod h1:B+oqV0zdewN7OiEHYJm+hW+8/Te7B8tHHgD8rK5ZLZk= 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= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=

@ -1,11 +1,13 @@
package msg package msg
import ( import (
"strconv"
"strings"
"github.com/openimsdk/open-im-server/v3/pkg/common/config" "github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/protocol/constant"
pbchat "github.com/openimsdk/protocol/msg" pbchat "github.com/openimsdk/protocol/msg"
"github.com/openimsdk/tools/utils/datautil" "github.com/openimsdk/tools/utils/datautil"
"strconv"
"strings"
) )
const ( const (
@ -13,28 +15,50 @@ const (
) )
func filterAfterMsg(msg *pbchat.SendMsgReq, after *config.AfterConfig) bool { 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 { 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 // 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 return false
} }
if len(allowedTypes) != 0 && !isInInterval(msg.MsgData.ContentType, allowedTypes) {
if defaultDeniedTypes(msg.MsgData.ContentType) {
return false return false
} }
if len(deniedTypes) != 0 && isInInterval(msg.MsgData.ContentType, deniedTypes) {
if len(deniedTypes) != 0 && datautil.Contain(msg.MsgData.ContentType, deniedTypes...) {
return false 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 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 { for _, v := range interval {
if strings.Contains(v, separator) { if strings.Contains(v, separator) {
// is interval // is interval
@ -50,7 +74,7 @@ func isInInterval(contentType int32, interval []string) bool {
if err != nil { if err != nil {
continue continue
} }
if datautil.BetweenEq(int(contentType), bottom, top) { if datautil.BetweenEq(int(data), bottom, top) {
return true return true
} }
} else { } else {
@ -58,7 +82,7 @@ func isInInterval(contentType int32, interval []string) bool {
if err != nil { if err != nil {
continue continue
} }
if int(contentType) == iv { if int(data) == iv {
return true return true
} }
} }

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

@ -364,19 +364,17 @@ type Redis struct {
} }
type BeforeConfig struct { type BeforeConfig struct {
Enable bool `mapstructure:"enable"` Enable bool `mapstructure:"enable"`
Timeout int `mapstructure:"timeout"` Timeout int `mapstructure:"timeout"`
FailedContinue bool `mapstructure:"failedContinue"` FailedContinue bool `mapstructure:"failedContinue"`
AllowedTypes []string `mapstructure:"allowedTypes"` DeniedTypes []int32 `mapstructure:"deniedTypes"`
DeniedTypes []string `mapstructure:"deniedTypes"`
} }
type AfterConfig struct { type AfterConfig struct {
Enable bool `mapstructure:"enable"` Enable bool `mapstructure:"enable"`
Timeout int `mapstructure:"timeout"` Timeout int `mapstructure:"timeout"`
AttentionIds []string `mapstructure:"attentionIds"` AttentionIds []string `mapstructure:"attentionIds"`
AllowedTypes []string `mapstructure:"allowedTypes"` DeniedTypes []int32 `mapstructure:"deniedTypes"`
DeniedTypes []string `mapstructure:"deniedTypes"`
} }
type Share struct { 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/database"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "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/pagination"
"github.com/openimsdk/tools/db/tx" "github.com/openimsdk/tools/db/tx"
"github.com/openimsdk/tools/utils/datautil" "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(ctx context.Context, userIDs []string) (users []*model.User, err error)
// Find userInfo By Nickname // Find userInfo By Nickname
FindByNickname(ctx context.Context, nickname string) (users []*model.User, err error) FindByNickname(ctx context.Context, nickname string) (users []*model.User, err error)
// Find notificationAccounts // FindNotification find system account by level
FindNotification(ctx context.Context, level int64) (users []*model.User, err error) 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 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) Create(ctx context.Context, users []*model.User) (err error)
// UpdateByMap update (zero value) external guarantee userID exists // 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) 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. // 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) { func (u *userDatabase) Create(ctx context.Context, users []*model.User) (err error) {
return u.tx.Transaction(ctx, func(ctx context.Context) error { return u.tx.Transaction(ctx, func(ctx context.Context) error {

@ -16,9 +16,10 @@ package mgo
import ( import (
"context" "context"
"time"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" "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/open-im-server/v3/pkg/common/storage/model"
"time"
"github.com/openimsdk/protocol/user" "github.com/openimsdk/protocol/user"
"github.com/openimsdk/tools/db/mongoutil" "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}) 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) { 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}) return mongoutil.Find[*model.User](ctx, u.coll, bson.M{"nickname": nickname})
} }

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

Loading…
Cancel
Save