mirror of
https://github.com/openimsdk/open-im-server.git
synced 2026-07-04 09:57:43 +08:00
commit
9f31031a94
@ -210,6 +210,7 @@ func newGinRouter(ctx context.Context, client discovery.SvcDiscoveryRegistry, co
|
||||
friendRouterGroup.POST("/get_full_friend_user_ids", f.GetFullFriendUserIDs)
|
||||
friendRouterGroup.POST("/get_self_unhandled_apply_count", f.GetSelfUnhandledApplyCount)
|
||||
friendRouterGroup.POST("/get_pinned_friend_ids", f.GetPinnedFriendIDs)
|
||||
friendRouterGroup.POST("/add_oneway_friend", f.AddOnewayFriend)
|
||||
}
|
||||
|
||||
g := NewGroupApi(group.NewGroupClient(groupConn))
|
||||
|
||||
@ -700,6 +700,12 @@ func (s *friendServer) AddOnewayFriend(ctx context.Context, req *relation.ApplyT
|
||||
if err := s.db.BecomeOnewayFriend(ctx, req.FromUserID, req.ToUserID, becomeFriendByOneway); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Silently notify only A (FromUserID) to trigger an incremental friend-list sync
|
||||
// so the remark is reflected in the conversation list.
|
||||
// B (ToUserID) receives no notification of any kind.
|
||||
s.notificationSender.FriendAddedOnewayNotification(ctx, req.FromUserID, req.ToUserID)
|
||||
|
||||
// Notify only A (FromUserID) so incremental friend sync is triggered
|
||||
// without notifying B (ToUserID).
|
||||
//tips := sdkws.FriendApplicationApprovedTips{
|
||||
|
||||
@ -282,6 +282,19 @@ func (f *FriendNotificationSender) FriendsInfoUpdateNotification(ctx context.Con
|
||||
f.Notification(ctx, toUserID, toUserID, constant.FriendsInfoUpdateNotification, &tips)
|
||||
}
|
||||
|
||||
// FriendAddedOnewayNotification silently notifies ownerUserID that friendUserID has been added
|
||||
// to their friend list (one-way, no consent from friendUserID required).
|
||||
// isSendMsg=false ensures no visible message appears in either user's conversation list.
|
||||
func (f *FriendNotificationSender) FriendAddedOnewayNotification(ctx context.Context, ownerUserID, friendUserID string) {
|
||||
tips := sdkws.FriendsInfoUpdateTips{
|
||||
FromToUserID: &sdkws.FromToUserID{ToUserID: ownerUserID},
|
||||
FriendIDs: []string{friendUserID},
|
||||
}
|
||||
f.setSortVersion(ctx, &tips.FriendVersion, &tips.FriendVersionID,
|
||||
database.FriendVersionName, ownerUserID, &tips.FriendSortVersion)
|
||||
f.Notification(ctx, ownerUserID, ownerUserID, constant.FriendsInfoUpdateNotification, &tips)
|
||||
}
|
||||
|
||||
func (f *FriendNotificationSender) BlackAddedNotification(ctx context.Context, req *relation.AddBlackReq) {
|
||||
tips := sdkws.BlackAddedTips{FromToUserID: &sdkws.FromToUserID{}}
|
||||
tips.FromToUserID.FromUserID = req.OwnerUserID
|
||||
|
||||
@ -108,6 +108,19 @@ func (s *rtcServer) handleInvite(ctx context.Context, req *rtc.SignalInviteReq,
|
||||
}
|
||||
}
|
||||
|
||||
// 从主叫用户资料获取铃声 URL,注入到邀请信息中,被叫方收到后播放主叫方铃声
|
||||
if inviterInfo, err := s.userClient.GetUserInfo(ctx, req.UserID); err == nil && inviterInfo.CallRingtoneURL != "" {
|
||||
inv.CallerRingtoneURL = inviterInfo.CallRingtoneURL
|
||||
}
|
||||
|
||||
// 查询被叫方铃声 URL,供主叫方在等待时播放
|
||||
var calleeRingtoneURL string
|
||||
if len(inv.InviteeUserIDList) > 0 {
|
||||
if inviteeInfo, err := s.userClient.GetUserInfo(ctx, inv.InviteeUserIDList[0]); err == nil {
|
||||
calleeRingtoneURL = inviteeInfo.CallRingtoneURL
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := s.roomClient.CreateRoom(ctx, &livekit.CreateRoomRequest{Name: inv.RoomID}); err != nil {
|
||||
log.ZError(ctx, "handleInvite", err, "r", err.Error())
|
||||
return nil, errs.WrapMsg(err, "LiveKit CreateRoom failed", "roomID", inv.RoomID)
|
||||
@ -147,9 +160,10 @@ func (s *rtcServer) handleInvite(ctx context.Context, req *rtc.SignalInviteReq,
|
||||
|
||||
log.ZDebug(ctx, "handleInvite", "token", token, "roomID", inv.RoomID, "liveURL", s.config.RpcConfig.LiveKit.ExternalAddress)
|
||||
return &rtc.SignalInviteResp{
|
||||
Token: token,
|
||||
RoomID: inv.RoomID,
|
||||
LiveURL: s.config.RpcConfig.LiveKit.ExternalAddress,
|
||||
Token: token,
|
||||
RoomID: inv.RoomID,
|
||||
LiveURL: s.config.RpcConfig.LiveKit.ExternalAddress,
|
||||
CalleeRingtoneURL: calleeRingtoneURL,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -164,6 +178,19 @@ func (s *rtcServer) handleInviteInGroup(ctx context.Context, req *rtc.SignalInvi
|
||||
inv.InviterUserID = req.UserID
|
||||
inv.InitiateTime = time.Now().UnixMilli()
|
||||
|
||||
// 从主叫用户资料获取铃声 URL,注入到邀请信息中,被叫方收到后播放主叫方铃声
|
||||
if inviterInfo, err := s.userClient.GetUserInfo(ctx, req.UserID); err == nil && inviterInfo.CallRingtoneURL != "" {
|
||||
inv.CallerRingtoneURL = inviterInfo.CallRingtoneURL
|
||||
}
|
||||
|
||||
// 查询第一位被叫的铃声 URL,供主叫方在等待时播放
|
||||
var calleeRingtoneURL string
|
||||
if len(inv.InviteeUserIDList) > 0 {
|
||||
if inviteeInfo, err := s.userClient.GetUserInfo(ctx, inv.InviteeUserIDList[0]); err == nil {
|
||||
calleeRingtoneURL = inviteeInfo.CallRingtoneURL
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := s.roomClient.CreateRoom(ctx, &livekit.CreateRoomRequest{Name: inv.RoomID}); err != nil {
|
||||
return nil, errs.WrapMsg(err, "LiveKit CreateRoom failed", "roomID", inv.RoomID)
|
||||
}
|
||||
@ -206,9 +233,10 @@ func (s *rtcServer) handleInviteInGroup(ctx context.Context, req *rtc.SignalInvi
|
||||
}
|
||||
|
||||
return &rtc.SignalInviteInGroupResp{
|
||||
Token: token,
|
||||
RoomID: inv.RoomID,
|
||||
LiveURL: s.config.RpcConfig.LiveKit.ExternalAddress,
|
||||
Token: token,
|
||||
RoomID: inv.RoomID,
|
||||
LiveURL: s.config.RpcConfig.LiveKit.ExternalAddress,
|
||||
CalleeRingtoneURL: calleeRingtoneURL,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@ -46,9 +46,11 @@ func UserDB2Pb(user *relationtb.User) *sdkws.UserInfo {
|
||||
FirstName: user.FirstName,
|
||||
LastName: user.LastName,
|
||||
Phone: user.Phone,
|
||||
AreaCode: user.AreaCode,
|
||||
PhoneVisibility: user.PhoneVisibility,
|
||||
CallAcceptSetting: user.CallAcceptSetting,
|
||||
MsgReceiveSetting: user.MsgReceiveSetting,
|
||||
CallRingtoneURL: user.CallRingtoneURL,
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,16 +61,18 @@ func UsersDB2Pb(users []*relationtb.User) []*sdkws.UserInfo {
|
||||
func UserPb2DB(user *sdkws.UserInfo) *relationtb.User {
|
||||
fullName := BuildFullName(user.FirstName, user.LastName)
|
||||
return &relationtb.User{
|
||||
UserID: user.UserID,
|
||||
Nickname: user.Nickname,
|
||||
FaceURL: user.FaceURL,
|
||||
Ex: user.Ex,
|
||||
CreateTime: time.UnixMilli(user.CreateTime),
|
||||
AppMangerLevel: user.AppMangerLevel,
|
||||
UserID: user.UserID,
|
||||
Nickname: user.Nickname,
|
||||
FaceURL: user.FaceURL,
|
||||
Ex: user.Ex,
|
||||
CreateTime: time.UnixMilli(user.CreateTime),
|
||||
AppMangerLevel: user.AppMangerLevel,
|
||||
GlobalRecvMsgOpt: user.GlobalRecvMsgOpt,
|
||||
FirstName: user.FirstName,
|
||||
LastName: user.LastName,
|
||||
FullName: fullName,
|
||||
FirstName: user.FirstName,
|
||||
LastName: user.LastName,
|
||||
FullName: fullName,
|
||||
AreaCode: user.AreaCode,
|
||||
CallRingtoneURL: user.CallRingtoneURL,
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,8 +87,10 @@ func UserPb2DBMap(user *sdkws.UserInfo) map[string]any {
|
||||
"ex": user.Ex,
|
||||
"first_name": user.FirstName,
|
||||
"last_name": user.LastName,
|
||||
"area_code": user.AreaCode,
|
||||
"app_manager_level": user.AppMangerLevel,
|
||||
"global_recv_msg_opt": user.GlobalRecvMsgOpt,
|
||||
"call_ringtone_url": user.CallRingtoneURL,
|
||||
}
|
||||
for key, value := range fields {
|
||||
if v, ok := value.(string); ok && v != "" {
|
||||
@ -115,12 +121,32 @@ func UserPb2DBMapEx(user *sdkws.UserInfoWithEx) map[string]any {
|
||||
if user.Ex != nil {
|
||||
val["ex"] = user.Ex.Value
|
||||
}
|
||||
if user.FirstName != nil {
|
||||
val["first_name"] = user.FirstName.Value
|
||||
}
|
||||
if user.LastName != nil {
|
||||
val["last_name"] = user.LastName.Value
|
||||
}
|
||||
if user.FirstName != nil || user.LastName != nil {
|
||||
firstName := ""
|
||||
lastName := ""
|
||||
if user.FirstName != nil {
|
||||
firstName = user.FirstName.Value
|
||||
}
|
||||
if user.LastName != nil {
|
||||
lastName = user.LastName.Value
|
||||
}
|
||||
val["full_name"] = BuildFullName(firstName, lastName)
|
||||
}
|
||||
if user.GlobalRecvMsgOpt != nil {
|
||||
val["global_recv_msg_opt"] = user.GlobalRecvMsgOpt.Value
|
||||
}
|
||||
if user.Phone != nil {
|
||||
val["phone"] = user.Phone.Value
|
||||
}
|
||||
if user.AreaCode != nil {
|
||||
val["area_code"] = user.AreaCode.Value
|
||||
}
|
||||
if user.PhoneVisibility != nil {
|
||||
val["phone_visibility"] = user.PhoneVisibility.Value
|
||||
}
|
||||
@ -130,7 +156,8 @@ func UserPb2DBMapEx(user *sdkws.UserInfoWithEx) map[string]any {
|
||||
if user.MsgReceiveSetting != nil {
|
||||
val["msg_receive_setting"] = user.MsgReceiveSetting.Value
|
||||
}
|
||||
// TODO: Add FirstName/LastName support to UserInfoWithEx proto when regenerated
|
||||
|
||||
if user.CallRingtoneURL != nil {
|
||||
val["call_ringtone_url"] = user.CallRingtoneURL.Value
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
@ -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"
|
||||
@ -63,7 +64,38 @@ func (u *UserMgo) UpdateByMap(ctx context.Context, userID string, args map[strin
|
||||
if len(args) == 0 {
|
||||
return nil
|
||||
}
|
||||
return mongoutil.UpdateOne(ctx, u.coll, bson.M{"user_id": userID}, bson.M{"$set": args}, true)
|
||||
filter := bson.M{"user_id": userID}
|
||||
update := bson.M{"$set": args}
|
||||
if err := mongoutil.UpdateOne(ctx, u.coll, filter, update, true); err != nil {
|
||||
return err
|
||||
}
|
||||
// Keep user attributes in sync for consumers that read from the "attribute" collection.
|
||||
// Only sync the allowed attribute fields.
|
||||
attributeSet := make(map[string]any)
|
||||
for _, key := range []string{
|
||||
"nickname",
|
||||
"first_name",
|
||||
"last_name",
|
||||
"full_name",
|
||||
"remark",
|
||||
"face_url",
|
||||
"phone_number",
|
||||
"area_code",
|
||||
} {
|
||||
if v, ok := args[key]; ok {
|
||||
attributeSet[key] = v
|
||||
}
|
||||
}
|
||||
//// user collection uses "phone"; attribute collection uses "phone_number".
|
||||
if v, ok := args["phone"]; ok {
|
||||
attributeSet["phone_number"] = v
|
||||
}
|
||||
if len(attributeSet) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
attributeColl := u.coll.Database().Collection("attribute")
|
||||
return mongoutil.UpdateOne(ctx, attributeColl, filter, bson.M{"$set": attributeSet}, true)
|
||||
}
|
||||
|
||||
func (u *UserMgo) Find(ctx context.Context, userIDs []string) (users []*model.User, err error) {
|
||||
|
||||
@ -62,9 +62,12 @@ type User struct {
|
||||
LastName string `bson:"last_name"`
|
||||
FullName string `bson:"full_name"`
|
||||
Phone string `bson:"phone"`
|
||||
AreaCode string `bson:"area_code"`
|
||||
PhoneVisibility int32 `bson:"phone_visibility"`
|
||||
CallAcceptSetting int32 `bson:"call_accept_setting"`
|
||||
MsgReceiveSetting int32 `bson:"msg_receive_setting"`
|
||||
// CallRingtoneURL 用户自定义来电铃声 URL;对方来电时播放此铃声
|
||||
CallRingtoneURL string `bson:"call_ringtone_url"`
|
||||
// Status 账号状态:0=正常,1=冻结,2=黑名单
|
||||
Status int32 `bson:"status"`
|
||||
}
|
||||
|
||||
2
protocol
2
protocol
@ -1 +1 @@
|
||||
Subproject commit 7f613eb71f23a69730cfb3c3abd1515da0fb17cf
|
||||
Subproject commit 3b211f91d0e6b98797f91ba34fa64a7b47df5645
|
||||
Loading…
x
Reference in New Issue
Block a user