diff --git a/pkg/rpcclient/convert/friend.go b/pkg/rpcclient/convert/friend.go new file mode 100644 index 000000000..c4ac52477 --- /dev/null +++ b/pkg/rpcclient/convert/friend.go @@ -0,0 +1,31 @@ +package convert + +import ( + "context" + + "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/relation" + "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" + sdk "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" + utils "github.com/OpenIMSDK/open_utils" +) + +func FriendPb2DB(friend *sdkws.FriendInfo) (*relation.FriendModel, error) { + dbFriend := &relation.FriendModel{} + utils.CopyStructFields(dbFriend, friend) + dbFriend.FriendUserID = friend.FriendUser.UserID + dbFriend.CreateTime = utils.UnixSecondToTime(friend.CreateTime) + return dbFriend, nil +} + +func FriendDB2Pb(ctx context.Context, friendDB *relation.FriendModel, fn func(ctx context.Context, userID string) (*sdkws.UserInfo, error)) (*sdk.FriendInfo, error) { + pbfriend := &sdk.FriendInfo{FriendUser: &sdk.UserInfo{}} + utils.CopyStructFields(pbfriend, friendDB) + user, err := fn(ctx, friendDB.FriendUserID) + if err != nil { + return nil, err + } + utils.CopyStructFields(pbfriend.FriendUser, user) + pbfriend.CreateTime = friendDB.CreateTime.Unix() + pbfriend.FriendUser.CreateTime = friendDB.CreateTime.Unix() + return pbfriend, nil +} diff --git a/pkg/rpcclient/convert/group.go b/pkg/rpcclient/convert/group.go new file mode 100644 index 000000000..233bcdeda --- /dev/null +++ b/pkg/rpcclient/convert/group.go @@ -0,0 +1 @@ +package convert diff --git a/pkg/rpcclient/friend_client.go b/pkg/rpcclient/friend_client.go new file mode 100644 index 000000000..6625a19f5 --- /dev/null +++ b/pkg/rpcclient/friend_client.go @@ -0,0 +1,58 @@ +package rpcclient + +import ( + "context" + + "github.com/OpenIMSDK/Open-IM-Server/pkg/common/config" + discoveryRegistry "github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry" + "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/friend" + sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" +) + +type FriendClient struct { + *MetaClient +} + +func NewFriendClient(zk discoveryRegistry.SvcDiscoveryRegistry) *FriendClient { + return &FriendClient{NewMetaClient(zk, config.Config.RpcRegisterName.OpenImFriendName)} +} + +func (f *FriendClient) GetFriendsInfo(ctx context.Context, ownerUserID, friendUserID string) (resp *sdkws.FriendInfo, err error) { + cc, err := f.getConn() + if err != nil { + return nil, err + } + r, err := friend.NewFriendClient(cc).GetDesignatedFriends(ctx, &friend.GetDesignatedFriendsReq{OwnerUserID: ownerUserID, FriendUserIDs: []string{friendUserID}}) + if err != nil { + return nil, err + } + resp = r.FriendsInfo[0] + return +} + +// possibleFriendUserID是否在userID的好友中 +func (f *FriendClient) IsFriend(ctx context.Context, possibleFriendUserID, userID string) (bool, error) { + cc, err := f.getConn() + if err != nil { + return false, err + } + resp, err := friend.NewFriendClient(cc).IsFriend(ctx, &friend.IsFriendReq{UserID1: userID, UserID2: possibleFriendUserID}) + if err != nil { + return false, err + } + return resp.InUser1Friends, nil + +} + +func (f *FriendClient) GetFriendIDs(ctx context.Context, ownerUserID string) (friendIDs []string, err error) { + cc, err := f.getConn() + if err != nil { + return nil, err + } + req := friend.GetFriendIDsReq{UserID: ownerUserID} + resp, err := friend.NewFriendClient(cc).GetFriendIDs(ctx, &req) + if err != nil { + return nil, err + } + return resp.FriendIDs, err +} diff --git a/pkg/rpcclient/group_client.go b/pkg/rpcclient/group_client.go new file mode 100644 index 000000000..5fa1d390d --- /dev/null +++ b/pkg/rpcclient/group_client.go @@ -0,0 +1,130 @@ +package rpcclient + +import ( + "context" + "strings" + + "github.com/OpenIMSDK/Open-IM-Server/pkg/common/config" + "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" + "github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry" + "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" + "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/group" + "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" + "github.com/OpenIMSDK/Open-IM-Server/pkg/utils" +) + +type GroupClient struct { + MetaClient +} + +func NewGroupClient(client discoveryregistry.SvcDiscoveryRegistry) *GroupClient { + return &GroupClient{ + MetaClient: MetaClient{ + client: client, + rpcRegisterName: config.Config.RpcRegisterName.OpenImGroupName, + }, + } +} + +func (g *GroupClient) GetGroupInfos(ctx context.Context, groupIDs []string, complete bool) ([]*sdkws.GroupInfo, error) { + cc, err := g.getConn() + if err != nil { + return nil, err + } + resp, err := group.NewGroupClient(cc).GetGroupsInfo(ctx, &group.GetGroupsInfoReq{ + GroupIDs: groupIDs, + }) + if err != nil { + return nil, err + } + if complete { + if ids := utils.Single(groupIDs, utils.Slice(resp.GroupInfos, func(e *sdkws.GroupInfo) string { + return e.GroupID + })); len(ids) > 0 { + return nil, errs.ErrGroupIDNotFound.Wrap(strings.Join(ids, ",")) + } + } + return resp.GroupInfos, nil +} + +func (g *GroupClient) GetGroupInfo(ctx context.Context, groupID string) (*sdkws.GroupInfo, error) { + groups, err := g.GetGroupInfos(ctx, []string{groupID}, true) + if err != nil { + return nil, err + } + return groups[0], nil +} + +func (g *GroupClient) GetGroupInfoMap(ctx context.Context, groupIDs []string, complete bool) (map[string]*sdkws.GroupInfo, error) { + groups, err := g.GetGroupInfos(ctx, groupIDs, complete) + if err != nil { + return nil, err + } + return utils.SliceToMap(groups, func(e *sdkws.GroupInfo) string { + return e.GroupID + }), nil +} + +func (g *GroupClient) GetGroupMemberInfos(ctx context.Context, groupID string, userIDs []string, complete bool) ([]*sdkws.GroupMemberFullInfo, error) { + cc, err := g.getConn() + if err != nil { + return nil, err + } + resp, err := group.NewGroupClient(cc).GetGroupMembersInfo(ctx, &group.GetGroupMembersInfoReq{ + GroupID: groupID, + UserIDs: userIDs, + }) + if err != nil { + return nil, err + } + if complete { + if ids := utils.Single(userIDs, utils.Slice(resp.Members, func(e *sdkws.GroupMemberFullInfo) string { + return e.UserID + })); len(ids) > 0 { + return nil, errs.ErrNotInGroupYet.Wrap(strings.Join(ids, ",")) + } + } + return resp.Members, nil +} + +func (g *GroupClient) GetGroupMemberInfo(ctx context.Context, groupID string, userID string) (*sdkws.GroupMemberFullInfo, error) { + members, err := g.GetGroupMemberInfos(ctx, groupID, []string{userID}, true) + if err != nil { + return nil, err + } + return members[0], nil +} + +func (g *GroupClient) GetGroupMemberInfoMap(ctx context.Context, groupID string, userIDs []string, complete bool) (map[string]*sdkws.GroupMemberFullInfo, error) { + members, err := g.GetGroupMemberInfos(ctx, groupID, userIDs, true) + if err != nil { + return nil, err + } + return utils.SliceToMap(members, func(e *sdkws.GroupMemberFullInfo) string { + return e.UserID + }), nil +} + +func (g *GroupClient) GetOwnerAndAdminInfos(ctx context.Context, groupID string) ([]*sdkws.GroupMemberFullInfo, error) { + cc, err := g.getConn() + if err != nil { + return nil, err + } + resp, err := group.NewGroupClient(cc).GetGroupMemberRoleLevel(ctx, &group.GetGroupMemberRoleLevelReq{ + GroupID: groupID, + RoleLevels: []int32{constant.GroupOwner, constant.GroupAdmin}, + }) + return resp.Members, err +} + +func (g *GroupClient) GetOwnerInfo(ctx context.Context, groupID string) (*sdkws.GroupMemberFullInfo, error) { + cc, err := g.getConn() + if err != nil { + return nil, err + } + resp, err := group.NewGroupClient(cc).GetGroupMemberRoleLevel(ctx, &group.GetGroupMemberRoleLevelReq{ + GroupID: groupID, + RoleLevels: []int32{constant.GroupOwner}, + }) + return resp.Members[0], err +} diff --git a/pkg/rpcclient/meta_client.go b/pkg/rpcclient/meta_client.go new file mode 100644 index 000000000..9685b8bd2 --- /dev/null +++ b/pkg/rpcclient/meta_client.go @@ -0,0 +1,38 @@ +package rpcclient + +import ( + "github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry" + "google.golang.org/grpc" +) + +type MetaClient struct { + // contains filtered or unexported fields + client discoveryregistry.SvcDiscoveryRegistry + rpcRegisterName string +} + +type NotificationMsg struct { + SendID string + RecvID string + Content []byte // sdkws.TipsComm + MsgFrom int32 + ContentType int32 + SessionType int32 + SenderNickname string + SenderFaceURL string +} + +func NewMetaClient(client discoveryregistry.SvcDiscoveryRegistry, rpcRegisterName string) *MetaClient { + return &MetaClient{ + client: client, + rpcRegisterName: rpcRegisterName, + } +} + +func (m *MetaClient) getConn() (*grpc.ClientConn, error) { + return m.client.GetConn(m.rpcRegisterName) +} + +func (m *MetaClient) getRpcRegisterName() string { + return m.rpcRegisterName +} diff --git a/pkg/rpcclient/msg_client.go b/pkg/rpcclient/msg_client.go new file mode 100644 index 000000000..214283810 --- /dev/null +++ b/pkg/rpcclient/msg_client.go @@ -0,0 +1,305 @@ +package rpcclient + +import ( + "context" + + "github.com/OpenIMSDK/Open-IM-Server/pkg/common/config" + "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" + "github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry" + "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg" + "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" + "github.com/OpenIMSDK/Open-IM-Server/pkg/utils" +) + +type MsgClient struct { + *MetaClient +} + +func NewMsgClient(zk discoveryregistry.SvcDiscoveryRegistry) *MsgClient { + return &MsgClient{NewMetaClient(zk, config.Config.RpcRegisterName.OpenImMsgName)} +} + +func (m *MsgClient) SendMsg(ctx context.Context, req *msg.SendMsgReq) (*msg.SendMsgResp, error) { + cc, err := m.getConn() + if err != nil { + return nil, err + } + resp, err := msg.NewMsgClient(cc).SendMsg(ctx, req) + return resp, err +} + +func (m *MsgClient) GetMaxAndMinSeq(ctx context.Context, req *sdkws.GetMaxAndMinSeqReq) (*sdkws.GetMaxAndMinSeqResp, error) { + cc, err := m.getConn() + if err != nil { + return nil, err + } + resp, err := msg.NewMsgClient(cc).GetMaxAndMinSeq(ctx, req) + return resp, err +} + +func (m *MsgClient) PullMessageBySeqList(ctx context.Context, req *sdkws.PullMessageBySeqsReq) (*sdkws.PullMessageBySeqsResp, error) { + cc, err := m.getConn() + if err != nil { + return nil, err + } + resp, err := msg.NewMsgClient(cc).PullMessageBySeqs(ctx, req) + return resp, err +} + +func (c *MsgClient) Notification(ctx context.Context, notificationMsg *NotificationMsg) error { + var err error + var req msg.SendMsgReq + var msg sdkws.MsgData + var offlineInfo sdkws.OfflinePushInfo + var title, desc, ex string + var pushSwitch, unReadCount bool + var reliabilityLevel int + msg.SendID = notificationMsg.SendID + msg.RecvID = notificationMsg.RecvID + msg.Content = notificationMsg.Content + msg.MsgFrom = notificationMsg.MsgFrom + msg.ContentType = notificationMsg.ContentType + msg.SessionType = notificationMsg.SessionType + msg.CreateTime = utils.GetCurrentTimestampByMill() + msg.ClientMsgID = utils.GetMsgID(notificationMsg.SendID) + msg.Options = make(map[string]bool, 7) + msg.SenderNickname = notificationMsg.SenderNickname + msg.SenderFaceURL = notificationMsg.SenderFaceURL + switch notificationMsg.SessionType { + case constant.GroupChatType, constant.SuperGroupChatType: + msg.RecvID = "" + msg.GroupID = notificationMsg.RecvID + } + offlineInfo.IOSBadgeCount = config.Config.IOSPush.BadgeCount + offlineInfo.IOSPushSound = config.Config.IOSPush.PushSound + switch msg.ContentType { + case constant.GroupCreatedNotification: + pushSwitch = config.Config.Notification.GroupCreated.OfflinePush.PushSwitch + title = config.Config.Notification.GroupCreated.OfflinePush.Title + desc = config.Config.Notification.GroupCreated.OfflinePush.Desc + ex = config.Config.Notification.GroupCreated.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.GroupCreated.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.GroupCreated.Conversation.UnreadCount + case constant.GroupInfoSetNotification: + pushSwitch = config.Config.Notification.GroupInfoSet.OfflinePush.PushSwitch + title = config.Config.Notification.GroupInfoSet.OfflinePush.Title + desc = config.Config.Notification.GroupInfoSet.OfflinePush.Desc + ex = config.Config.Notification.GroupInfoSet.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.GroupInfoSet.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.GroupInfoSet.Conversation.UnreadCount + case constant.JoinGroupApplicationNotification: + pushSwitch = config.Config.Notification.JoinGroupApplication.OfflinePush.PushSwitch + title = config.Config.Notification.JoinGroupApplication.OfflinePush.Title + desc = config.Config.Notification.JoinGroupApplication.OfflinePush.Desc + ex = config.Config.Notification.JoinGroupApplication.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.JoinGroupApplication.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.JoinGroupApplication.Conversation.UnreadCount + case constant.MemberQuitNotification: + pushSwitch = config.Config.Notification.MemberQuit.OfflinePush.PushSwitch + title = config.Config.Notification.MemberQuit.OfflinePush.Title + desc = config.Config.Notification.MemberQuit.OfflinePush.Desc + ex = config.Config.Notification.MemberQuit.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.MemberQuit.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.MemberQuit.Conversation.UnreadCount + case constant.GroupApplicationAcceptedNotification: + pushSwitch = config.Config.Notification.GroupApplicationAccepted.OfflinePush.PushSwitch + title = config.Config.Notification.GroupApplicationAccepted.OfflinePush.Title + desc = config.Config.Notification.GroupApplicationAccepted.OfflinePush.Desc + ex = config.Config.Notification.GroupApplicationAccepted.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.GroupApplicationAccepted.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.GroupApplicationAccepted.Conversation.UnreadCount + case constant.GroupApplicationRejectedNotification: + pushSwitch = config.Config.Notification.GroupApplicationRejected.OfflinePush.PushSwitch + title = config.Config.Notification.GroupApplicationRejected.OfflinePush.Title + desc = config.Config.Notification.GroupApplicationRejected.OfflinePush.Desc + ex = config.Config.Notification.GroupApplicationRejected.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.GroupApplicationRejected.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.GroupApplicationRejected.Conversation.UnreadCount + case constant.GroupOwnerTransferredNotification: + pushSwitch = config.Config.Notification.GroupOwnerTransferred.OfflinePush.PushSwitch + title = config.Config.Notification.GroupOwnerTransferred.OfflinePush.Title + desc = config.Config.Notification.GroupOwnerTransferred.OfflinePush.Desc + ex = config.Config.Notification.GroupOwnerTransferred.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.GroupOwnerTransferred.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.GroupOwnerTransferred.Conversation.UnreadCount + case constant.MemberKickedNotification: + pushSwitch = config.Config.Notification.MemberKicked.OfflinePush.PushSwitch + title = config.Config.Notification.MemberKicked.OfflinePush.Title + desc = config.Config.Notification.MemberKicked.OfflinePush.Desc + ex = config.Config.Notification.MemberKicked.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.MemberKicked.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.MemberKicked.Conversation.UnreadCount + case constant.MemberInvitedNotification: + pushSwitch = config.Config.Notification.MemberInvited.OfflinePush.PushSwitch + title = config.Config.Notification.MemberInvited.OfflinePush.Title + desc = config.Config.Notification.MemberInvited.OfflinePush.Desc + ex = config.Config.Notification.MemberInvited.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.MemberInvited.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.MemberInvited.Conversation.UnreadCount + case constant.MemberEnterNotification: + pushSwitch = config.Config.Notification.MemberEnter.OfflinePush.PushSwitch + title = config.Config.Notification.MemberEnter.OfflinePush.Title + desc = config.Config.Notification.MemberEnter.OfflinePush.Desc + ex = config.Config.Notification.MemberEnter.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.MemberEnter.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.MemberEnter.Conversation.UnreadCount + case constant.UserInfoUpdatedNotification: + pushSwitch = config.Config.Notification.UserInfoUpdated.OfflinePush.PushSwitch + title = config.Config.Notification.UserInfoUpdated.OfflinePush.Title + desc = config.Config.Notification.UserInfoUpdated.OfflinePush.Desc + ex = config.Config.Notification.UserInfoUpdated.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.UserInfoUpdated.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.UserInfoUpdated.Conversation.UnreadCount + case constant.FriendApplicationNotification: + pushSwitch = config.Config.Notification.FriendApplication.OfflinePush.PushSwitch + title = config.Config.Notification.FriendApplication.OfflinePush.Title + desc = config.Config.Notification.FriendApplication.OfflinePush.Desc + ex = config.Config.Notification.FriendApplication.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.FriendApplication.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.FriendApplication.Conversation.UnreadCount + case constant.FriendApplicationApprovedNotification: + pushSwitch = config.Config.Notification.FriendApplicationApproved.OfflinePush.PushSwitch + title = config.Config.Notification.FriendApplicationApproved.OfflinePush.Title + desc = config.Config.Notification.FriendApplicationApproved.OfflinePush.Desc + ex = config.Config.Notification.FriendApplicationApproved.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.FriendApplicationApproved.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.FriendApplicationApproved.Conversation.UnreadCount + case constant.FriendApplicationRejectedNotification: + pushSwitch = config.Config.Notification.FriendApplicationRejected.OfflinePush.PushSwitch + title = config.Config.Notification.FriendApplicationRejected.OfflinePush.Title + desc = config.Config.Notification.FriendApplicationRejected.OfflinePush.Desc + ex = config.Config.Notification.FriendApplicationRejected.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.FriendApplicationRejected.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.FriendApplicationRejected.Conversation.UnreadCount + case constant.FriendAddedNotification: + pushSwitch = config.Config.Notification.FriendAdded.OfflinePush.PushSwitch + title = config.Config.Notification.FriendAdded.OfflinePush.Title + desc = config.Config.Notification.FriendAdded.OfflinePush.Desc + ex = config.Config.Notification.FriendAdded.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.FriendAdded.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.FriendAdded.Conversation.UnreadCount + case constant.FriendDeletedNotification: + pushSwitch = config.Config.Notification.FriendDeleted.OfflinePush.PushSwitch + title = config.Config.Notification.FriendDeleted.OfflinePush.Title + desc = config.Config.Notification.FriendDeleted.OfflinePush.Desc + ex = config.Config.Notification.FriendDeleted.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.FriendDeleted.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.FriendDeleted.Conversation.UnreadCount + case constant.FriendRemarkSetNotification: + pushSwitch = config.Config.Notification.FriendRemarkSet.OfflinePush.PushSwitch + title = config.Config.Notification.FriendRemarkSet.OfflinePush.Title + desc = config.Config.Notification.FriendRemarkSet.OfflinePush.Desc + ex = config.Config.Notification.FriendRemarkSet.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.FriendRemarkSet.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.FriendRemarkSet.Conversation.UnreadCount + case constant.BlackAddedNotification: + pushSwitch = config.Config.Notification.BlackAdded.OfflinePush.PushSwitch + title = config.Config.Notification.BlackAdded.OfflinePush.Title + desc = config.Config.Notification.BlackAdded.OfflinePush.Desc + ex = config.Config.Notification.BlackAdded.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.BlackAdded.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.BlackAdded.Conversation.UnreadCount + case constant.BlackDeletedNotification: + pushSwitch = config.Config.Notification.BlackDeleted.OfflinePush.PushSwitch + title = config.Config.Notification.BlackDeleted.OfflinePush.Title + desc = config.Config.Notification.BlackDeleted.OfflinePush.Desc + ex = config.Config.Notification.BlackDeleted.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.BlackDeleted.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.BlackDeleted.Conversation.UnreadCount + case constant.ConversationOptChangeNotification: + pushSwitch = config.Config.Notification.ConversationOptUpdate.OfflinePush.PushSwitch + title = config.Config.Notification.ConversationOptUpdate.OfflinePush.Title + desc = config.Config.Notification.ConversationOptUpdate.OfflinePush.Desc + ex = config.Config.Notification.ConversationOptUpdate.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.ConversationOptUpdate.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.ConversationOptUpdate.Conversation.UnreadCount + + case constant.GroupDismissedNotification: + pushSwitch = config.Config.Notification.GroupDismissed.OfflinePush.PushSwitch + title = config.Config.Notification.GroupDismissed.OfflinePush.Title + desc = config.Config.Notification.GroupDismissed.OfflinePush.Desc + ex = config.Config.Notification.GroupDismissed.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.GroupDismissed.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.GroupDismissed.Conversation.UnreadCount + + case constant.GroupMutedNotification: + pushSwitch = config.Config.Notification.GroupMuted.OfflinePush.PushSwitch + title = config.Config.Notification.GroupMuted.OfflinePush.Title + desc = config.Config.Notification.GroupMuted.OfflinePush.Desc + ex = config.Config.Notification.GroupMuted.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.GroupMuted.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.GroupMuted.Conversation.UnreadCount + + case constant.GroupCancelMutedNotification: + pushSwitch = config.Config.Notification.GroupCancelMuted.OfflinePush.PushSwitch + title = config.Config.Notification.GroupCancelMuted.OfflinePush.Title + desc = config.Config.Notification.GroupCancelMuted.OfflinePush.Desc + ex = config.Config.Notification.GroupCancelMuted.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.GroupCancelMuted.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.GroupCancelMuted.Conversation.UnreadCount + + case constant.GroupMemberMutedNotification: + pushSwitch = config.Config.Notification.GroupMemberMuted.OfflinePush.PushSwitch + title = config.Config.Notification.GroupMemberMuted.OfflinePush.Title + desc = config.Config.Notification.GroupMemberMuted.OfflinePush.Desc + ex = config.Config.Notification.GroupMemberMuted.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.GroupMemberMuted.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.GroupMemberMuted.Conversation.UnreadCount + + case constant.GroupMemberCancelMutedNotification: + pushSwitch = config.Config.Notification.GroupMemberCancelMuted.OfflinePush.PushSwitch + title = config.Config.Notification.GroupMemberCancelMuted.OfflinePush.Title + desc = config.Config.Notification.GroupMemberCancelMuted.OfflinePush.Desc + ex = config.Config.Notification.GroupMemberCancelMuted.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.GroupMemberCancelMuted.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.GroupMemberCancelMuted.Conversation.UnreadCount + + case constant.GroupMemberInfoSetNotification: + pushSwitch = config.Config.Notification.GroupMemberInfoSet.OfflinePush.PushSwitch + title = config.Config.Notification.GroupMemberInfoSet.OfflinePush.Title + desc = config.Config.Notification.GroupMemberInfoSet.OfflinePush.Desc + ex = config.Config.Notification.GroupMemberInfoSet.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.GroupMemberInfoSet.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.GroupMemberInfoSet.Conversation.UnreadCount + + case constant.ConversationPrivateChatNotification: + pushSwitch = config.Config.Notification.ConversationSetPrivate.OfflinePush.PushSwitch + title = config.Config.Notification.ConversationSetPrivate.OfflinePush.Title + desc = config.Config.Notification.ConversationSetPrivate.OfflinePush.Desc + ex = config.Config.Notification.ConversationSetPrivate.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.ConversationSetPrivate.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.ConversationSetPrivate.Conversation.UnreadCount + case constant.FriendInfoUpdatedNotification: + pushSwitch = config.Config.Notification.FriendInfoUpdated.OfflinePush.PushSwitch + title = config.Config.Notification.FriendInfoUpdated.OfflinePush.Title + desc = config.Config.Notification.FriendInfoUpdated.OfflinePush.Desc + ex = config.Config.Notification.FriendInfoUpdated.OfflinePush.Ext + reliabilityLevel = config.Config.Notification.FriendInfoUpdated.Conversation.ReliabilityLevel + unReadCount = config.Config.Notification.FriendInfoUpdated.Conversation.UnreadCount + case constant.DeleteMessageNotification: + reliabilityLevel = constant.ReliableNotificationNoMsg + case constant.ConversationUnreadNotification, constant.SuperGroupUpdateNotification: + reliabilityLevel = constant.UnreliableNotification + } + switch reliabilityLevel { + case constant.UnreliableNotification: + utils.SetSwitchFromOptions(msg.Options, constant.IsHistory, false) + utils.SetSwitchFromOptions(msg.Options, constant.IsPersistent, false) + utils.SetSwitchFromOptions(msg.Options, constant.IsConversationUpdate, false) + utils.SetSwitchFromOptions(msg.Options, constant.IsSenderConversationUpdate, false) + case constant.ReliableNotificationNoMsg: + utils.SetSwitchFromOptions(msg.Options, constant.IsConversationUpdate, false) + utils.SetSwitchFromOptions(msg.Options, constant.IsSenderConversationUpdate, false) + case constant.ReliableNotificationMsg: + + } + utils.SetSwitchFromOptions(msg.Options, constant.IsUnreadCount, unReadCount) + utils.SetSwitchFromOptions(msg.Options, constant.IsOfflinePush, pushSwitch) + offlineInfo.Title = title + offlineInfo.Desc = desc + offlineInfo.Ex = ex + msg.OfflinePushInfo = &offlineInfo + req.MsgData = &msg + _, err = c.SendMsg(ctx, &req) + return err +} diff --git a/pkg/rpcclient/notification2/friend.go b/pkg/rpcclient/notification2/friend.go new file mode 100644 index 000000000..6c60fcc34 --- /dev/null +++ b/pkg/rpcclient/notification2/friend.go @@ -0,0 +1,170 @@ +package notification2 + +import ( + "context" + + "github.com/OpenIMSDK/Open-IM-Server/pkg/common/config" + "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" + "github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry" + pbFriend "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/friend" + "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" + "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient" + "github.com/golang/protobuf/jsonpb" + "github.com/golang/protobuf/proto" +) + +type FriendNotificationSender struct { + *rpcclient.MsgClient + getUsersInfoMap func(ctx context.Context, userIDs []string, complete bool) (map[string]*sdkws.UserInfo, error) + getFriendsInfo func(ctx context.Context, ownerUserID, friendUserID string) (resp *sdkws.FriendInfo, err error) + getUsersInfo func(ctx context.Context, userIDs []string, complete bool) ([]*sdkws.UserInfo, error) +} + +func NewFriendNotificationSender(client discoveryregistry.SvcDiscoveryRegistry, getUsersInfoMap func(ctx context.Context, userIDs []string, complete bool) (map[string]*sdkws.UserInfo, error)) *FriendNotificationSender { + return &FriendNotificationSender{ + MsgClient: rpcclient.NewMsgClient(client), + getUsersInfoMap: getUsersInfoMap, + } +} + +func (c *FriendNotificationSender) getFromToUserNickname(ctx context.Context, fromUserID, toUserID string) (string, string, error) { + users, err := c.getUsersInfoMap(ctx, []string{fromUserID, toUserID}, true) + if err != nil { + return "", "", nil + } + return users[fromUserID].Nickname, users[toUserID].Nickname, nil +} + +func (c *FriendNotificationSender) friendNotification(ctx context.Context, fromUserID, toUserID string, contentType int32, m proto.Message) { + var err error + var tips sdkws.TipsComm + tips.Detail, err = proto.Marshal(m) + if err != nil { + return + } + + marshaler := jsonpb.Marshaler{ + OrigName: true, + EnumsAsInts: false, + EmitDefaults: false, + } + + tips.JsonDetail, _ = marshaler.MarshalToString(m) + + fromUserNickname, toUserNickname, err := c.getFromToUserNickname(ctx, fromUserID, toUserID) + if err != nil { + return + } + cn := config.Config.Notification + switch contentType { + case constant.FriendApplicationNotification: + tips.DefaultTips = fromUserNickname + cn.FriendApplication.DefaultTips.Tips + case constant.FriendApplicationApprovedNotification: + tips.DefaultTips = fromUserNickname + cn.FriendApplicationApproved.DefaultTips.Tips + case constant.FriendApplicationRejectedNotification: + tips.DefaultTips = fromUserNickname + cn.FriendApplicationRejected.DefaultTips.Tips + case constant.FriendAddedNotification: + tips.DefaultTips = cn.FriendAdded.DefaultTips.Tips + case constant.FriendDeletedNotification: + tips.DefaultTips = cn.FriendDeleted.DefaultTips.Tips + toUserNickname + case constant.FriendRemarkSetNotification: + tips.DefaultTips = fromUserNickname + cn.FriendRemarkSet.DefaultTips.Tips + case constant.BlackAddedNotification: + tips.DefaultTips = cn.BlackAdded.DefaultTips.Tips + case constant.BlackDeletedNotification: + tips.DefaultTips = cn.BlackDeleted.DefaultTips.Tips + toUserNickname + case constant.UserInfoUpdatedNotification: + tips.DefaultTips = cn.UserInfoUpdated.DefaultTips.Tips + case constant.FriendInfoUpdatedNotification: + tips.DefaultTips = cn.FriendInfoUpdated.DefaultTips.Tips + toUserNickname + default: + return + } + + var n rpcclient.NotificationMsg + n.SendID = fromUserID + n.RecvID = toUserID + n.ContentType = contentType + n.SessionType = constant.SingleChatType + n.MsgFrom = constant.SysMsgType + n.Content, err = proto.Marshal(&tips) + if err != nil { + return + } + c.Notification(ctx, &n) +} + +func (c *FriendNotificationSender) FriendApplicationAddNotification(ctx context.Context, req *pbFriend.ApplyToAddFriendReq) { + FriendApplicationTips := sdkws.FriendApplicationTips{FromToUserID: &sdkws.FromToUserID{}} + FriendApplicationTips.FromToUserID.FromUserID = req.FromUserID + FriendApplicationTips.FromToUserID.ToUserID = req.ToUserID + c.friendNotification(ctx, req.FromUserID, req.ToUserID, constant.FriendApplicationNotification, &FriendApplicationTips) +} + +func (c *FriendNotificationSender) FriendApplicationAgreedNotification(ctx context.Context, req *pbFriend.RespondFriendApplyReq) { + FriendApplicationApprovedTips := sdkws.FriendApplicationApprovedTips{FromToUserID: &sdkws.FromToUserID{}} + FriendApplicationApprovedTips.FromToUserID.FromUserID = req.FromUserID + FriendApplicationApprovedTips.FromToUserID.ToUserID = req.ToUserID + FriendApplicationApprovedTips.HandleMsg = req.HandleMsg + c.friendNotification(ctx, req.ToUserID, req.FromUserID, constant.FriendApplicationApprovedNotification, &FriendApplicationApprovedTips) +} + +func (c *FriendNotificationSender) FriendApplicationRefusedNotification(ctx context.Context, req *pbFriend.RespondFriendApplyReq) { + FriendApplicationApprovedTips := sdkws.FriendApplicationApprovedTips{FromToUserID: &sdkws.FromToUserID{}} + FriendApplicationApprovedTips.FromToUserID.FromUserID = req.FromUserID + FriendApplicationApprovedTips.FromToUserID.ToUserID = req.ToUserID + FriendApplicationApprovedTips.HandleMsg = req.HandleMsg + c.friendNotification(ctx, req.ToUserID, req.FromUserID, constant.FriendApplicationRejectedNotification, &FriendApplicationApprovedTips) +} + +func (c *FriendNotificationSender) FriendAddedNotification(ctx context.Context, operationID, opUserID, fromUserID, toUserID string) { + friendAddedTips := sdkws.FriendAddedTips{Friend: &sdkws.FriendInfo{}, OpUser: &sdkws.PublicUserInfo{}} + user, err := c.getUsersInfo(ctx, []string{opUserID}, true) + if err != nil { + return + } + friendAddedTips.OpUser.UserID = user[0].UserID + friendAddedTips.OpUser.Ex = user[0].Ex + friendAddedTips.OpUser.Nickname = user[0].Nickname + friendAddedTips.OpUser.FaceURL = user[0].FaceURL + + friend, err := c.getFriendsInfo(ctx, fromUserID, toUserID) + if err != nil { + return + } + friendAddedTips.Friend = friend + c.friendNotification(ctx, fromUserID, toUserID, constant.FriendAddedNotification, &friendAddedTips) +} + +func (c *FriendNotificationSender) FriendDeletedNotification(ctx context.Context, req *pbFriend.DeleteFriendReq) { + friendDeletedTips := sdkws.FriendDeletedTips{FromToUserID: &sdkws.FromToUserID{}} + friendDeletedTips.FromToUserID.FromUserID = req.OwnerUserID + friendDeletedTips.FromToUserID.ToUserID = req.FriendUserID + c.friendNotification(ctx, req.OwnerUserID, req.FriendUserID, constant.FriendDeletedNotification, &friendDeletedTips) +} + +func (c *FriendNotificationSender) FriendRemarkSetNotification(ctx context.Context, fromUserID, toUserID string) { + friendInfoChangedTips := sdkws.FriendInfoChangedTips{FromToUserID: &sdkws.FromToUserID{}} + friendInfoChangedTips.FromToUserID.FromUserID = fromUserID + friendInfoChangedTips.FromToUserID.ToUserID = toUserID + c.friendNotification(ctx, fromUserID, toUserID, constant.FriendRemarkSetNotification, &friendInfoChangedTips) +} + +func (c *FriendNotificationSender) BlackAddedNotification(ctx context.Context, req *pbFriend.AddBlackReq) { + blackAddedTips := sdkws.BlackAddedTips{FromToUserID: &sdkws.FromToUserID{}} + blackAddedTips.FromToUserID.FromUserID = req.OwnerUserID + blackAddedTips.FromToUserID.ToUserID = req.BlackUserID + c.friendNotification(ctx, req.OwnerUserID, req.BlackUserID, constant.BlackAddedNotification, &blackAddedTips) +} + +func (c *FriendNotificationSender) BlackDeletedNotification(ctx context.Context, req *pbFriend.RemoveBlackReq) { + blackDeletedTips := sdkws.BlackDeletedTips{FromToUserID: &sdkws.FromToUserID{}} + blackDeletedTips.FromToUserID.FromUserID = req.OwnerUserID + blackDeletedTips.FromToUserID.ToUserID = req.BlackUserID + c.friendNotification(ctx, req.OwnerUserID, req.BlackUserID, constant.BlackDeletedNotification, &blackDeletedTips) +} + +func (c *FriendNotificationSender) FriendInfoUpdatedNotification(ctx context.Context, changedUserID string, needNotifiedUserID string, opUserID string) { + selfInfoUpdatedTips := sdkws.UserInfoUpdatedTips{UserID: changedUserID} + c.friendNotification(ctx, opUserID, needNotifiedUserID, constant.FriendInfoUpdatedNotification, &selfInfoUpdatedTips) +} diff --git a/pkg/rpcclient/notification2/n.go b/pkg/rpcclient/notification2/n.go new file mode 100644 index 000000000..1e74dcfff --- /dev/null +++ b/pkg/rpcclient/notification2/n.go @@ -0,0 +1,12 @@ +package notification2 + +type NotificationMsg struct { + SendID string + RecvID string + Content []byte // sdkws.TipsComm + MsgFrom int32 + ContentType int32 + SessionType int32 + SenderNickname string + SenderFaceURL string +} diff --git a/pkg/rpcclient/user_client.go b/pkg/rpcclient/user_client.go new file mode 100644 index 000000000..0ff0370c9 --- /dev/null +++ b/pkg/rpcclient/user_client.go @@ -0,0 +1,112 @@ +package rpcclient + +import ( + "context" + "strings" + + "github.com/OpenIMSDK/Open-IM-Server/pkg/common/config" + "github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry" + "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" + "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" + "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/user" + "github.com/OpenIMSDK/Open-IM-Server/pkg/utils" +) + +type UserClient struct { + MetaClient +} + +func NewUserClient(client discoveryregistry.SvcDiscoveryRegistry) *GroupClient { + return &GroupClient{ + MetaClient: MetaClient{ + client: client, + rpcRegisterName: config.Config.RpcRegisterName.OpenImUserName, + }, + } +} + +func (u *UserClient) GetUsersInfos(ctx context.Context, userIDs []string, complete bool) ([]*sdkws.UserInfo, error) { + cc, err := u.getConn() + if err != nil { + return nil, err + } + resp, err := user.NewUserClient(cc).GetDesignateUsers(ctx, &user.GetDesignateUsersReq{ + UserIDs: userIDs, + }) + if err != nil { + return nil, err + } + if complete { + if ids := utils.Single(userIDs, utils.Slice(resp.UsersInfo, func(e *sdkws.UserInfo) string { + return e.UserID + })); len(ids) > 0 { + return nil, errs.ErrUserIDNotFound.Wrap(strings.Join(ids, ",")) + } + } + return resp.UsersInfo, nil +} + +func (u *UserClient) GetUserInfo(ctx context.Context, userID string) (*sdkws.UserInfo, error) { + users, err := u.GetUsersInfos(ctx, []string{userID}, true) + if err != nil { + return nil, err + } + return users[0], nil +} + +func (u *UserClient) GetUsersInfoMap(ctx context.Context, userIDs []string, complete bool) (map[string]*sdkws.UserInfo, error) { + users, err := u.GetUsersInfos(ctx, userIDs, complete) + if err != nil { + return nil, err + } + return utils.SliceToMap(users, func(e *sdkws.UserInfo) string { + return e.UserID + }), nil +} + +func (u *UserClient) GetPublicUserInfos(ctx context.Context, userIDs []string, complete bool) ([]*sdkws.PublicUserInfo, error) { + users, err := u.GetUsersInfos(ctx, userIDs, complete) + if err != nil { + return nil, err + } + return utils.Slice(users, func(e *sdkws.UserInfo) *sdkws.PublicUserInfo { + return &sdkws.PublicUserInfo{ + UserID: e.UserID, + Nickname: e.Nickname, + FaceURL: e.FaceURL, + Ex: e.Ex, + } + }), nil +} + +func (u *UserClient) GetPublicUserInfo(ctx context.Context, userID string) (*sdkws.PublicUserInfo, error) { + users, err := u.GetPublicUserInfos(ctx, []string{userID}, true) + if err != nil { + return nil, err + } + return users[0], nil +} + +func (u *UserClient) GetPublicUserInfoMap(ctx context.Context, userIDs []string, complete bool) (map[string]*sdkws.PublicUserInfo, error) { + users, err := u.GetPublicUserInfos(ctx, userIDs, complete) + if err != nil { + return nil, err + } + return utils.SliceToMap(users, func(e *sdkws.PublicUserInfo) string { + return e.UserID + }), nil +} + +func (u *UserClient) GetUserGlobalMsgRecvOpt(ctx context.Context, userID string) (int32, error) { + cc, err := u.getConn() + if err != nil { + return 0, err + } + resp, err := user.NewUserClient(cc).GetGlobalRecvMessageOpt(ctx, &user.GetGlobalRecvMessageOptReq{ + UserID: userID, + }) + if err != nil { + return 0, err + } + return resp.GlobalRecvMsgOpt, err +}