From 7e4065ccbdb87914431324acda3f6e5e04dbb361 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Mon, 3 Mar 2025 10:39:53 +0800 Subject: [PATCH 1/5] fix: solve uncorrect notification when set group info (#3172) * fix: setGroupInfoEx uncorrect call. * update notification logic. * update group notification logic. * update update group announcement notication. * fix errror. * refresh * solve conflict. * update args. --- internal/rpc/group/db_map.go | 24 +++++++++---- internal/rpc/group/group.go | 55 +++++++++++++++--------------- internal/rpc/group/notification.go | 4 +-- 3 files changed, 47 insertions(+), 36 deletions(-) diff --git a/internal/rpc/group/db_map.go b/internal/rpc/group/db_map.go index e99f9e772..7504bc851 100644 --- a/internal/rpc/group/db_map.go +++ b/internal/rpc/group/db_map.go @@ -16,6 +16,7 @@ package group import ( "context" + "strings" "time" pbgroup "github.com/openimsdk/protocol/group" @@ -55,41 +56,52 @@ func UpdateGroupInfoMap(ctx context.Context, group *sdkws.GroupInfoForSet) map[s return m } -func UpdateGroupInfoExMap(ctx context.Context, group *pbgroup.SetGroupInfoExReq) (map[string]any, error) { - m := make(map[string]any) +func UpdateGroupInfoExMap(ctx context.Context, group *pbgroup.SetGroupInfoExReq) (m map[string]any, normalFlag, groupNameFlag, notificationFlag bool, err error) { + m = make(map[string]any) if group.GroupName != nil { - if group.GroupName.Value != "" { + if strings.TrimSpace(group.GroupName.Value) != "" { m["group_name"] = group.GroupName.Value + groupNameFlag = true } else { - return nil, errs.ErrArgs.WrapMsg("group name is empty") + return nil, normalFlag, notificationFlag, groupNameFlag, errs.ErrArgs.WrapMsg("group name is empty") } } + if group.Notification != nil { + notificationFlag = true + group.Notification.Value = strings.TrimSpace(group.Notification.Value) // if Notification only contains spaces, set it to empty string + m["notification"] = group.Notification.Value - m["notification_update_time"] = time.Now() m["notification_user_id"] = mcontext.GetOpUserID(ctx) + m["notification_update_time"] = time.Now() } if group.Introduction != nil { m["introduction"] = group.Introduction.Value + normalFlag = true } if group.FaceURL != nil { m["face_url"] = group.FaceURL.Value + normalFlag = true } if group.NeedVerification != nil { m["need_verification"] = group.NeedVerification.Value + normalFlag = true } if group.LookMemberInfo != nil { m["look_member_info"] = group.LookMemberInfo.Value + normalFlag = true } if group.ApplyMemberFriend != nil { m["apply_member_friend"] = group.ApplyMemberFriend.Value + normalFlag = true } if group.Ex != nil { m["ex"] = group.Ex.Value + normalFlag = true } - return m, nil + return m, normalFlag, groupNameFlag, notificationFlag, nil } func UpdateGroupStatusMap(status int) map[string]any { diff --git a/internal/rpc/group/group.go b/internal/rpc/group/group.go index 649027fb8..24f91937c 100644 --- a/internal/rpc/group/group.go +++ b/internal/rpc/group/group.go @@ -292,10 +292,11 @@ func (g *groupServer) CreateGroup(ctx context.Context, req *pbgroup.CreateGroupR g.notification.GroupCreatedNotification(ctx, tips) if req.GroupInfo.Notification != "" { + notificationFlag := true g.notification.GroupInfoSetAnnouncementNotification(ctx, &sdkws.GroupInfoSetAnnouncementTips{ Group: tips.Group, OpUser: tips.OpUser, - }) + }, ¬ificationFlag) } reqCallBackAfter := &pbgroup.CreateGroupReq{ @@ -1030,7 +1031,8 @@ func (g *groupServer) SetGroupInfo(ctx context.Context, req *pbgroup.SetGroupInf log.ZWarn(ctx, "SetConversations", err, "UserIDs", resp.UserIDs, "conversation", conversation) } }() - g.notification.GroupInfoSetAnnouncementNotification(ctx, &sdkws.GroupInfoSetAnnouncementTips{Group: tips.Group, OpUser: tips.OpUser}) + notficationFlag := true + g.notification.GroupInfoSetAnnouncementNotification(ctx, &sdkws.GroupInfoSetAnnouncementTips{Group: tips.Group, OpUser: tips.OpUser}, ¬ficationFlag) } if req.GroupInfoForSet.GroupName != "" { num-- @@ -1091,7 +1093,7 @@ func (g *groupServer) SetGroupInfoEx(ctx context.Context, req *pbgroup.SetGroupI return nil, err } - updatedData, err := UpdateGroupInfoExMap(ctx, req) + updatedData, normalFlag, groupNameFlag, notificationFlag, err := UpdateGroupInfoExMap(ctx, req) if len(updatedData) == 0 { return &pbgroup.SetGroupInfoExResp{}, nil } @@ -1119,41 +1121,38 @@ func (g *groupServer) SetGroupInfoEx(ctx context.Context, req *pbgroup.SetGroupI tips.OpUser = g.groupMemberDB2PB(opMember, 0) } - num := len(updatedData) - - if req.Notification != nil { - num -= 3 - + if notificationFlag { if req.Notification.Value != "" { - func() { - conversation := &pbconversation.ConversationReq{ - ConversationID: msgprocessor.GetConversationIDBySessionType(constant.ReadGroupChatType, req.GroupID), - ConversationType: constant.ReadGroupChatType, - GroupID: req.GroupID, - } + conversation := &pbconv.ConversationReq{ + ConversationID: msgprocessor.GetConversationIDBySessionType(constant.ReadGroupChatType, req.GroupID), + ConversationType: constant.ReadGroupChatType, + GroupID: req.GroupID, + } - resp, err := g.GetGroupMemberUserIDs(ctx, &pbgroup.GetGroupMemberUserIDsReq{GroupID: req.GroupID}) - if err != nil { - log.ZWarn(ctx, "GetGroupMemberIDs is failed.", err) - return - } + resp, err := g.GetGroupMemberUserIDs(ctx, &pbgroup.GetGroupMemberUserIDsReq{GroupID: req.GroupID}) + if err != nil { + log.ZWarn(ctx, "GetGroupMemberIDs is failed.", err) + return nil, err + } - conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.GroupNotification} - if err := g.conversationClient.SetConversations(ctx, resp.UserIDs, conversation); err != nil { - log.ZWarn(ctx, "SetConversations", err, "UserIDs", resp.UserIDs, "conversation", conversation) - } - }() + conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.GroupNotification} + if err := g.conversationClient.SetConversations(ctx, resp.UserIDs, conversation); err != nil { + log.ZWarn(ctx, "SetConversations", err, "UserIDs", resp.UserIDs, "conversation", conversation) + } - g.notification.GroupInfoSetAnnouncementNotification(ctx, &sdkws.GroupInfoSetAnnouncementTips{Group: tips.Group, OpUser: tips.OpUser}) + g.notification.GroupInfoSetAnnouncementNotification(ctx, &sdkws.GroupInfoSetAnnouncementTips{Group: tips.Group, OpUser: tips.OpUser}, ¬ificationFlag) + } else { + notificationFlag = false + g.notification.GroupInfoSetAnnouncementNotification(ctx, &sdkws.GroupInfoSetAnnouncementTips{Group: tips.Group, OpUser: tips.OpUser}, ¬ificationFlag) } } - if req.GroupName != nil { - num-- + if groupNameFlag { g.notification.GroupInfoSetNameNotification(ctx, &sdkws.GroupInfoSetNameTips{Group: tips.Group, OpUser: tips.OpUser}) } - if num > 0 { + // if updatedData > 0, send the normal notification + if normalFlag { g.notification.GroupInfoSetNotification(ctx, tips) } diff --git a/internal/rpc/group/notification.go b/internal/rpc/group/notification.go index 1aa5333b4..49aa4504b 100644 --- a/internal/rpc/group/notification.go +++ b/internal/rpc/group/notification.go @@ -349,7 +349,7 @@ func (g *NotificationSender) GroupInfoSetNameNotification(ctx context.Context, t g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupInfoSetNameNotification, tips) } -func (g *NotificationSender) GroupInfoSetAnnouncementNotification(ctx context.Context, tips *sdkws.GroupInfoSetAnnouncementTips) { +func (g *NotificationSender) GroupInfoSetAnnouncementNotification(ctx context.Context, tips *sdkws.GroupInfoSetAnnouncementTips, sendMessage *bool) { var err error defer func() { if err != nil { @@ -360,7 +360,7 @@ func (g *NotificationSender) GroupInfoSetAnnouncementNotification(ctx context.Co return } g.setVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID) - g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupInfoSetAnnouncementNotification, tips, rpcclient.WithRpcGetUserName()) + g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupInfoSetAnnouncementNotification, tips, notification.WithRpcGetUserName(), notification.WithSendMessage(sendMessage)) } func (g *NotificationSender) JoinGroupApplicationNotification(ctx context.Context, req *pbgroup.JoinGroupReq) { From 2719e6878bb0f316046eb33d42e7ce3f5848cbd6 Mon Sep 17 00:00:00 2001 From: OpenIM-Gordon <1432970085@qq.com> Date: Fri, 28 Feb 2025 16:59:04 +0800 Subject: [PATCH 2/5] refactor: change sendNotification to sendMessage to avoid ambiguity regarding message sending behavior. (#3173) * feat: add a field to specify whether to send a notification message when creating a group. * feat: add a field to specify whether to send a notification message when creating a group. * refactor: change sendNotification to sendMessage to avoid ambiguity regarding message sending behavior. --------- Co-authored-by: Monet Lee --- go.mod | 4 ++-- go.sum | 12 ++++++------ internal/rpc/group/group.go | 8 ++++---- internal/rpc/group/notification.go | 16 ++++++++-------- pkg/common/config/parse.go | 7 +++++-- pkg/notification/msg.go | 12 +++++++++--- 6 files changed, 34 insertions(+), 25 deletions(-) diff --git a/go.mod b/go.mod index c5e5a1f85..ccd9885d0 100644 --- a/go.mod +++ b/go.mod @@ -12,8 +12,8 @@ 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/tools v0.0.50-alpha.72 + github.com/openimsdk/protocol v0.0.72-alpha.78 + github.com/openimsdk/tools v0.0.50-alpha.74 github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_golang v1.18.0 github.com/stretchr/testify v1.9.0 diff --git a/go.sum b/go.sum index 947af7889..18d2a6495 100644 --- a/go.sum +++ b/go.sum @@ -317,12 +317,12 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v1.25.0 h1:Vw7br2PCDYijJHSfBOWhov+8cAnUf8MfMaIOV323l6Y= github.com/onsi/gomega v1.25.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= -github.com/openimsdk/gomake v0.0.14-alpha.5 h1:VY9c5x515lTfmdhhPjMvR3BBRrRquAUCFsz7t7vbv7Y= -github.com/openimsdk/gomake v0.0.14-alpha.5/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/tools v0.0.50-alpha.72 h1:d/vaZjIfvrNp3EeRJEIiamBO7HiPx6CP4wiuq8NpfzY= -github.com/openimsdk/tools v0.0.50-alpha.72/go.mod h1:B+oqV0zdewN7OiEHYJm+hW+8/Te7B8tHHgD8rK5ZLZk= +github.com/openimsdk/gomake v0.0.15-alpha.2 h1:5Q8yl8ezy2yx+q8/ucU/t4kJnDfCzNOrkXcDACCqtyM= +github.com/openimsdk/gomake v0.0.15-alpha.2/go.mod h1:PndCozNc2IsQIciyn9mvEblYWZwJmAI+06z94EY+csI= +github.com/openimsdk/protocol v0.0.72-alpha.78 h1:n9HVj5olMPiGLF3Z4apPvvYzn2yOpyrsn2/YiAaIsxw= +github.com/openimsdk/protocol v0.0.72-alpha.78/go.mod h1:WF7EuE55vQvpyUAzDXcqg+B+446xQyEba0X35lTINmw= +github.com/openimsdk/tools v0.0.50-alpha.74 h1:yh10SiMiivMEjicEQg+QAsH4pvaO+4noMPdlw+ew0Kc= +github.com/openimsdk/tools v0.0.50-alpha.74/go.mod h1:n2poR3asX1e1XZce4O+MOWAp+X02QJRFvhcLCXZdzRo= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= diff --git a/internal/rpc/group/group.go b/internal/rpc/group/group.go index 649027fb8..edd32dfea 100644 --- a/internal/rpc/group/group.go +++ b/internal/rpc/group/group.go @@ -289,7 +289,7 @@ func (g *groupServer) CreateGroup(ctx context.Context, req *pbgroup.CreateGroupR break } } - g.notification.GroupCreatedNotification(ctx, tips) + g.notification.GroupCreatedNotification(ctx, tips, req.SendMessage) if req.GroupInfo.Notification != "" { g.notification.GroupInfoSetAnnouncementNotification(ctx, &sdkws.GroupInfoSetAnnouncementTips{ @@ -452,7 +452,7 @@ func (g *groupServer) InviteUserToGroup(ctx context.Context, req *pbgroup.Invite return nil, err } - if err = g.notification.GroupApplicationAgreeMemberEnterNotification(ctx, req.GroupID, opUserID, req.InvitedUserIDs...); err != nil { + if err = g.notification.GroupApplicationAgreeMemberEnterNotification(ctx, req.GroupID, req.SendMessage, opUserID, req.InvitedUserIDs...); err != nil { return nil, err } return &pbgroup.InviteUserToGroupResp{}, nil @@ -618,7 +618,7 @@ func (g *groupServer) KickGroupMember(ctx context.Context, req *pbgroup.KickGrou for _, userID := range req.KickedUserIDs { tips.KickedUserList = append(tips.KickedUserList, convert.Db2PbGroupMember(memberMap[userID])) } - g.notification.MemberKickedNotification(ctx, tips) + g.notification.MemberKickedNotification(ctx, tips, req.SendMessage) if err := g.deleteMemberAndSetConversationSeq(ctx, req.GroupID, req.KickedUserIDs); err != nil { return nil, err } @@ -1373,7 +1373,7 @@ func (g *groupServer) DismissGroup(ctx context.Context, req *pbgroup.DismissGrou if mcontext.GetOpUserID(ctx) == owner.UserID { tips.OpUser = g.groupMemberDB2PB(owner, 0) } - g.notification.GroupDismissedNotification(ctx, tips) + g.notification.GroupDismissedNotification(ctx, tips, req.SendMessage) } membersID, err := g.db.FindGroupMemberUserID(ctx, group.GroupID) if err != nil { diff --git a/internal/rpc/group/notification.go b/internal/rpc/group/notification.go index 1aa5333b4..fc0c36564 100644 --- a/internal/rpc/group/notification.go +++ b/internal/rpc/group/notification.go @@ -307,7 +307,7 @@ func (g *NotificationSender) setSortVersion(ctx context.Context, version *uint64 } } -func (g *NotificationSender) GroupCreatedNotification(ctx context.Context, tips *sdkws.GroupCreatedTips) { +func (g *NotificationSender) GroupCreatedNotification(ctx context.Context, tips *sdkws.GroupCreatedTips, SendMessage *bool) { var err error defer func() { if err != nil { @@ -318,7 +318,7 @@ func (g *NotificationSender) GroupCreatedNotification(ctx context.Context, tips return } g.setVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID) - g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupCreatedNotification, tips) + g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupCreatedNotification, tips, notification.WithSendMessage(SendMessage)) } func (g *NotificationSender) GroupInfoSetNotification(ctx context.Context, tips *sdkws.GroupInfoSetTips) { @@ -505,7 +505,7 @@ func (g *NotificationSender) GroupOwnerTransferredNotification(ctx context.Conte g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupOwnerTransferredNotification, tips) } -func (g *NotificationSender) MemberKickedNotification(ctx context.Context, tips *sdkws.MemberKickedTips) { +func (g *NotificationSender) MemberKickedNotification(ctx context.Context, tips *sdkws.MemberKickedTips, SendMessage *bool) { var err error defer func() { if err != nil { @@ -516,10 +516,10 @@ func (g *NotificationSender) MemberKickedNotification(ctx context.Context, tips return } g.setVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID) - g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.MemberKickedNotification, tips) + g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.MemberKickedNotification, tips, notification.WithSendMessage(SendMessage)) } -func (g *NotificationSender) GroupApplicationAgreeMemberEnterNotification(ctx context.Context, groupID string, invitedOpUserID string, entrantUserID ...string) error { +func (g *NotificationSender) GroupApplicationAgreeMemberEnterNotification(ctx context.Context, groupID string, SendMessage *bool, invitedOpUserID string, entrantUserID ...string) error { var err error defer func() { if err != nil { @@ -569,7 +569,7 @@ func (g *NotificationSender) GroupApplicationAgreeMemberEnterNotification(ctx co } } g.setVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID) - g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.MemberInvitedNotification, tips) + g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.MemberInvitedNotification, tips, notification.WithSendMessage(SendMessage)) return nil } @@ -614,7 +614,7 @@ func (g *NotificationSender) MemberEnterNotification(ctx context.Context, groupI return nil } -func (g *NotificationSender) GroupDismissedNotification(ctx context.Context, tips *sdkws.GroupDismissedTips) { +func (g *NotificationSender) GroupDismissedNotification(ctx context.Context, tips *sdkws.GroupDismissedTips, SendMessage *bool) { var err error defer func() { if err != nil { @@ -624,7 +624,7 @@ func (g *NotificationSender) GroupDismissedNotification(ctx context.Context, tip if err = g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return } - g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupDismissedNotification, tips) + g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupDismissedNotification, tips, notification.WithSendMessage(SendMessage)) } func (g *NotificationSender) GroupMemberMutedNotification(ctx context.Context, groupID, groupMemberUserID string, mutedSeconds uint32) { diff --git a/pkg/common/config/parse.go b/pkg/common/config/parse.go index 08f82ac7d..50959caee 100644 --- a/pkg/common/config/parse.go +++ b/pkg/common/config/parse.go @@ -58,10 +58,13 @@ func GetProjectRoot() (string, error) { return projectRoot, nil } -func GetOptionsByNotification(cfg NotificationConfig) msgprocessor.Options { +func GetOptionsByNotification(cfg NotificationConfig, sendMessage *bool) msgprocessor.Options { opts := msgprocessor.NewOptions() - if cfg.UnreadCount { + if sendMessage != nil { + cfg.IsSendMsg = *sendMessage + } + if cfg.IsSendMsg { opts = msgprocessor.WithOptions(opts, msgprocessor.WithUnreadCount(true)) } if cfg.OfflinePush.Enable { diff --git a/pkg/notification/msg.go b/pkg/notification/msg.go index 0795982c8..8e028c577 100644 --- a/pkg/notification/msg.go +++ b/pkg/notification/msg.go @@ -179,14 +179,20 @@ func NewNotificationSender(conf *config.Notification, opts ...NotificationSender } type notificationOpt struct { - WithRpcGetUsername bool + RpcGetUsername bool + SendMessage *bool } type NotificationOptions func(*notificationOpt) func WithRpcGetUserName() NotificationOptions { return func(opt *notificationOpt) { - opt.WithRpcGetUsername = true + opt.RpcGetUsername = true + } +} +func WithSendMessage(sendMessage *bool) NotificationOptions { + return func(opt *notificationOpt) { + opt.SendMessage = sendMessage } } @@ -233,7 +239,7 @@ func (s *NotificationSender) send(ctx context.Context, sendID, recvID string, co if sendID == recvID && contentType == constant.HasReadReceipt { optionsConfig.ReliabilityLevel = constant.UnreliableNotification } - options := config.GetOptionsByNotification(optionsConfig) + options := config.GetOptionsByNotification(optionsConfig, notificationOpt.SendMessage) s.SetOptionsByContentType(ctx, options, contentType) msg.Options = options // fill Notification OfflinePush by config From 41bca107be082ca6df053040c2085f255ad6a14f Mon Sep 17 00:00:00 2001 From: chao <48119764+withchao@users.noreply.github.com> Date: Mon, 3 Mar 2025 17:59:35 +0800 Subject: [PATCH 3/5] feat: optimizing BatchGetIncrementalGroupMember (#3180) * pb * fix: Modifying other fields while setting IsPrivateChat does not take effect * fix: quote message error revoke * refactoring scheduled tasks * refactoring scheduled tasks * refactoring scheduled tasks * refactoring scheduled tasks * refactoring scheduled tasks * refactoring scheduled tasks * upgrading pkg tools * fix * fix * optimize log output * feat: support GetLastMessage * feat: support GetLastMessage * feat: s3 switch * feat: s3 switch * fix: GetUsersOnline * feat: SendBusinessNotification supported configuration parameters * feat: SendBusinessNotification supported configuration parameters * feat: SendBusinessNotification supported configuration parameters * feat: seq conversion failed without exiting * fix: DeleteDoc crash * fix: fill send time * fix: fill send time * fix: crash caused by withdrawing messages from users who have left the group * fix: user msg timestamp * seq read config * seq read config * fix: the source message of the reference is withdrawn, and the referenced message is deleted * feat: optimize the default notification.yml * fix: shouldPushOffline * fix: optimizing BatchGetIncrementalGroupMember --- internal/rpc/group/sync.go | 176 ++++++------------------------------- 1 file changed, 26 insertions(+), 150 deletions(-) diff --git a/internal/rpc/group/sync.go b/internal/rpc/group/sync.go index 0592aa811..335f4481b 100644 --- a/internal/rpc/group/sync.go +++ b/internal/rpc/group/sync.go @@ -11,12 +11,12 @@ import ( "github.com/openimsdk/protocol/constant" pbgroup "github.com/openimsdk/protocol/group" "github.com/openimsdk/protocol/sdkws" - "github.com/openimsdk/tools/errs" - "github.com/openimsdk/tools/log" ) -func (s *groupServer) GetFullGroupMemberUserIDs(ctx context.Context, req *pbgroup.GetFullGroupMemberUserIDsReq) (*pbgroup.GetFullGroupMemberUserIDsResp, error) { - vl, err := s.db.FindMaxGroupMemberVersionCache(ctx, req.GroupID) +const versionSyncLimit = 500 + +func (g *groupServer) GetFullGroupMemberUserIDs(ctx context.Context, req *pbgroup.GetFullGroupMemberUserIDsReq) (*pbgroup.GetFullGroupMemberUserIDsResp, error) { + vl, err := g.db.FindMaxGroupMemberVersionCache(ctx, req.GroupID) if err != nil { return nil, err } @@ -132,152 +132,8 @@ func (s *groupServer) GetIncrementalGroupMember(ctx context.Context, req *pbgrou return resp, nil } -func (s *groupServer) BatchGetIncrementalGroupMember(ctx context.Context, req *pbgroup.BatchGetIncrementalGroupMemberReq) (resp *pbgroup.BatchGetIncrementalGroupMemberResp, err error) { - type VersionInfo struct { - GroupID string - VersionID string - VersionNumber uint64 - } - - var groupIDs []string - - groupsVersionMap := make(map[string]*VersionInfo) - groupsMap := make(map[string]*model.Group) - hasGroupUpdateMap := make(map[string]bool) - sortVersionMap := make(map[string]uint64) - - var targetKeys, versionIDs []string - var versionNumbers []uint64 - - var requestBodyLen int - - for _, group := range req.ReqList { - groupsVersionMap[group.GroupID] = &VersionInfo{ - GroupID: group.GroupID, - VersionID: group.VersionID, - VersionNumber: group.Version, - } - - groupIDs = append(groupIDs, group.GroupID) - } - - groups, err := s.db.FindGroup(ctx, groupIDs) - if err != nil { - return nil, errs.Wrap(err) - } - - for _, group := range groups { - if group.Status == constant.GroupStatusDismissed { - err = servererrs.ErrDismissedAlready.Wrap() - log.ZError(ctx, "This group is Dismissed Already", err, "group is", group.GroupID) - - delete(groupsVersionMap, group.GroupID) - } else { - groupsMap[group.GroupID] = group - } - } - - for groupID, vInfo := range groupsVersionMap { - targetKeys = append(targetKeys, groupID) - versionIDs = append(versionIDs, vInfo.VersionID) - versionNumbers = append(versionNumbers, vInfo.VersionNumber) - } - - opt := incrversion.BatchOption[[]*sdkws.GroupMemberFullInfo, pbgroup.BatchGetIncrementalGroupMemberResp]{ - Ctx: ctx, - TargetKeys: targetKeys, - VersionIDs: versionIDs, - VersionNumbers: versionNumbers, - Versions: func(ctx context.Context, groupIDs []string, versions []uint64, limits []int) (map[string]*model.VersionLog, error) { - vLogs, err := s.db.BatchFindMemberIncrVersion(ctx, groupIDs, versions, limits) - if err != nil { - return nil, errs.Wrap(err) - } - - for groupID, vlog := range vLogs { - vlogElems := make([]model.VersionLogElem, 0, len(vlog.Logs)) - for i, log := range vlog.Logs { - switch log.EID { - case model.VersionGroupChangeID: - vlog.LogLen-- - hasGroupUpdateMap[groupID] = true - case model.VersionSortChangeID: - vlog.LogLen-- - sortVersionMap[groupID] = uint64(log.Version) - default: - vlogElems = append(vlogElems, vlog.Logs[i]) - } - } - vlog.Logs = vlogElems - if vlog.LogLen > 0 { - hasGroupUpdateMap[groupID] = true - } - } - - return vLogs, nil - }, - CacheMaxVersions: s.db.BatchFindMaxGroupMemberVersionCache, - Find: func(ctx context.Context, groupID string, ids []string) ([]*sdkws.GroupMemberFullInfo, error) { - memberInfo, err := s.getGroupMembersInfo(ctx, groupID, ids) - if err != nil { - return nil, err - } - - return memberInfo, err - }, - Resp: func(versions map[string]*model.VersionLog, deleteIdsMap map[string][]string, insertListMap, updateListMap map[string][]*sdkws.GroupMemberFullInfo, fullMap map[string]bool) *pbgroup.BatchGetIncrementalGroupMemberResp { - resList := make(map[string]*pbgroup.GetIncrementalGroupMemberResp) - - for groupID, versionLog := range versions { - resList[groupID] = &pbgroup.GetIncrementalGroupMemberResp{ - VersionID: versionLog.ID.Hex(), - Version: uint64(versionLog.Version), - Full: fullMap[groupID], - Delete: deleteIdsMap[groupID], - Insert: insertListMap[groupID], - Update: updateListMap[groupID], - SortVersion: sortVersionMap[groupID], - } - - requestBodyLen += len(insertListMap[groupID]) + len(updateListMap[groupID]) + len(deleteIdsMap[groupID]) - if requestBodyLen > 200 { - break - } - } - - return &pbgroup.BatchGetIncrementalGroupMemberResp{ - RespList: resList, - } - }, - } - - resp, err = opt.Build() - if err != nil { - return nil, errs.Wrap(err) - } - - for groupID, val := range resp.RespList { - if val.Full || hasGroupUpdateMap[groupID] { - count, err := s.db.FindGroupMemberNum(ctx, groupID) - if err != nil { - return nil, err - } - - owner, err := s.db.TakeGroupOwner(ctx, groupID) - if err != nil { - return nil, err - } - - resp.RespList[groupID].Group = s.groupDB2PB(groupsMap[groupID], owner.UserID, count) - } - } - - return resp, nil - -} - -func (s *groupServer) GetIncrementalJoinGroup(ctx context.Context, req *pbgroup.GetIncrementalJoinGroupReq) (*pbgroup.GetIncrementalJoinGroupResp, error) { - if err := authverify.CheckAccessV3(ctx, req.UserID, s.config.Share.IMAdminUserID); err != nil { +func (g *groupServer) GetIncrementalJoinGroup(ctx context.Context, req *pbgroup.GetIncrementalJoinGroupReq) (*pbgroup.GetIncrementalJoinGroupResp, error) { + if err := authverify.CheckAccessV3(ctx, req.UserID, g.config.Share.IMAdminUserID); err != nil { return nil, err } opt := incrversion.Option[*sdkws.GroupInfo, pbgroup.GetIncrementalJoinGroupResp]{ @@ -301,3 +157,23 @@ func (s *groupServer) GetIncrementalJoinGroup(ctx context.Context, req *pbgroup. } return opt.Build() } + +func (g *groupServer) BatchGetIncrementalGroupMember(ctx context.Context, req *pbgroup.BatchGetIncrementalGroupMemberReq) (*pbgroup.BatchGetIncrementalGroupMemberResp, error) { + var num int + resp := make(map[string]*pbgroup.GetIncrementalGroupMemberResp) + for _, memberReq := range req.ReqList { + if _, ok := resp[memberReq.GroupID]; ok { + continue + } + memberResp, err := g.GetIncrementalGroupMember(ctx, memberReq) + if err != nil { + return nil, err + } + resp[memberReq.GroupID] = memberResp + num += len(memberResp.Insert) + len(memberResp.Update) + len(memberResp.Delete) + if num >= versionSyncLimit { + break + } + } + return &pbgroup.BatchGetIncrementalGroupMemberResp{RespList: resp}, nil +} From b75b8ec900f63a2d8950ee3ef2127d84725d60ae Mon Sep 17 00:00:00 2001 From: chao <48119764+withchao@users.noreply.github.com> Date: Tue, 4 Mar 2025 16:09:29 +0800 Subject: [PATCH 4/5] fix: the sorting is wrong after canceling the administrator in group settings (#3185) * pb * fix: Modifying other fields while setting IsPrivateChat does not take effect * fix: quote message error revoke * refactoring scheduled tasks * refactoring scheduled tasks * refactoring scheduled tasks * refactoring scheduled tasks * refactoring scheduled tasks * refactoring scheduled tasks * upgrading pkg tools * fix * fix * optimize log output * feat: support GetLastMessage * feat: support GetLastMessage * feat: s3 switch * feat: s3 switch * fix: GetUsersOnline * feat: SendBusinessNotification supported configuration parameters * feat: SendBusinessNotification supported configuration parameters * feat: SendBusinessNotification supported configuration parameters * feat: seq conversion failed without exiting * fix: DeleteDoc crash * fix: fill send time * fix: fill send time * fix: crash caused by withdrawing messages from users who have left the group * fix: user msg timestamp * seq read config * seq read config * fix: the source message of the reference is withdrawn, and the referenced message is deleted * feat: optimize the default notification.yml * fix: shouldPushOffline * fix: the sorting is wrong after canceling the administrator in group settings --- internal/rpc/group/notification.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/rpc/group/notification.go b/internal/rpc/group/notification.go index 1aa5333b4..0285352ce 100644 --- a/internal/rpc/group/notification.go +++ b/internal/rpc/group/notification.go @@ -781,7 +781,7 @@ func (g *NotificationSender) GroupMemberSetToAdminNotification(ctx context.Conte if err = g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return } - g.setVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID) + g.setSortVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID, &tips.GroupSortVersion) g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberSetToAdminNotification, tips) } @@ -806,6 +806,6 @@ func (g *NotificationSender) GroupMemberSetToOrdinaryUserNotification(ctx contex if err = g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return } - g.setVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID) + g.setSortVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID, &tips.GroupSortVersion) g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberSetToOrdinaryUserNotification, tips) } From 744f481b9cc49c7fa8ee571c9230c95f80287445 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Tue, 4 Mar 2025 18:12:35 +0800 Subject: [PATCH 5/5] fix: solve uncorrect GroupMember enter group notification type. (#3188) --- internal/rpc/group/group.go | 10 +++++++-- internal/rpc/group/notification.go | 34 ++++++++++++++---------------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/internal/rpc/group/group.go b/internal/rpc/group/group.go index 649027fb8..061339cbf 100644 --- a/internal/rpc/group/group.go +++ b/internal/rpc/group/group.go @@ -827,8 +827,14 @@ func (g *groupServer) GroupApplicationResponse(ctx context.Context, req *pbgroup if member == nil { log.ZDebug(ctx, "GroupApplicationResponse", "member is nil") } else { - if err = g.notification.GroupApplicationAgreeMemberEnterNotification(ctx, req.GroupID, groupRequest.InviterUserID, req.FromUserID); err != nil { - return nil, err + if groupRequest.InviterUserID == "" { + if err = g.notification.MemberEnterNotification(ctx, req.GroupID, req.FromUserID); err != nil { + return nil, err + } + } else { + if err = g.notification.GroupApplicationAgreeMemberEnterNotification(ctx, req.GroupID, nil, groupRequest.InviterUserID, req.FromUserID); err != nil { + return nil, err + } } } case constant.GroupResponseRefuse: diff --git a/internal/rpc/group/notification.go b/internal/rpc/group/notification.go index 1aa5333b4..c48707b0b 100644 --- a/internal/rpc/group/notification.go +++ b/internal/rpc/group/notification.go @@ -233,17 +233,17 @@ func (g *NotificationSender) groupMemberDB2PB(member *model.GroupMember, appMang return result, nil } */ -func (g *NotificationSender) fillOpUser(ctx context.Context, opUser **sdkws.GroupMemberFullInfo, groupID string) (err error) { - return g.fillOpUserByUserID(ctx, mcontext.GetOpUserID(ctx), opUser, groupID) +func (g *NotificationSender) fillOpUser(ctx context.Context, targetUser **sdkws.GroupMemberFullInfo, groupID string) (err error) { + return g.fillUserByUserID(ctx, mcontext.GetOpUserID(ctx), targetUser, groupID) } -func (g *NotificationSender) fillOpUserByUserID(ctx context.Context, userID string, opUser **sdkws.GroupMemberFullInfo, groupID string) error { - if opUser == nil { +func (g *NotificationSender) fillUserByUserID(ctx context.Context, userID string, targetUser **sdkws.GroupMemberFullInfo, groupID string) error { + if targetUser == nil { return errs.ErrInternalServer.WrapMsg("**sdkws.GroupMemberFullInfo is nil") } if groupID != "" { if authverify.IsManagerUserID(userID, g.config.Share.IMAdminUserID) { - *opUser = &sdkws.GroupMemberFullInfo{ + *targetUser = &sdkws.GroupMemberFullInfo{ GroupID: groupID, UserID: userID, RoleLevel: constant.GroupAdmin, @@ -252,7 +252,7 @@ func (g *NotificationSender) fillOpUserByUserID(ctx context.Context, userID stri } else { member, err := g.db.TakeGroupMember(ctx, groupID, userID) if err == nil { - *opUser = g.groupMemberDB2PB(member, 0) + *targetUser = g.groupMemberDB2PB(member, 0) } else if !(errors.Is(err, mongo.ErrNoDocuments) || errs.ErrRecordNotFound.Is(err)) { return err } @@ -262,8 +262,8 @@ func (g *NotificationSender) fillOpUserByUserID(ctx context.Context, userID stri if err != nil { return err } - if *opUser == nil { - *opUser = &sdkws.GroupMemberFullInfo{ + if *targetUser == nil { + *targetUser = &sdkws.GroupMemberFullInfo{ GroupID: groupID, UserID: userID, Nickname: user.Nickname, @@ -271,11 +271,11 @@ func (g *NotificationSender) fillOpUserByUserID(ctx context.Context, userID stri OperatorUserID: userID, } } else { - if (*opUser).Nickname == "" { - (*opUser).Nickname = user.Nickname + if (*targetUser).Nickname == "" { + (*targetUser).Nickname = user.Nickname } - if (*opUser).FaceURL == "" { - (*opUser).FaceURL = user.FaceURL + if (*targetUser).FaceURL == "" { + (*targetUser).FaceURL = user.FaceURL } } return nil @@ -556,15 +556,13 @@ func (g *NotificationSender) GroupApplicationAgreeMemberEnterNotification(ctx co InvitedUserList: users, } opUserID := mcontext.GetOpUserID(ctx) - if err = g.fillOpUserByUserID(ctx, opUserID, &tips.OpUser, tips.Group.GroupID); err != nil { + if err = g.fillUserByUserID(ctx, opUserID, &tips.OpUser, tips.Group.GroupID); err != nil { return nil } - switch { - case invitedOpUserID == "": - case invitedOpUserID == opUserID: + if invitedOpUserID == opUserID { tips.InviterUser = tips.OpUser - default: - if err = g.fillOpUserByUserID(ctx, invitedOpUserID, &tips.InviterUser, tips.Group.GroupID); err != nil { + } else { + if err = g.fillUserByUserID(ctx, invitedOpUserID, &tips.InviterUser, tips.Group.GroupID); err != nil { return err } }