From 6c12751e270ccf5be4dccadefa33ef39d5a722cc Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Fri, 14 Jul 2023 20:07:26 +0800 Subject: [PATCH 01/62] fix: implement of GetUsersOnlineStatus (#567) --- internal/api/user.go | 2 +- internal/msggateway/hub_server.go | 5 ----- pkg/common/db/cache/conversation.go | 6 +++--- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/internal/api/user.go b/internal/api/user.go index 28cb74509..baea8fed3 100644 --- a/internal/api/user.go +++ b/internal/api/user.go @@ -83,7 +83,7 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) { msgClient := msggateway.NewMsgGatewayClient(v) reply, err := msgClient.GetUsersOnlineStatus(c, &req) if err != nil { - log.ZWarn(c, "GetUsersOnlineStatus rpc err", err) + log.ZWarn(c, "GetUsersOnlineStatus rpc err", err) continue } else { wsResult = append(wsResult, reply.SuccessResult...) diff --git a/internal/msggateway/hub_server.go b/internal/msggateway/hub_server.go index 81aade1cb..5b756bf92 100644 --- a/internal/msggateway/hub_server.go +++ b/internal/msggateway/hub_server.go @@ -25,9 +25,7 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/log" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/prome" - "github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify" "github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry" - "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msggateway" "github.com/OpenIMSDK/Open-IM-Server/pkg/startrpc" "github.com/OpenIMSDK/Open-IM-Server/pkg/utils" @@ -84,9 +82,6 @@ func (s *Server) GetUsersOnlineStatus( ctx context.Context, req *msggateway.GetUsersOnlineStatusReq, ) (*msggateway.GetUsersOnlineStatusResp, error) { - if !tokenverify.IsAppManagerUid(ctx) { - return nil, errs.ErrNoPermission.Wrap("only app manager") - } var resp msggateway.GetUsersOnlineStatusResp for _, userID := range req.UserIDs { clients, ok := s.LongConnServer.GetUserAllCons(userID) diff --git a/pkg/common/db/cache/conversation.go b/pkg/common/db/cache/conversation.go index d3a9d44aa..119967c70 100644 --- a/pkg/common/db/cache/conversation.go +++ b/pkg/common/db/cache/conversation.go @@ -54,7 +54,7 @@ type ConversationCache interface { // get one conversation from msgCache GetConversation(ctx context.Context, ownerUserID, conversationID string) (*relationTb.ConversationModel, error) - DelConvsersations(ownerUserID string, conversationIDs ...string) ConversationCache + DelConversations(ownerUserID string, conversationIDs ...string) ConversationCache DelUsersConversation(conversationID string, ownerUserIDs ...string) ConversationCache // get one conversation from msgCache GetConversations( @@ -225,9 +225,9 @@ func (c *ConversationRedisCache) GetConversation( ) } -func (c *ConversationRedisCache) DelConvsersations(ownerUserID string, convsersationIDs ...string) ConversationCache { +func (c *ConversationRedisCache) DelConversations(ownerUserID string, conversationIDs ...string) ConversationCache { var keys []string - for _, conversationID := range convsersationIDs { + for _, conversationID := range conversationIDs { keys = append(keys, c.getConversationKey(ownerUserID, conversationID)) } cache := c.NewCache() From b5e5945b61b398fe1a4d676fd885bff50c4ac4cb Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Mon, 17 Jul 2023 15:13:28 +0800 Subject: [PATCH 02/62] fix bug: obtain user online status err(#567) --- internal/api/user.go | 6 +++++- internal/msggateway/hub_server.go | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/internal/api/user.go b/internal/api/user.go index baea8fed3..1e75b8fb4 100644 --- a/internal/api/user.go +++ b/internal/api/user.go @@ -84,7 +84,11 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) { reply, err := msgClient.GetUsersOnlineStatus(c, &req) if err != nil { log.ZWarn(c, "GetUsersOnlineStatus rpc err", err) - continue + // apiresp.GinError(c, err) + parseError := apiresp.ParseError(err) + if parseError.ErrCode == errs.NoPermissionError { + apiresp.GinError(c, err) + } } else { wsResult = append(wsResult, reply.SuccessResult...) } diff --git a/internal/msggateway/hub_server.go b/internal/msggateway/hub_server.go index 6d852515c..992943fe9 100644 --- a/internal/msggateway/hub_server.go +++ b/internal/msggateway/hub_server.go @@ -16,6 +16,8 @@ package msggateway import ( "context" + "github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify" + "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache" From 459efacd3c36eef3b1a78d3f26458ad2d5992c72 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Mon, 17 Jul 2023 16:29:01 +0800 Subject: [PATCH 03/62] fix bug: obtain user online status err(#567) --- internal/msggateway/hub_server.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/msggateway/hub_server.go b/internal/msggateway/hub_server.go index 992943fe9..deb8c3d77 100644 --- a/internal/msggateway/hub_server.go +++ b/internal/msggateway/hub_server.go @@ -16,11 +16,10 @@ package msggateway import ( "context" + "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify" "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" - "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache" - "google.golang.org/grpc" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/config" @@ -84,6 +83,9 @@ func (s *Server) GetUsersOnlineStatus( ctx context.Context, req *msggateway.GetUsersOnlineStatusReq, ) (*msggateway.GetUsersOnlineStatusResp, error) { + if !tokenverify.IsAppManagerUid(ctx) { + return nil, errs.ErrNoPermission.Wrap("only app manager") + } var resp msggateway.GetUsersOnlineStatusResp for _, userID := range req.UserIDs { clients, ok := s.LongConnServer.GetUserAllCons(userID) From a06de3c7d7d7fac799243e9a1b7f2c9e1849c799 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Mon, 17 Jul 2023 16:30:48 +0800 Subject: [PATCH 04/62] fix bug: obtain user online status err(#567) --- internal/msggateway/hub_server.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/msggateway/hub_server.go b/internal/msggateway/hub_server.go index 992943fe9..deb8c3d77 100644 --- a/internal/msggateway/hub_server.go +++ b/internal/msggateway/hub_server.go @@ -16,11 +16,10 @@ package msggateway import ( "context" + "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify" "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" - "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache" - "google.golang.org/grpc" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/config" @@ -84,6 +83,9 @@ func (s *Server) GetUsersOnlineStatus( ctx context.Context, req *msggateway.GetUsersOnlineStatusReq, ) (*msggateway.GetUsersOnlineStatusResp, error) { + if !tokenverify.IsAppManagerUid(ctx) { + return nil, errs.ErrNoPermission.Wrap("only app manager") + } var resp msggateway.GetUsersOnlineStatusResp for _, userID := range req.UserIDs { clients, ok := s.LongConnServer.GetUserAllCons(userID) From 4e9ac1081b9250b2b664f97596a572077929899d Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Mon, 17 Jul 2023 16:32:28 +0800 Subject: [PATCH 05/62] fix bug: obtain user online status err(#567) --- internal/api/user.go | 6 +++++- internal/msggateway/hub_server.go | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/internal/api/user.go b/internal/api/user.go index baea8fed3..1e75b8fb4 100644 --- a/internal/api/user.go +++ b/internal/api/user.go @@ -84,7 +84,11 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) { reply, err := msgClient.GetUsersOnlineStatus(c, &req) if err != nil { log.ZWarn(c, "GetUsersOnlineStatus rpc err", err) - continue + // apiresp.GinError(c, err) + parseError := apiresp.ParseError(err) + if parseError.ErrCode == errs.NoPermissionError { + apiresp.GinError(c, err) + } } else { wsResult = append(wsResult, reply.SuccessResult...) } diff --git a/internal/msggateway/hub_server.go b/internal/msggateway/hub_server.go index 6d852515c..deb8c3d77 100644 --- a/internal/msggateway/hub_server.go +++ b/internal/msggateway/hub_server.go @@ -16,8 +16,9 @@ package msggateway import ( "context" - "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache" + "github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify" + "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" "google.golang.org/grpc" @@ -82,6 +83,9 @@ func (s *Server) GetUsersOnlineStatus( ctx context.Context, req *msggateway.GetUsersOnlineStatusReq, ) (*msggateway.GetUsersOnlineStatusResp, error) { + if !tokenverify.IsAppManagerUid(ctx) { + return nil, errs.ErrNoPermission.Wrap("only app manager") + } var resp msggateway.GetUsersOnlineStatusResp for _, userID := range req.UserIDs { clients, ok := s.LongConnServer.GetUserAllCons(userID) From 7313ffb321888b537fafee897fd39c33899fafd1 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Thu, 20 Jul 2023 18:21:22 +0800 Subject: [PATCH 06/62] fix bug: obtain user online status err(#567) --- internal/api/user.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/api/user.go b/internal/api/user.go index 1e75b8fb4..0cfe63a2f 100644 --- a/internal/api/user.go +++ b/internal/api/user.go @@ -88,6 +88,7 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) { parseError := apiresp.ParseError(err) if parseError.ErrCode == errs.NoPermissionError { apiresp.GinError(c, err) + return } } else { wsResult = append(wsResult, reply.SuccessResult...) From 24549defa3e4ec022c5e7555675b672faf5a350b Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Fri, 21 Jul 2023 09:49:14 +0800 Subject: [PATCH 07/62] fix bug: obtain user online status err(#567) --- internal/api/user.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/internal/api/user.go b/internal/api/user.go index 0cfe63a2f..a48bf1498 100644 --- a/internal/api/user.go +++ b/internal/api/user.go @@ -84,12 +84,7 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) { reply, err := msgClient.GetUsersOnlineStatus(c, &req) if err != nil { log.ZWarn(c, "GetUsersOnlineStatus rpc err", err) - // apiresp.GinError(c, err) - parseError := apiresp.ParseError(err) - if parseError.ErrCode == errs.NoPermissionError { - apiresp.GinError(c, err) - return - } + apiresp.GinError(c, err) } else { wsResult = append(wsResult, reply.SuccessResult...) } From 36802ab2765f206240715719f8da7111c41cfdd6 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Fri, 21 Jul 2023 10:44:28 +0800 Subject: [PATCH 08/62] fix bug: obtain user online status err(#567) --- internal/api/user.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/internal/api/user.go b/internal/api/user.go index a48bf1498..5febe4668 100644 --- a/internal/api/user.go +++ b/internal/api/user.go @@ -84,7 +84,13 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) { reply, err := msgClient.GetUsersOnlineStatus(c, &req) if err != nil { log.ZWarn(c, "GetUsersOnlineStatus rpc err", err) - apiresp.GinError(c, err) + + parseError := apiresp.ParseError(err) + log.ZInfo(c, "errcode bantanger", parseError.ErrCode) + if parseError.ErrCode == errs.NoPermissionError { + apiresp.GinError(c, err) + return + } } else { wsResult = append(wsResult, reply.SuccessResult...) } From a4736e66c39d3f4453c676f097f32e426e438288 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Fri, 21 Jul 2023 11:17:16 +0800 Subject: [PATCH 09/62] fix bug: obtain user online status err(#567) --- internal/api/user.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/api/user.go b/internal/api/user.go index 5febe4668..3e338ac83 100644 --- a/internal/api/user.go +++ b/internal/api/user.go @@ -86,7 +86,7 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) { log.ZWarn(c, "GetUsersOnlineStatus rpc err", err) parseError := apiresp.ParseError(err) - log.ZInfo(c, "errcode bantanger", parseError.ErrCode) + log.ZDebug(c, "errcode bantanger", parseError.ErrCode) if parseError.ErrCode == errs.NoPermissionError { apiresp.GinError(c, err) return From ced120ea575a03fb0ddda15e71583fe778976cf2 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Fri, 21 Jul 2023 11:34:38 +0800 Subject: [PATCH 10/62] fix bug: obtain user online status err(#567) --- internal/api/user.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/api/user.go b/internal/api/user.go index 3e338ac83..67c042ea4 100644 --- a/internal/api/user.go +++ b/internal/api/user.go @@ -86,7 +86,7 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) { log.ZWarn(c, "GetUsersOnlineStatus rpc err", err) parseError := apiresp.ParseError(err) - log.ZDebug(c, "errcode bantanger", parseError.ErrCode) + log.ZDebug(c, "errcode bantanger", "errcode", parseError.ErrCode) if parseError.ErrCode == errs.NoPermissionError { apiresp.GinError(c, err) return From 6a05b859cc4f2d134d2e7c38c5aa7fa3b35d7fd4 Mon Sep 17 00:00:00 2001 From: pluto <83957921+plutoyty@users.noreply.github.com> Date: Fri, 14 Jul 2023 18:59:28 +0800 Subject: [PATCH 11/62] fix bug #545 (#555) Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- go.mod | 4 +--- internal/push/offlinepush/offlinepush_interface.go | 3 +++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 8a7fd7153..21e6e2241 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.18 require ( firebase.google.com/go v3.13.0+incompatible github.com/OpenIMSDK/open_utils v1.0.8 - github.com/Shopify/sarama v1.32.0 + github.com/Shopify/sarama v1.29.0 github.com/bwmarrin/snowflake v0.3.0 github.com/dtm-labs/rockscache v0.1.1 github.com/gin-gonic/gin v1.9.1 @@ -141,5 +141,3 @@ require ( google.golang.org/genproto v0.0.0-20230525234025-438c736192d0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect ) - -replace github.com/Shopify/sarama => github.com/Shopify/sarama v1.29.0 diff --git a/internal/push/offlinepush/offlinepush_interface.go b/internal/push/offlinepush/offlinepush_interface.go index 44dfce2b8..5aa7e089f 100644 --- a/internal/push/offlinepush/offlinepush_interface.go +++ b/internal/push/offlinepush/offlinepush_interface.go @@ -18,10 +18,12 @@ import ( "context" ) +// OfflinePusher Offline Pusher type OfflinePusher interface { Push(ctx context.Context, userIDs []string, title, content string, opts *Opts) error } +// Opts opts type Opts struct { Signal *Signal IOSPushSound string @@ -29,6 +31,7 @@ type Opts struct { Ex string } +// Signal message id type Signal struct { ClientMsgID string } From 1849053a6c00084e7d467c48df6fb4734b06c82d Mon Sep 17 00:00:00 2001 From: Alan <68671759+hanzhixiao@users.noreply.github.com> Date: Fri, 14 Jul 2023 19:14:18 +0800 Subject: [PATCH 12/62] message for your changes (#565) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’> Co-authored-by: ‘hanzhixiao’ <‘709674996@qq.com’> Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- build.cmd | 1 + internal/rpc/msg/server.go | 3 --- pkg/common/db/controller/msg.go | 6 ------ 3 files changed, 1 insertion(+), 9 deletions(-) create mode 100644 build.cmd diff --git a/build.cmd b/build.cmd new file mode 100644 index 000000000..4c53576c0 --- /dev/null +++ b/build.cmd @@ -0,0 +1 @@ +go build -o \ No newline at end of file diff --git a/internal/rpc/msg/server.go b/internal/rpc/msg/server.go index 1a152b7be..5e2cf925f 100644 --- a/internal/rpc/msg/server.go +++ b/internal/rpc/msg/server.go @@ -17,9 +17,6 @@ package msg import ( "context" - - "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/relation" - "google.golang.org/grpc" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" diff --git a/pkg/common/db/controller/msg.go b/pkg/common/db/controller/msg.go index fe72396ce..fdda23ac9 100644 --- a/pkg/common/db/controller/msg.go +++ b/pkg/common/db/controller/msg.go @@ -15,16 +15,10 @@ package controller import ( - "context" "errors" "time" - "gorm.io/gorm" - - relation2 "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/relation" - "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/relation" - "github.com/redis/go-redis/v9" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/config" From c1ccd9046f16272c716bcd442eed4fb427483d51 Mon Sep 17 00:00:00 2001 From: Alan <68671759+hanzhixiao@users.noreply.github.com> Date: Fri, 14 Jul 2023 20:40:41 +0800 Subject: [PATCH 13/62] debug (#566) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * message for your changes Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’> * debug Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’> * Delete start.bat * Delete build.cmd --------- Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’> Co-authored-by: ‘hanzhixiao’ <‘709674996@qq.com’> Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- build.cmd | 1 - internal/rpc/msg/sync_msg.go | 7 +++---- pkg/common/db/controller/msg.go | 10 +++++----- pkg/common/db/table/unrelation/msg.go | 2 +- pkg/common/db/unrelation/msg.go | 22 +++++++++++----------- 5 files changed, 20 insertions(+), 22 deletions(-) delete mode 100644 build.cmd diff --git a/build.cmd b/build.cmd deleted file mode 100644 index 4c53576c0..000000000 --- a/build.cmd +++ /dev/null @@ -1 +0,0 @@ -go build -o \ No newline at end of file diff --git a/internal/rpc/msg/sync_msg.go b/internal/rpc/msg/sync_msg.go index 8cfac93bd..70967a1ba 100644 --- a/internal/rpc/msg/sync_msg.go +++ b/internal/rpc/msg/sync_msg.go @@ -108,11 +108,11 @@ func (m *msgServer) GetMaxSeq(ctx context.Context, req *sdkws.GetMaxSeqReq) (*sd func (m *msgServer) SearchMessage(ctx context.Context, req *msg.SearchMessageReq) (resp *msg.SearchMessageResp, err error) { var chatLogs []*sdkws.MsgData + var total int32 resp = &msg.SearchMessageResp{} - if chatLogs, err = m.MsgDatabase.SearchMessage(ctx, req); err != nil { + if total, chatLogs, err = m.MsgDatabase.SearchMessage(ctx, req); err != nil { return nil, err } - var num int for _, chatLog := range chatLogs { pbChatLog := &msg.ChatLog{} utils.CopyStructFields(pbChatLog, chatLog) @@ -146,9 +146,8 @@ func (m *msgServer) SearchMessage(ctx context.Context, req *msg.SearchMessageReq pbChatLog.GroupType = group.GroupType } resp.ChatLogs = append(resp.ChatLogs, pbChatLog) - num++ } - resp.ChatLogsNum = int32(num) + resp.ChatLogsNum = total return resp, nil } diff --git a/pkg/common/db/controller/msg.go b/pkg/common/db/controller/msg.go index fdda23ac9..37a71bafa 100644 --- a/pkg/common/db/controller/msg.go +++ b/pkg/common/db/controller/msg.go @@ -92,7 +92,7 @@ type CommonMsgDatabase interface { GetConversationMinMaxSeqInMongoAndCache(ctx context.Context, conversationID string) (minSeqMongo, maxSeqMongo, minSeqCache, maxSeqCache int64, err error) SetSendMsgStatus(ctx context.Context, id string, status int32) error GetSendMsgStatus(ctx context.Context, id string) (int32, error) - SearchMessage(ctx context.Context, req *pbMsg.SearchMessageReq) (msgData []*sdkws.MsgData, err error) + SearchMessage(ctx context.Context, req *pbMsg.SearchMessageReq) (total int32, msgData []*sdkws.MsgData, err error) // to mq MsgToMQ(ctx context.Context, key string, msg2mq *sdkws.MsgData) error @@ -940,14 +940,14 @@ func (db *commonMsgDatabase) RangeGroupSendCount( return db.msgDocDatabase.RangeGroupSendCount(ctx, start, end, ase, pageNumber, showNumber) } -func (db *commonMsgDatabase) SearchMessage(ctx context.Context, req *pbMsg.SearchMessageReq) (msgData []*sdkws.MsgData, err error) { +func (db *commonMsgDatabase) SearchMessage(ctx context.Context, req *pbMsg.SearchMessageReq) (total int32, msgData []*sdkws.MsgData, err error) { var totalMsgs []*sdkws.MsgData - msgs, err := db.msgDocDatabase.SearchMessage(ctx, req) + total, msgs, err := db.msgDocDatabase.SearchMessage(ctx, req) if err != nil { - return nil, err + return 0, nil, err } for _, msg := range msgs { totalMsgs = append(totalMsgs, convert.MsgDB2Pb(msg.Msg)) } - return totalMsgs, nil + return total, totalMsgs, nil } diff --git a/pkg/common/db/table/unrelation/msg.go b/pkg/common/db/table/unrelation/msg.go index ac4602d35..dc16613ed 100644 --- a/pkg/common/db/table/unrelation/msg.go +++ b/pkg/common/db/table/unrelation/msg.go @@ -110,7 +110,7 @@ type MsgDocModelInterface interface { GetMsgDocModelByIndex(ctx context.Context, conversationID string, index, sort int64) (*MsgDocModel, error) DeleteMsgsInOneDocByIndex(ctx context.Context, docID string, indexes []int) error MarkSingleChatMsgsAsRead(ctx context.Context, userID string, docID string, indexes []int64) error - SearchMessage(ctx context.Context, req *msg.SearchMessageReq) ([]*MsgInfoModel, error) + SearchMessage(ctx context.Context, req *msg.SearchMessageReq) (int32, []*MsgInfoModel, error) RangeUserSendCount( ctx context.Context, start time.Time, diff --git a/pkg/common/db/unrelation/msg.go b/pkg/common/db/unrelation/msg.go index 222b70190..b7403ebde 100644 --- a/pkg/common/db/unrelation/msg.go +++ b/pkg/common/db/unrelation/msg.go @@ -1067,20 +1067,20 @@ func (m *MsgMongoDriver) RangeGroupSendCount( return result[0].MsgCount, result[0].UserCount, groups, dateCount, nil } -func (m *MsgMongoDriver) SearchMessage(ctx context.Context, req *msg.SearchMessageReq) ([]*table.MsgInfoModel, error) { - msgs, err := m.searchMessage(ctx, req) +func (m *MsgMongoDriver) SearchMessage(ctx context.Context, req *msg.SearchMessageReq) (int32, []*table.MsgInfoModel, error) { + total, msgs, err := m.searchMessage(ctx, req) if err != nil { - return nil, err + return 0, nil, err } for _, msg1 := range msgs { if msg1.IsRead { msg1.Msg.IsRead = true } } - return msgs, nil + return total, msgs, nil } -func (m *MsgMongoDriver) searchMessage(ctx context.Context, req *msg.SearchMessageReq) ([]*table.MsgInfoModel, error) { +func (m *MsgMongoDriver) searchMessage(ctx context.Context, req *msg.SearchMessageReq) (int32, []*table.MsgInfoModel, error) { var pipe mongo.Pipeline condition := bson.A{} if req.SendTime != "" { @@ -1153,16 +1153,16 @@ func (m *MsgMongoDriver) searchMessage(ctx context.Context, req *msg.SearchMessa } cursor, err := m.MsgCollection.Aggregate(ctx, pipe) if err != nil { - return nil, err + return 0, nil, err } var msgsDocs []table.MsgDocModel err = cursor.All(ctx, &msgsDocs) if err != nil { - return nil, err + return 0, nil, err } if len(msgsDocs) == 0 { - return nil, errs.Wrap(mongo.ErrNoDocuments) + return 0, nil, errs.Wrap(mongo.ErrNoDocuments) } msgs := make([]*table.MsgInfoModel, 0) for index := range msgsDocs { @@ -1187,14 +1187,14 @@ func (m *MsgMongoDriver) searchMessage(ctx context.Context, req *msg.SearchMessa } data, err := json.Marshal(&revokeContent) if err != nil { - return nil, err + return 0, nil, err } elem := sdkws.NotificationElem{ Detail: string(data), } content, err := json.Marshal(&elem) if err != nil { - return nil, err + return 0, nil, err } msg.Msg.ContentType = constant.MsgRevokeNotification msg.Msg.Content = string(content) @@ -1209,5 +1209,5 @@ func (m *MsgMongoDriver) searchMessage(ctx context.Context, req *msg.SearchMessa } else { msgs = msgs[start:] } - return msgs, nil + return n, msgs, nil } From 63c6838585288b222295cc133cd323f627a11085 Mon Sep 17 00:00:00 2001 From: WangchuXiao Date: Fri, 14 Jul 2023 20:46:25 +0800 Subject: [PATCH 14/62] fix bug: multiple gateway kick user (#568) * new feature: add batch send msg * new feature: add batch send msg * new feature: add batch send msg * new feature: add batch send msg * new feature: add batch send msg * new feature: add batch send msg * fix bug: multiple gateway kick user * fix bug: multiple gateway kick user * fix bug: multiple gateway kick user * fix bug: multiple gateway kick user * fix bug: multiple gateway kick user Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- internal/api/msg.go | 3 ++ internal/msggateway/hub_server.go | 7 ++-- internal/msggateway/n_ws_server.go | 58 +++++++++++++++--------------- internal/rpc/auth/auth.go | 8 ++++- internal/tools/cron_task.go | 10 +++--- pkg/proto/msg/msg.go | 10 ++++++ 6 files changed, 56 insertions(+), 40 deletions(-) diff --git a/internal/api/msg.go b/internal/api/msg.go index d8a3c292b..8ad7943e9 100644 --- a/internal/api/msg.go +++ b/internal/api/msg.go @@ -214,6 +214,7 @@ func (m *MessageApi) SendMessage(c *gin.Context) { if err != nil { log.ZError(c, "decodeData failed", err) apiresp.GinError(c, err) + return } sendMsgReq.MsgData.RecvID = req.RecvID var status int @@ -260,6 +261,7 @@ func (m *MessageApi) BatchSendMsg(c *gin.Context) { if err != nil { log.ZError(c, "GetAllUserIDs failed", err) apiresp.GinError(c, err) + return } if len(recvIDsPart) < showNumber { recvIDs = append(recvIDs, recvIDsPart...) @@ -275,6 +277,7 @@ func (m *MessageApi) BatchSendMsg(c *gin.Context) { if err != nil { log.ZError(c, "decodeData failed", err) apiresp.GinError(c, err) + return } for _, recvID := range recvIDs { sendMsgReq.MsgData.RecvID = recvID diff --git a/internal/msggateway/hub_server.go b/internal/msggateway/hub_server.go index 81aade1cb..746780c03 100644 --- a/internal/msggateway/hub_server.go +++ b/internal/msggateway/hub_server.go @@ -181,13 +181,12 @@ func (s *Server) KickUserOffline( if clients, _, ok := s.LongConnServer.GetUserPlatformCons(v, int(req.PlatformID)); ok { for _, client := range clients { log.ZDebug(ctx, "kick user offline", "userID", v, "platformID", req.PlatformID, "client", client) - err := client.KickOnlineMessage() - if err != nil { - return nil, err + if err := client.longConnServer.KickUserConn(client); err != nil { + log.ZWarn(ctx, "kick user offline failed", err, "userID", v, "platformID", req.PlatformID) } } } else { - log.ZWarn(ctx, "conn not exist", nil, "userID", v, "platformID", req.PlatformID) + log.ZInfo(ctx, "conn not exist", "userID", v, "platformID", req.PlatformID) } } return &msggateway.KickUserOfflineResp{}, nil diff --git a/internal/msggateway/n_ws_server.go b/internal/msggateway/n_ws_server.go index 2988e2c08..c2b46cf1f 100644 --- a/internal/msggateway/n_ws_server.go +++ b/internal/msggateway/n_ws_server.go @@ -47,6 +47,7 @@ type LongConnServer interface { Validate(s interface{}) error SetCacheHandler(cache cache.MsgModel) SetDiscoveryRegistry(client discoveryregistry.SvcDiscoveryRegistry) + KickUserConn(client *Client) error UnRegister(c *Client) Compressor Encoder @@ -145,7 +146,7 @@ func (ws *WsServer) Run() error { case client = <-ws.unregisterChan: ws.unregisterClient(client) case onlineInfo := <-ws.kickHandlerChan: - ws.multiTerminalLoginChecker(onlineInfo) + ws.multiTerminalLoginChecker(onlineInfo.clientOK, onlineInfo.oldClients, onlineInfo.newClient) } } }() @@ -207,80 +208,77 @@ func getRemoteAdders(client []*Client) string { return ret } -func (ws *WsServer) multiTerminalLoginChecker(info *kickHandler) { +func (ws *WsServer) KickUserConn(client *Client) error { + ws.clients.deleteClients(client.UserID, []*Client{client}) + return client.KickOnlineMessage() +} + +func (ws *WsServer) multiTerminalLoginChecker(clientOK bool, oldClients []*Client, newClient *Client) { switch config.Config.MultiLoginPolicy { case constant.DefalutNotKick: case constant.PCAndOther: - if constant.PlatformIDToClass(info.newClient.PlatformID) == constant.TerminalPC { + if constant.PlatformIDToClass(newClient.PlatformID) == constant.TerminalPC { return } fallthrough case constant.AllLoginButSameTermKick: - if info.clientOK { - ws.clients.deleteClients(info.newClient.UserID, info.oldClients) - for _, c := range info.oldClients { + if clientOK { + ws.clients.deleteClients(newClient.UserID, oldClients) + for _, c := range oldClients { err := c.KickOnlineMessage() if err != nil { log.ZWarn(c.ctx, "KickOnlineMessage", err) } } m, err := ws.cache.GetTokensWithoutError( - info.newClient.ctx, - info.newClient.UserID, - info.newClient.PlatformID, + newClient.ctx, + newClient.UserID, + newClient.PlatformID, ) if err != nil && err != redis.Nil { log.ZWarn( - info.newClient.ctx, + newClient.ctx, "get token from redis err", err, "userID", - info.newClient.UserID, + newClient.UserID, "platformID", - info.newClient.PlatformID, + newClient.PlatformID, ) return } if m == nil { log.ZWarn( - info.newClient.ctx, + newClient.ctx, "m is nil", errors.New("m is nil"), "userID", - info.newClient.UserID, + newClient.UserID, "platformID", - info.newClient.PlatformID, + newClient.PlatformID, ) return } log.ZDebug( - info.newClient.ctx, + newClient.ctx, "get token from redis", "userID", - info.newClient.UserID, + newClient.UserID, "platformID", - info.newClient.PlatformID, + newClient.PlatformID, "tokenMap", m, ) for k := range m { - if k != info.newClient.ctx.GetToken() { + if k != newClient.ctx.GetToken() { m[k] = constant.KickedToken } } - log.ZDebug(info.newClient.ctx, "set token map is ", "token map", m, "userID", info.newClient.UserID) - err = ws.cache.SetTokenMapByUidPid(info.newClient.ctx, info.newClient.UserID, info.newClient.PlatformID, m) + log.ZDebug(newClient.ctx, "set token map is ", "token map", m, "userID", newClient.UserID) + err = ws.cache.SetTokenMapByUidPid(newClient.ctx, newClient.UserID, newClient.PlatformID, m) if err != nil { - log.ZWarn( - info.newClient.ctx, - "SetTokenMapByUidPid err", - err, - "userID", - info.newClient.UserID, - "platformID", - info.newClient.PlatformID, - ) + log.ZWarn(newClient.ctx, "SetTokenMapByUidPid err", err, "userID", newClient.UserID, "platformID", newClient.PlatformID) return } } diff --git a/internal/rpc/auth/auth.go b/internal/rpc/auth/auth.go index 48e21fbce..317754743 100644 --- a/internal/rpc/auth/auth.go +++ b/internal/rpc/auth/auth.go @@ -23,6 +23,7 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller" + "github.com/OpenIMSDK/Open-IM-Server/pkg/common/log" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify" "github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry" @@ -129,11 +130,16 @@ func (s *authServer) forceKickOff(ctx context.Context, userID string, platformID if err != nil { return err } + for _, v := range conns { + log.ZDebug(ctx, "forceKickOff", "conn", v.(*grpc.ClientConn).Target()) + } for _, v := range conns { client := msggateway.NewMsgGatewayClient(v) kickReq := &msggateway.KickUserOfflineReq{KickUserIDList: []string{userID}, PlatformID: platformID} _, err := client.KickUserOffline(ctx, kickReq) - return utils.Wrap(err, "") + if err != nil { + log.ZError(ctx, "forceKickOff", err, "kickReq", kickReq) + } } return nil } diff --git a/internal/tools/cron_task.go b/internal/tools/cron_task.go index 5e4183615..82343157b 100644 --- a/internal/tools/cron_task.go +++ b/internal/tools/cron_task.go @@ -41,11 +41,11 @@ func StartCronTask() error { panic(err) } log.ZInfo(context.Background(), "start msgDestruct cron task", "cron config", config.Config.MsgDestructTime) - _, err = c.AddFunc(config.Config.MsgDestructTime, msgTool.ConversationsDestructMsgs) - if err != nil { - fmt.Println("start conversationsDestructMsgs cron failed", err.Error(), config.Config.ChatRecordsClearTime) - panic(err) - } + // _, err = c.AddFunc(config.Config.MsgDestructTime, msgTool.ConversationsDestructMsgs) + // if err != nil { + // fmt.Println("start conversationsDestructMsgs cron failed", err.Error(), config.Config.ChatRecordsClearTime) + // panic(err) + // } c.Start() wg.Wait() return nil diff --git a/pkg/proto/msg/msg.go b/pkg/proto/msg/msg.go index 62b776856..03c9da915 100644 --- a/pkg/proto/msg/msg.go +++ b/pkg/proto/msg/msg.go @@ -126,6 +126,11 @@ func (x *MarkMsgsAsReadReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + for _, seq := range x.Seqs { + if seq == 0 { + return errs.ErrArgs.Wrap("seqs has 0 value is invalid") + } + } return nil } @@ -139,6 +144,11 @@ func (x *MarkConversationAsReadReq) Check() error { if x.HasReadSeq < 1 { return errs.ErrArgs.Wrap("hasReadSeq is invalid") } + for _, seq := range x.Seqs { + if seq == 0 { + return errs.ErrArgs.Wrap("seqs has 0 value is invalid") + } + } return nil } From 41cef76b350d5b02bf49141dcd040cdd0a2cbe74 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Fri, 14 Jul 2023 20:54:24 +0800 Subject: [PATCH 15/62] fix: implement of GetUsersOnlineStatus (#567) (#569) Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- internal/api/user.go | 2 +- internal/msggateway/hub_server.go | 5 ----- pkg/common/db/cache/conversation.go | 6 +++--- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/internal/api/user.go b/internal/api/user.go index 28cb74509..baea8fed3 100644 --- a/internal/api/user.go +++ b/internal/api/user.go @@ -83,7 +83,7 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) { msgClient := msggateway.NewMsgGatewayClient(v) reply, err := msgClient.GetUsersOnlineStatus(c, &req) if err != nil { - log.ZWarn(c, "GetUsersOnlineStatus rpc err", err) + log.ZWarn(c, "GetUsersOnlineStatus rpc err", err) continue } else { wsResult = append(wsResult, reply.SuccessResult...) diff --git a/internal/msggateway/hub_server.go b/internal/msggateway/hub_server.go index 746780c03..6d852515c 100644 --- a/internal/msggateway/hub_server.go +++ b/internal/msggateway/hub_server.go @@ -25,9 +25,7 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/log" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/prome" - "github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify" "github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry" - "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msggateway" "github.com/OpenIMSDK/Open-IM-Server/pkg/startrpc" "github.com/OpenIMSDK/Open-IM-Server/pkg/utils" @@ -84,9 +82,6 @@ func (s *Server) GetUsersOnlineStatus( ctx context.Context, req *msggateway.GetUsersOnlineStatusReq, ) (*msggateway.GetUsersOnlineStatusResp, error) { - if !tokenverify.IsAppManagerUid(ctx) { - return nil, errs.ErrNoPermission.Wrap("only app manager") - } var resp msggateway.GetUsersOnlineStatusResp for _, userID := range req.UserIDs { clients, ok := s.LongConnServer.GetUserAllCons(userID) diff --git a/pkg/common/db/cache/conversation.go b/pkg/common/db/cache/conversation.go index d3a9d44aa..119967c70 100644 --- a/pkg/common/db/cache/conversation.go +++ b/pkg/common/db/cache/conversation.go @@ -54,7 +54,7 @@ type ConversationCache interface { // get one conversation from msgCache GetConversation(ctx context.Context, ownerUserID, conversationID string) (*relationTb.ConversationModel, error) - DelConvsersations(ownerUserID string, conversationIDs ...string) ConversationCache + DelConversations(ownerUserID string, conversationIDs ...string) ConversationCache DelUsersConversation(conversationID string, ownerUserIDs ...string) ConversationCache // get one conversation from msgCache GetConversations( @@ -225,9 +225,9 @@ func (c *ConversationRedisCache) GetConversation( ) } -func (c *ConversationRedisCache) DelConvsersations(ownerUserID string, convsersationIDs ...string) ConversationCache { +func (c *ConversationRedisCache) DelConversations(ownerUserID string, conversationIDs ...string) ConversationCache { var keys []string - for _, conversationID := range convsersationIDs { + for _, conversationID := range conversationIDs { keys = append(keys, c.getConversationKey(ownerUserID, conversationID)) } cache := c.NewCache() From 23526cd89c94ee38a38b9ba4081b99f9270ea231 Mon Sep 17 00:00:00 2001 From: skiffer-git <44203734@qq.com> Date: Fri, 14 Jul 2023 21:07:30 +0800 Subject: [PATCH 16/62] fix bug: DelConvsersations->DelConversations Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- pkg/common/db/controller/conversation.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/common/db/controller/conversation.go b/pkg/common/db/controller/conversation.go index 3cb4d1055..d65315918 100644 --- a/pkg/common/db/controller/conversation.go +++ b/pkg/common/db/controller/conversation.go @@ -104,7 +104,7 @@ func (c *conversationDatabase) SetUsersConversationFiledTx(ctx context.Context, if err != nil { return err } - cache = cache.DelConversationIDs(NotUserIDs...).DelUserConversationIDsHash(NotUserIDs...).DelConvsersations(conversation.ConversationID, NotUserIDs...) + cache = cache.DelConversationIDs(NotUserIDs...).DelUserConversationIDsHash(NotUserIDs...).DelConversations(conversation.ConversationID, NotUserIDs...) } return nil }); err != nil { @@ -128,7 +128,7 @@ func (c *conversationDatabase) CreateConversation(ctx context.Context, conversat var userIDs []string cache := c.cache.NewCache() for _, conversation := range conversations { - cache = cache.DelConvsersations(conversation.OwnerUserID, conversation.ConversationID) + cache = cache.DelConversations(conversation.OwnerUserID, conversation.ConversationID) userIDs = append(userIDs, conversation.OwnerUserID) } return cache.DelConversationIDs(userIDs...).DelUserConversationIDsHash(userIDs...).ExecDel(ctx) @@ -190,7 +190,7 @@ func (c *conversationDatabase) SetUserConversations(ctx context.Context, ownerUs var conversationIDs []string for _, conversation := range conversations { conversationIDs = append(conversationIDs, conversation.ConversationID) - cache = cache.DelConvsersations(conversation.OwnerUserID, conversation.ConversationID) + cache = cache.DelConversations(conversation.OwnerUserID, conversation.ConversationID) } conversationTx := c.conversationDB.NewTx(tx) existConversations, err := conversationTx.Find(ctx, ownerUserID, conversationIDs) @@ -247,7 +247,7 @@ func (c *conversationDatabase) CreateGroupChatConversation(ctx context.Context, for _, v := range notExistUserIDs { conversation := relationTb.ConversationModel{ConversationType: constant.SuperGroupChatType, GroupID: groupID, OwnerUserID: v, ConversationID: conversationID} conversations = append(conversations, &conversation) - cache = cache.DelConvsersations(v, conversationID) + cache = cache.DelConversations(v, conversationID) } cache = cache.DelConversationIDs(notExistUserIDs...).DelUserConversationIDsHash(notExistUserIDs...) if len(conversations) > 0 { @@ -261,7 +261,7 @@ func (c *conversationDatabase) CreateGroupChatConversation(ctx context.Context, return err } for _, v := range existConversationUserIDs { - cache = cache.DelConvsersations(v, conversationID) + cache = cache.DelConversations(v, conversationID) } return nil }); err != nil { From 5ea342f564000a01aed5636014165e01870623e6 Mon Sep 17 00:00:00 2001 From: kubbot <3293172751ysy@gmail.com> Date: Fri, 14 Jul 2023 21:14:22 +0800 Subject: [PATCH 17/62] release: v3.0 release Signed-off-by: kubbot <3293172751ysy@gmail.com> Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- docker-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 0b32d2d50..c78e4a63b 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -100,7 +100,7 @@ services: openim_server: - image: ghcr.io/openimsdk/openim-server:v3.0.1 + image: ghcr.io/openimsdk/openim-server:v3.0.0 container_name: openim-server volumes: - ./logs:/Open-IM-Server/logs From 25030a19baa2f25c2aa96bdc806d605ef9787bb2 Mon Sep 17 00:00:00 2001 From: kubbot <3293172751ysy@gmail.com> Date: Fri, 14 Jul 2023 21:39:30 +0800 Subject: [PATCH 18/62] fix: script v3.0 Signed-off-by: kubbot <3293172751ysy@gmail.com> Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- init_docker.sh | 7 ++++++- install_guide.sh | 0 install_im_compose.sh | 0 install_im_server.sh | 0 4 files changed, 6 insertions(+), 1 deletion(-) mode change 100644 => 100755 init_docker.sh mode change 100644 => 100755 install_guide.sh mode change 100644 => 100755 install_im_compose.sh mode change 100644 => 100755 install_im_server.sh diff --git a/init_docker.sh b/init_docker.sh old mode 100644 new mode 100755 index 09213bf50..9815fe871 --- a/init_docker.sh +++ b/init_docker.sh @@ -21,7 +21,12 @@ if ! command -v docker >/dev/null 2>&1; then fi # Start Docker services using docker-compose -docker-compose up -d +if command -v docker-compose &> /dev/null +then + docker-compose up -d +else + docker compose up -d +fi # Move back to the 'scripts' folder cd scripts diff --git a/install_guide.sh b/install_guide.sh old mode 100644 new mode 100755 diff --git a/install_im_compose.sh b/install_im_compose.sh old mode 100644 new mode 100755 diff --git a/install_im_server.sh b/install_im_server.sh old mode 100644 new mode 100755 From ad39d3bf69499968ae2a59dac1e0157b2a551a9b Mon Sep 17 00:00:00 2001 From: kubbot <3293172751ysy@gmail.com> Date: Fri, 14 Jul 2023 21:54:23 +0800 Subject: [PATCH 19/62] build: fix chat docker images Signed-off-by: kubbot <3293172751ysy@gmail.com> Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- docker-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index c78e4a63b..1f7d09f82 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -123,7 +123,7 @@ services: max-file: "2" openim_chat: - image: openim/openim_chat:v1.1.0 + image: ghcr.io/openimsdk/openim-chat:v1.0.0 container_name: openim_chat restart: always depends_on: From dcc270fb4d6f5e6f4844f9f8c0c74f4100dbb210 Mon Sep 17 00:00:00 2001 From: kubbot <3293172751ysy@gmail.com> Date: Fri, 14 Jul 2023 22:10:01 +0800 Subject: [PATCH 20/62] fix: release 3.0 Signed-off-by: kubbot <3293172751ysy@gmail.com> Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- docker-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 1f7d09f82..23565c23a 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -100,7 +100,7 @@ services: openim_server: - image: ghcr.io/openimsdk/openim-server:v3.0.0 + image: ghcr.io/openimsdk/openim-server:v3.0 container_name: openim-server volumes: - ./logs:/Open-IM-Server/logs From f25f7e0ef8843f24496514177fa2659e16af7bfe Mon Sep 17 00:00:00 2001 From: skiffer-git <72860476+skiffer-git@users.noreply.github.com> Date: Sat, 15 Jul 2023 11:58:35 +0800 Subject: [PATCH 21/62] Replace WeChat image links with COS (Cloud Object Storage) Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b180f4438..dcf7230c1 100644 --- a/README.md +++ b/README.md @@ -182,7 +182,7 @@ We take notes of each [biweekly meeting](https://github.com/OpenIMSDK/Open-IM-Se ## Who are using Open-IM-Server The [user case studies](https://github.com/OpenIMSDK/community/blob/main/ADOPTERS.md) page includes the user list of the project. You can leave a [📝comment](https://github.com/OpenIMSDK/Open-IM-Server/issues/379) to let us know your use case. -![avatar](https://github.com/OpenIMSDK/OpenIM-Docs/blob/main/docs/images/WechatIMG20.jpeg) +![avatar](https://openim-1253691595.cos.ap-nanjing.myqcloud.com/WechatIMG20.jpeg) ## License From df16bda12fc101e82b7bf0bc0e707513effb7c68 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Mon, 17 Jul 2023 16:32:28 +0800 Subject: [PATCH 22/62] fix bug: obtain user online status err(#567) Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- internal/api/user.go | 6 +++++- internal/msggateway/hub_server.go | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/internal/api/user.go b/internal/api/user.go index baea8fed3..1e75b8fb4 100644 --- a/internal/api/user.go +++ b/internal/api/user.go @@ -84,7 +84,11 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) { reply, err := msgClient.GetUsersOnlineStatus(c, &req) if err != nil { log.ZWarn(c, "GetUsersOnlineStatus rpc err", err) - continue + // apiresp.GinError(c, err) + parseError := apiresp.ParseError(err) + if parseError.ErrCode == errs.NoPermissionError { + apiresp.GinError(c, err) + } } else { wsResult = append(wsResult, reply.SuccessResult...) } diff --git a/internal/msggateway/hub_server.go b/internal/msggateway/hub_server.go index 6d852515c..deb8c3d77 100644 --- a/internal/msggateway/hub_server.go +++ b/internal/msggateway/hub_server.go @@ -16,8 +16,9 @@ package msggateway import ( "context" - "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache" + "github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify" + "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" "google.golang.org/grpc" @@ -82,6 +83,9 @@ func (s *Server) GetUsersOnlineStatus( ctx context.Context, req *msggateway.GetUsersOnlineStatusReq, ) (*msggateway.GetUsersOnlineStatusResp, error) { + if !tokenverify.IsAppManagerUid(ctx) { + return nil, errs.ErrNoPermission.Wrap("only app manager") + } var resp msggateway.GetUsersOnlineStatusResp for _, userID := range req.UserIDs { clients, ok := s.LongConnServer.GetUserAllCons(userID) From 2631591417b22661651cdfd09dad5dbe8e8b60ef Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Fri, 14 Jul 2023 20:07:26 +0800 Subject: [PATCH 23/62] fix: implement of GetUsersOnlineStatus (#567) --- internal/msggateway/hub_server.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/internal/msggateway/hub_server.go b/internal/msggateway/hub_server.go index deb8c3d77..4922437cb 100644 --- a/internal/msggateway/hub_server.go +++ b/internal/msggateway/hub_server.go @@ -83,9 +83,6 @@ func (s *Server) GetUsersOnlineStatus( ctx context.Context, req *msggateway.GetUsersOnlineStatusReq, ) (*msggateway.GetUsersOnlineStatusResp, error) { - if !tokenverify.IsAppManagerUid(ctx) { - return nil, errs.ErrNoPermission.Wrap("only app manager") - } var resp msggateway.GetUsersOnlineStatusResp for _, userID := range req.UserIDs { clients, ok := s.LongConnServer.GetUserAllCons(userID) From 0f92a1e40a5baa10db3dac3fc752966abcb52eb0 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Mon, 17 Jul 2023 16:29:01 +0800 Subject: [PATCH 24/62] fix bug: obtain user online status err(#567) Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- internal/msggateway/hub_server.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/msggateway/hub_server.go b/internal/msggateway/hub_server.go index 4922437cb..deb8c3d77 100644 --- a/internal/msggateway/hub_server.go +++ b/internal/msggateway/hub_server.go @@ -83,6 +83,9 @@ func (s *Server) GetUsersOnlineStatus( ctx context.Context, req *msggateway.GetUsersOnlineStatusReq, ) (*msggateway.GetUsersOnlineStatusResp, error) { + if !tokenverify.IsAppManagerUid(ctx) { + return nil, errs.ErrNoPermission.Wrap("only app manager") + } var resp msggateway.GetUsersOnlineStatusResp for _, userID := range req.UserIDs { clients, ok := s.LongConnServer.GetUserAllCons(userID) From cbf295af16a1265869db04e2189f0d8d5a5ee0ff Mon Sep 17 00:00:00 2001 From: withchao <48119764+withchao@users.noreply.github.com> Date: Mon, 17 Jul 2023 17:23:39 +0800 Subject: [PATCH 25/62] fix: s3 browser preview (#580) Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- config/config.yaml | 2 +- pkg/common/db/controller/s3.go | 4 +--- pkg/common/db/s3/cos/cos.go | 26 ++++++++++++++++---------- pkg/common/db/s3/minio/minio.go | 20 ++++++++++---------- pkg/common/db/s3/oss/oss.go | 18 +++++++++--------- pkg/common/db/s3/s3.go | 4 ++-- 6 files changed, 39 insertions(+), 35 deletions(-) diff --git a/config/config.yaml b/config/config.yaml index 45f3b7179..1c01031dc 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -74,7 +74,7 @@ api: object: enable: "minio" #使用minio - apiURL: "http://127.0.0.1:10002/object/" + apiURL: "http://127.0.0.1:10002/object/" #地址需要app能访问到 minio: bucket: "openim" #不建议修改 endpoint: "http://127.0.0.1:10005" #minio对外服务的ip和端口,app要能访问此ip和端口 diff --git a/pkg/common/db/controller/s3.go b/pkg/common/db/controller/s3.go index cdd1ac4c2..220e8e070 100644 --- a/pkg/common/db/controller/s3.go +++ b/pkg/common/db/controller/s3.go @@ -77,9 +77,7 @@ func (s *s3Database) AccessURL(ctx context.Context, name string, expire time.Dur } opt := &s3.AccessURLOption{ ContentType: obj.ContentType, - } - if filename := filepath.Base(obj.Name); filename != "" { - opt.ContentDisposition = `attachment; filename=` + filename + Filename: filepath.Base(obj.Name), } expireTime := time.Now().Add(expire) rawURL, err := s.s3.AccessURL(ctx, obj.Key, expire, opt) diff --git a/pkg/common/db/s3/cos/cos.go b/pkg/common/db/s3/cos/cos.go index 799766bbe..cfdaaa5e4 100644 --- a/pkg/common/db/s3/cos/cos.go +++ b/pkg/common/db/s3/cos/cos.go @@ -248,21 +248,27 @@ func (c *Cos) ListUploadedParts(ctx context.Context, uploadID string, name strin } func (c *Cos) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (string, error) { - //reqParams := make(url.Values) - //if opt != nil { - // if opt.ContentType != "" { - // reqParams.Set("Content-Type", opt.ContentType) - // } - // if opt.ContentDisposition != "" { - // reqParams.Set("Content-Disposition", opt.ContentDisposition) - // } - //} + var option *cos.PresignedURLOptions + if opt != nil { + query := make(url.Values) + if opt.ContentType != "" { + query.Set("response-content-type", opt.ContentType) + } + if opt.Filename != "" { + query.Set("response-content-disposition", `attachment; filename="`+opt.Filename+`"`) + } + if len(query) > 0 { + option = &cos.PresignedURLOptions{ + Query: &query, + } + } + } if expire <= 0 { expire = time.Hour * 24 * 365 * 99 // 99 years } else if expire < time.Second { expire = time.Second } - rawURL, err := c.client.Object.GetPresignedURL(ctx, http.MethodGet, name, c.credential.SecretID, c.credential.SecretKey, expire, nil) + rawURL, err := c.client.Object.GetPresignedURL(ctx, http.MethodGet, name, c.credential.SecretID, c.credential.SecretKey, expire, option) if err != nil { return "", err } diff --git a/pkg/common/db/s3/minio/minio.go b/pkg/common/db/s3/minio/minio.go index 2f0a59a2e..baf9b64e6 100644 --- a/pkg/common/db/s3/minio/minio.go +++ b/pkg/common/db/s3/minio/minio.go @@ -253,21 +253,21 @@ func (m *Minio) ListUploadedParts(ctx context.Context, uploadID string, name str } func (m *Minio) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (string, error) { - //reqParams := make(url.Values) - //if opt != nil { - // if opt.ContentType != "" { - // reqParams.Set("Content-Type", opt.ContentType) - // } - // if opt.ContentDisposition != "" { - // reqParams.Set("Content-Disposition", opt.ContentDisposition) - // } - //} + reqParams := make(url.Values) + if opt != nil { + if opt.ContentType != "" { + reqParams.Set("response-content-type", opt.ContentType) + } + if opt.Filename != "" { + reqParams.Set("response-content-disposition", `attachment; filename="`+opt.Filename+`"`) + } + } if expire <= 0 { expire = time.Hour * 24 * 365 * 99 // 99 years } else if expire < time.Second { expire = time.Second } - u, err := m.core.Client.PresignedGetObject(ctx, m.bucket, name, expire, nil) + u, err := m.core.Client.PresignedGetObject(ctx, m.bucket, name, expire, reqParams) if err != nil { return "", err } diff --git a/pkg/common/db/s3/oss/oss.go b/pkg/common/db/s3/oss/oss.go index 572b665e6..f689836c6 100644 --- a/pkg/common/db/s3/oss/oss.go +++ b/pkg/common/db/s3/oss/oss.go @@ -261,15 +261,15 @@ func (o *OSS) ListUploadedParts(ctx context.Context, uploadID string, name strin } func (o *OSS) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (string, error) { - //var opts []oss.Option - //if opt != nil { - // if opt.ContentType != "" { - // opts = append(opts, oss.ContentType(opt.ContentType)) - // } - // if opt.ContentDisposition != "" { - // opts = append(opts, oss.ContentDisposition(opt.ContentDisposition)) - // } - //} + var opts []oss.Option + if opt != nil { + if opt.ContentType != "" { + opts = append(opts, oss.ResponseContentType(opt.ContentType)) + } + if opt.Filename != "" { + opts = append(opts, oss.ResponseContentDisposition(`attachment; filename="`+opt.Filename+`"`)) + } + } if expire <= 0 { expire = time.Hour * 24 * 365 * 99 // 99 years } else if expire < time.Second { diff --git a/pkg/common/db/s3/s3.go b/pkg/common/db/s3/s3.go index 55adc313c..fadb09a0b 100644 --- a/pkg/common/db/s3/s3.go +++ b/pkg/common/db/s3/s3.go @@ -117,8 +117,8 @@ type ListUploadedPartsResult struct { } type AccessURLOption struct { - ContentType string `json:"contentType"` - ContentDisposition string `json:"contentDisposition"` + ContentType string `json:"contentType"` + Filename string `json:"filename"` } type Interface interface { From e5953339da7c2dffd60b0c8df66fe643d62ea510 Mon Sep 17 00:00:00 2001 From: skiffer-git <44203734@qq.com> Date: Mon, 17 Jul 2023 20:59:25 +0800 Subject: [PATCH 26/62] update readme: With the release of the new system, the readme is also updated accordingly. Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- README-zh_CN.md | 230 ++++++++++++++++++++++++++++++------------------ 1 file changed, 144 insertions(+), 86 deletions(-) diff --git a/README-zh_CN.md b/README-zh_CN.md index 1cdd0a52e..c2bf90472 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -26,12 +26,14 @@ ## Open-IM-Server 是什么 -Open-IM-Server 是一款即时通讯服务器,使用纯 Golang 开发,采用 JSON over WebSocket 传输协议。在 Open-IM-Server 中,所有东西都是消息,因此您可以轻松扩展自定义消息,而无需修改服务器代码。使用微服务架构,Open-IM-Server 可以使用集群进行部署。通过在客户端服务器上部署 Open-IM-Server,开发人员可以免费快速地将即时通讯和实时网络功能集成到自己的应用程序中,并确保业务数据的安全性和隐私性。 +Open-IM-Server 是一款即时通讯服务器,使用纯 Golang 开发,采用 JSON over WebSocket 传输协议。在 Open-IM-Server 中,所有东西都是消息,因此您可以轻松扩展自定义消息,而无需修改服务器代码。使用微服务架构,Open-IM-Server 可以使用集群进行部署。通过在服务器上部署 Open-IM-Server,开发人员可以快速地将即时通讯和实时网络功能集成到自己的应用程序中,并确保业务数据的安全性和隐私性。 + +Open-IM-Server并不是一个独立的产品,本身不包含账号的注册和登录服务。 +为方便大家测试,我们开源了包括登录注册功能的 [chat 仓库](https://github.com/OpenIMSDK/chat),chat 业务服务端和 Open-IM-Server 一起部署,即可搭建一个聊天产品。 ## 特点 -+ 免费 -+ 可扩展架构 ++ 开源 + 易于集成 + 良好的可扩展性 + 高性能 @@ -40,137 +42,193 @@ Open-IM-Server 是一款即时通讯服务器,使用纯 Golang 开发,采用 ## 社区 -+ 访问中文官方网站:[Open-IM中文开发文档](https://doc.rentsoft.cn/) ++ 访问中文官方网站:[OpenIM中文开发文档](https://doc.rentsoft.cn/) ## 快速开始 ### 安装Open-IM-Server -> Open-IM 依赖于五个开源高性能组件:ETCD、MySQL、MongoDB、Redis 和 Kafka。在部署 Open-IM-Server 之前,请确保已安装上述五个组件。如果您的服务器没有上述组件,则必须首先安装缺失组件。如果您已经拥有上述组件,则建议直接使用它们。如果没有,则建议使用 Docker-compose,无需安装依赖项,一键部署,更快更方便。 +> Open-IM-Server依赖于五个开源组件:Zookeeper、MySQL、MongoDB、Redis 和 Kafka。在部署 Open-IM-Server 之前,请确保已安装上述五个组件。如果没有,则建议使用 docker-compose,一键部署,方便快捷。 + +### 使用 docker-compose 部署 + +1. 隆项目 -### 使用 Docker 部署 +``` +git clone https://github.com/OpenIMSDK/Open-IM-Server +cd Open-IM-Server +git checkout release-v3.0 #or other release branch +``` -1. 安装 [Go 环境](https://golang.org/doc/install)。确保 Go 版本至少为 1.17。 +2. 修改 env -2. 克隆 Open-IM 项目到您的服务器 +``` +此处主要修改相关组件密码 +USER=root #不用修改 +PASSWORD=openIM123 #8位以上的数字和字母组合密码,密码对redis mysql mongo生效,以及config/config.yaml中的accessSecret +ENDPOINT=http://127.0.0.1:10005 #minio对外服务的ip和端口,或用域名storage.xx.xx,app要能访问到此ip和端口或域名, +API_URL=http://127.0.0.1:10002/object/ #app要能访问到此ip和端口或域名, +DATA_DIR=./ #指定大磁盘目录 +``` - `git clone --recursive` +3. 部署和启动 -3. 部署 +注意:此命令只能执行一次,它会根据.env 中的 PASSWORD 变量修改 docker-compose 中组件密码,并修改 config/config.yaml 中的组件密码 +如果.env 中的密码变了,需要先 docker-compose down ; rm components -rf 后再执行此命令。 - 1. 修改 env +``` +chmod +x install_im_server.sh; +./install_im_server.sh; +``` - ``` - #cd Open-IM-server - USER=root - PASSWORD=openIM123 #密码至少8位数字,不包括特殊字符 - ENDPOINT=http://127.0.0.1:10005 #请用互联网IP替换127.0.0.1 - DATA_DIR=./ - ``` +4. 检查服务 - 2. 部署和启动 +``` +cd scripts; +./docker_check_service.sh +``` - ``` - chmod +x install_im_server.sh; - ./install_im_server.sh; - ``` +![https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/docker_build.png](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/docker_build.png) - 3. 检查服务 +5. 开放 IM 端口 - ``` - cd scripts; - ./docker_check_service.sh - ./check_all.sh - ``` +| TCP 端口 | 说明 | 操作 | +| --------- | ----------------------------------------------------- | --------------------------------------- | +| TCP:10001 | ws 协议,消息端口,如消息发送、推送等,用于客户端 SDK | 端口放行或 nginx 反向代理,并关闭防火墙 | +| TCP:10002 | api 端口,如用户、好友、群组、消息等接口。 | 端口放行或 nginx 反向代理,并关闭防火墙 | +| TCP:10005 | 选择 minio 存储时需要(openIM 默认使用 minio 存储) | 端口放行或 nginx 反向代理,并关闭防火墙 | - ![https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/Open-IM-Servers-on-System.png](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/Open-IM-Servers-on-System.png) +6. 开放 Chat 端口 + +| TCP 端口 | 说明 | 操作 | +| --------- | ------------------------ | --------------------------------------- | +| TCP:10008 | 业务系统,如注册、登录等 | 端口放行或 nginx 反向代理,并关闭防火墙 | +| TCP:10009 | 管理后台,如统计、封号等 | 端口放行或 nginx 反向代理,并关闭防火墙 | ### 使用源代码部署 -1. Go 1.17 或更高版本。 +1. Go 1.18或更高版本。 2. 克隆 ``` - git clone --recursive - cd cmd/openim-sdk-core - git checkout main + git clone https://github.com/OpenIMSDK/Open-IM-Server + cd Open-IM-Server + git checkout release-v3.0 #or other release branch ``` -3. 设置可执行权限 +3. 编译 ``` - cd ../../scripts/ + cd Open-IM-server/scripts chmod +x *.sh + ./build_all_service.sh ``` -4. 构建 +所有服务已成功构建如图所示 - ``` - ./batch_build_all_service.sh - ``` +![编译成功](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/build.png) -所有服务已成功构建 +> -### 配置说明 +### 组件配置说明 -> Open-IM 配置分为基本组件配置和业务内部服务配置。当使用产品时,开发人员需要将每个组件的地址填写为其服务器组件的地址,并确保业务内部服务端口未被占用。 +config/config.yaml中针对存储组件有详细的配置说明 -### 基本组件配置说明 - -+ ETCD - + Etcd 用于 RPC 服务的发现和注册,Etcd Schema 是注册名称的前缀,建议将其修改为公司名称,Etcd 地址(ip+port)支持集群部署,可以填写多个 ETCD 地址,也可以只有一个 etcd 地址。 ++ Zookeeper + + 用于RPC 服务发现和注册,支持集群。 + + ```` + ``` + zookeeper: + schema: openim #不建议修改 + address: [ 127.0.0.1:2181 ] #地址 + username: #用户名 + password: #密码 + ``` + ```` + + + + MySQL - + MySQL 用于消息和用户关系的全存储,暂时不支持集群部署。修改地址、用户、密码和数据库名称。 + + + 用于存储用户、关系链、群组,支持数据库主备。 + + ``` + mysql: + address: [ 127.0.0.1:13306 ] #地址 + username: root #用户名 + password: openIM123 #密码 + database: openIM_v2 #不建议修改 + maxOpenConn: 1000 #最大连接数 + maxIdleConn: 100 #最大空闲连接数 + maxLifeTime: 60 #连接可以重复使用的最长时间(秒) + logLevel: 4 #日志级别 1=slient 2=error 3=warn 4=info + slowThreshold: 500 #慢语句阈值 (毫秒) + ``` + + + + Mongo - + Mongo 用于消息的离线存储,默认存储 7 天。暂时不支持集群部署。只需修改地址和数据库名称即可。 + + 用于存储离线消息,支持mongo分片集群。 + + ``` + mongo: + uri: #不为空则直接使用该值 + address: [ 127.0.0.1:37017 ] #地址 + database: openIM #mongo db 默认即可 + username: root #用户名 + password: openIM123 #密码 + maxPoolSize: 100 #最大连接数 + ``` + + Redis - + Redis 目前主要用于消息序列号存储和用户令牌信息存储。暂时不支持集群部署。只需修改相应的 Redis 地址和密码即可。 + + 用于存储消息序列号、最新消息、用户token及mysql缓存,支持集群部署。 + + ``` + redis: + address: [ 127.0.0.1:16379 ] #地址 + username: #用户名 + password: openIM123 #密码 + ``` + + Kafka - + Kafka 用作消息传输存储队列,支持集群部署,只需修改相应的地址。 - -### 内部服务配置说明 - -+ credential&&push - + Open-IM 需要使用三方离线推送功能。目前使用的是腾讯的三方推送,支持 IOS、Android 和 OSX 推送。这些信息是腾讯推送的一些注册信息,开发人员需要去腾讯云移动推送注册相应的信息。如果您没有填写相应的信息,则无法使用离线消息推送功能。 -+ api&&rpcport&&longconnsvr&&rpcregistername - + API 端口是 HTTP 接口,longconnsvr 是 WebSocket 监听端口,rpcport 是内部服务启动端口。两者都支持集群部署。请确保这些端口未被使用。如果要为单个服务打开多个服务,请填写多个以逗号分隔的端口。rpcregistername 是每个服务在注册表 Etcd 中注册的服务名称,无需修改。 -+ log&&modulename - + 日志配置包括日志文件的存储路径,日志发送到 Elasticsearch 进行日志查看。目前不支持将日志发送到 Elasticsearch。暂时不需要修改配置。modulename 用于根据服务模块的名称拆分日志。默认配置可以。 - -### 脚本说明 - -> Open-IM 脚本提供服务编译、启动和停止脚本。有四个 Open-IM 脚本启动模块,一个是 http+rpc 服务启动模块,第二个是 WebSocket 服务启动模块,然后是 msg_transfer 模块,最后是 push 模块。 - -+ path_info.sh&&style_info.sh&& - - functions.sh - - + 包含每个模块的路径信息,包括源代码所在的路径、服务启动名称、shell 打印字体样式以及一些用于处理 shell 字符串的函数。 - -+ build_all_service.sh - - + 编译模块,将 Open-IM 的所有源代码编译为二进制文件并放入 bin 目录。 - -+ start_rpc_api_service.sh&&msg_gateway_start.sh&&msg_transfer_start.sh&&push_start.sh - - + 独立脚本启动模块,后跟 API 和 RPC 模块、消息网关模块、消息传输模块和推送模块。 - -+ start_all.sh&&stop_all.sh - - + 总脚本,启动所有服务和关闭所有服务。 - -## 认证流程图 + + 用于消息队列,用于消息解耦,支持集群部署。 + + ``` + kafka: + username: #用户名 + password: #密码 + addr: [ 127.0.0.1:9092 ] #地址 + latestMsgToRedis: + topic: "latestMsgToRedis" + offlineMsgToMongo: + topic: "offlineMsgToMongoMysql" + msgToPush: + topic: "msqToPush" + msgToModify: + topic: "msgToModify" + consumerGroupID: + msgToRedis: redis + msgToMongo: mongo + msgToMySql: mysql + msgToPush: push + msgToModify: modify + ``` + +## APP和OpenIM关系 + +OpenIM 是开源的即时通讯组件,它并不是一个独立的产品,此图展示了AppServer、AppClient、Open-IM-Server以及Open-IM-SDK之间的关系 ![https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/open-im-server.png](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/open-im-server.png) -## 架构 +## 整体架构 ![https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/Architecture.jpg](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/Architecture.jpg) ## 开始开发 OpenIM -[社区存储库](https://github.com/OpenIMSDK/community)包含有关从源代码构建 Kubernetes、如何贡献代码和文档、有关什么的联系人等所有信息。 +[社区存储库](https://github.com/OpenIMSDK/community)包含有关从源代码构建 Kubernetes、如何贡献代码和文档。 ## 贡献 From ff786eefaf61a6ddd3d5eb750c3936f3948f6e43 Mon Sep 17 00:00:00 2001 From: skiffer-git <72860476+skiffer-git@users.noreply.github.com> Date: Mon, 17 Jul 2023 20:43:20 +0800 Subject: [PATCH 27/62] Add files via upload Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- docs/images/build.png | Bin 0 -> 62555 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/images/build.png diff --git a/docs/images/build.png b/docs/images/build.png new file mode 100644 index 0000000000000000000000000000000000000000..7c5914c82597681eaeedbec895967d8794eada01 GIT binary patch literal 62555 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 literal 0 HcmV?d00001 From 273f92e767bb8ef4034c31ac31cf0a4c31717334 Mon Sep 17 00:00:00 2001 From: skiffer-git <72860476+skiffer-git@users.noreply.github.com> Date: Mon, 17 Jul 2023 20:56:17 +0800 Subject: [PATCH 28/62] Add files via upload Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- docs/images/docker_build.png | Bin 0 -> 67121 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/images/docker_build.png diff --git a/docs/images/docker_build.png b/docs/images/docker_build.png new file mode 100644 index 0000000000000000000000000000000000000000..dca7f32e0012451e7f539a09c5aafefacfb5b015 GIT binary patch literal 67121 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%0A5h=FR=&aCIjGY0zuLE0GPXLA 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 Date: Mon, 17 Jul 2023 21:03:42 +0800 Subject: [PATCH 29/62] update readme: With the release of the new system, the readme is also updated accordingly. Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- docs/images/docker_build.png | Bin 67121 -> 58699 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/images/docker_build.png b/docs/images/docker_build.png index dca7f32e0012451e7f539a09c5aafefacfb5b015..f4be10f6894b79a586b725cb463b5333690b5e48 100644 GIT binary patch literal 58699 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 literal 67121 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%0A5h=FR=&aCIjGY0zuLE0GPXLA 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 Date: Mon, 17 Jul 2023 21:04:40 +0800 Subject: [PATCH 30/62] update readme: With the release of the new system, the readme is also updated accordingly. Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- README-zh_CN.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README-zh_CN.md b/README-zh_CN.md index c2bf90472..4307d2bea 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -220,11 +220,11 @@ config/config.yaml中针对存储组件有详细的配置说明 OpenIM 是开源的即时通讯组件,它并不是一个独立的产品,此图展示了AppServer、AppClient、Open-IM-Server以及Open-IM-SDK之间的关系 -![https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/open-im-server.png](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/open-im-server.png) +![https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/open-im-server.png](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/open-im-server.png) ## 整体架构 -![https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/Architecture.jpg](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/Architecture.jpg) +![https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/Architecture.jpg](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/Architecture.jpg) ## 开始开发 OpenIM From d55aa1450b1255a295752d3881bee2761d03741b Mon Sep 17 00:00:00 2001 From: skiffer-git <44203734@qq.com> Date: Mon, 17 Jul 2023 21:18:34 +0800 Subject: [PATCH 31/62] update readme: With the release of the new system, the readme is also updated accordingly. Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- README-zh_CN.md | 62 ++++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/README-zh_CN.md b/README-zh_CN.md index 4307d2bea..b9b58deec 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -46,13 +46,9 @@ Open-IM-Server并不是一个独立的产品,本身不包含账号的注册和 ## 快速开始 -### 安装Open-IM-Server - -> Open-IM-Server依赖于五个开源组件:Zookeeper、MySQL、MongoDB、Redis 和 Kafka。在部署 Open-IM-Server 之前,请确保已安装上述五个组件。如果没有,则建议使用 docker-compose,一键部署,方便快捷。 - ### 使用 docker-compose 部署 -1. 隆项目 +1. 克隆项目 ``` git clone https://github.com/OpenIMSDK/Open-IM-Server @@ -60,7 +56,7 @@ cd Open-IM-Server git checkout release-v3.0 #or other release branch ``` -2. 修改 env +2. 修改 .env ``` 此处主要修改相关组件密码 @@ -90,22 +86,7 @@ cd scripts; ![https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/docker_build.png](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/docker_build.png) -5. 开放 IM 端口 - -| TCP 端口 | 说明 | 操作 | -| --------- | ----------------------------------------------------- | --------------------------------------- | -| TCP:10001 | ws 协议,消息端口,如消息发送、推送等,用于客户端 SDK | 端口放行或 nginx 反向代理,并关闭防火墙 | -| TCP:10002 | api 端口,如用户、好友、群组、消息等接口。 | 端口放行或 nginx 反向代理,并关闭防火墙 | -| TCP:10005 | 选择 minio 存储时需要(openIM 默认使用 minio 存储) | 端口放行或 nginx 反向代理,并关闭防火墙 | - -6. 开放 Chat 端口 - -| TCP 端口 | 说明 | 操作 | -| --------- | ------------------------ | --------------------------------------- | -| TCP:10008 | 业务系统,如注册、登录等 | 端口放行或 nginx 反向代理,并关闭防火墙 | -| TCP:10009 | 管理后台,如统计、封号等 | 端口放行或 nginx 反向代理,并关闭防火墙 | - -### 使用源代码部署 +### 使用源码编译 1. Go 1.18或更高版本。 @@ -129,8 +110,6 @@ cd scripts; ![编译成功](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/build.png) -> - ### 组件配置说明 config/config.yaml中针对存储组件有详细的配置说明 @@ -216,6 +195,41 @@ config/config.yaml中针对存储组件有详细的配置说明 msgToModify: modify ``` +### 启停服务 + +启动服务 + +``` +./start_all.sh; +``` + +检查服务 + +``` +./check_all.sh +``` + +停止服务 + +``` +./stop_all.sh +``` + +### 开放 IM 端口 + +| TCP 端口 | 说明 | 操作 | +| --------- | ----------------------------------------------------- | --------------------------------------- | +| TCP:10001 | ws 协议,消息端口,如消息发送、推送等,用于客户端 SDK | 端口放行或 nginx 反向代理,并关闭防火墙 | +| TCP:10002 | api 端口,如用户、好友、群组、消息等接口。 | 端口放行或 nginx 反向代理,并关闭防火墙 | +| TCP:10005 | 选择 minio 存储时需要(openIM 默认使用 minio 存储) | 端口放行或 nginx 反向代理,并关闭防火墙 | + +### 开放 Chat 端口 + +| TCP 端口 | 说明 | 操作 | +| --------- | ------------------------ | --------------------------------------- | +| TCP:10008 | 业务系统,如注册、登录等 | 端口放行或 nginx 反向代理,并关闭防火墙 | +| TCP:10009 | 管理后台,如统计、封号等 | 端口放行或 nginx 反向代理,并关闭防火墙 | + ## APP和OpenIM关系 OpenIM 是开源的即时通讯组件,它并不是一个独立的产品,此图展示了AppServer、AppClient、Open-IM-Server以及Open-IM-SDK之间的关系 From 1531f3abc715e2b8dba87ca81210bf95c892fcc1 Mon Sep 17 00:00:00 2001 From: skiffer-git <44203734@qq.com> Date: Mon, 17 Jul 2023 21:42:49 +0800 Subject: [PATCH 32/62] update readme: With the release of the new system, the readme is also updated accordingly. Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- README.md | 271 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 174 insertions(+), 97 deletions(-) diff --git a/README.md b/README.md index dcf7230c1..9e0242424 100644 --- a/README.md +++ b/README.md @@ -28,142 +28,219 @@ ## What is Open-IM-Server -Instant messaging server. Backend in pure Golang, wire transport protocol is JSON over websocket. -Everything is a message in Open-IM-Server, so you can extend custom messages easily, there is no need to modify the server code. -Using microservice architectures, Open-IM-Server can be deployed using clusters. -By deployment of the Open-IM-Server on the customer's server, developers can integrate instant messaging and real-time network capabilities into their own applications free of charge and quickly, and ensure the security and privacy of business data. +Open-IM-Server is an instant messaging server developed using pure Golang, adopting JSON over WebSocket as the communication protocol. In Open-IM-Server, everything is a message, so you can easily extend custom messages without modifying the server code. With a microservice architecture, Open-IM-Server can be deployed using clusters. By deploying Open-IM-Server on a server, developers can quickly integrate instant messaging and real-time networking features into their applications, ensuring the security and privacy of business data. + +Open-IM-Server is not a standalone product and does not include account registration and login services. For your convenience, we have open-sourced the [chat repository](https://github.com/OpenIMSDK/chat) which includes login and registration functionality. By deploying the chat business server alongside Open-IM-Server, a chat product can be set up. ## Features -- Everything in Free -- Scalable architecture -- Easy integration -- Good scalability +- Open source +- Easy to integrate +- Excellent scalability - High performance - Lightweight - Supports multiple protocols ## Community -- Visit the Chinese official website here: [📚 Open-IM docs](https://www.openim.online/zh) +- Visit the official Chinese website: [OpenIM Chinese Developer Documentation](https://doc.rentsoft.cn/) ## Quick start -### Installing Open-IM-Server - -> Open-IM relies on five open source high-performance components: ETCD, MySQL, MongoDB, Redis, and Kafka. Privatization deployment Before Open-IM-Server, please make sure that the above five components have been installed. If your server does not have the above components, you must first install Missing components. If you have the above components, it is recommended to use them directly. If not, it is recommended to use Docker-compose, no To install dependencies, one-click deployment, faster and more convenient. +### Deploying with docker-compose + + + +> 1. Clone the project +> +> ``` +> +> ``` +> +> 1. Modify .env +> +> ``` +> makefileCopy codeHere you mainly modify the passwords for related components +> USER=root #no need to modify +> PASSWORD=openIM123 #A combination of 8 or more numbers and letters, this password applies to redis, mysql, mongo, as well as accessSecret in config/config.yaml +> ENDPOINT=http://127.0.0.1:10005 #minio's external service IP and port, or use the domain name storage.xx.xx, the app must be able to access this IP and port or domain, +> API_URL=http://127.0.0.1:10002/object/ #the app must be able to access this IP and port or domain, +> DATA_DIR=./ #designate large disk directory +> ``` +> +> 1. Deploy and start +> +> Note: This command can only be executed once. It will modify the component passwords in docker-compose based on the PASSWORD variable in .env, and modify the component passwords in config/config.yaml. If the password in .env changes, you need to first execute docker-compose down; rm components -rf and then execute this command. +> +> ``` +> bashCopy codechmod +x install_im_server.sh; +> ./install_im_server.sh; +> ``` +> +> 1. Check the service +> +> ``` +> bashCopy codecd scripts; +> ./docker_check_service.sh +> ``` +> +> ![https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/docker_build.png](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/docker_build.png) + +### Compile from source + +1. Go 1.18 or higher version. -#### Deploy using Docker +2. Clone -1. Install [Go environment](https://golang.org/doc/install). Make sure Go version is at least 1.17 + ``` + arduinoCopy codegit clone https://github.com/OpenIMSDK/Open-IM-Server + cd Open-IM-Server + git checkout release-v3.0 #or other release branch + ``` -2. Clone the Open-IM project to your server +3. Compile ``` - git clone https://github.com/OpenIMSDK/Open-IM-Server.git --recursive + bashCopy codecd Open-IM-server/scripts + chmod +x *.sh + ./build_all_service.sh ``` -3. Deploy - - 1. Modify env - - ``` - #cd Open-IM-server - USER=root - PASSWORD=openIM123 #Password with more than 8 digits, excluding special characters - ENDPOINT=http://127.0.0.1:10005 #Replace 127.0.0.1 with Internet IP - DATA_DIR=./ - ``` - - 2. Deploy && Start - - ``` - chmod +x install_im_server.sh; - ./install_im_server.sh; - ``` - - 4. Check service - - ``` - cd scripts; - ./docker_check_service.sh./check_all.sh - ``` - - ![OpenIMServersonSystempng](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/Open-IM-Servers-on-System.png) - -#### Deploy using source code - -1. Go 1.17 or above. -2. Clone +All services have been successfully built as shown in the figure -```shell -git clone https://github.com/OpenIMSDK/Open-IM-Server.git --recursive -cd cmd/openim-sdk-core -git checkout main -``` +![Successful Compilation](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/build.png) -1. Set executable permissions +### Component Configuration Instructions -```shell -cd ../../scripts/ -chmod +x *.sh -``` +The config/config.yaml file has detailed configuration instructions for the storage components. -1. build +- Zookeeper -```shell -./batch_build_all_service.sh -``` - -all services build success + - Used for RPC service discovery and registration, cluster support. -### CONFIGURATION INSTRUCTIONS + ```` + yamlCopy code``` + zookeeper: + schema: openim #Not recommended to modify + address: [ 127.0.0.1:2181 ] #address + username: #username + password: #password + ``` + ```` -> Open-IM configuration is divided into basic component configuration and business internal service configuration. Developers need to fill in the address of each component as the address of their server component when using the product, and ensure that the internal service port of the business is not occupied +- MySQL -#### Basic Component Configuration Instructions + - Used for storing users, relationships, and groups, supports master-slave database. + + ``` + yamlCopy codemysql: + address: [ 127.0.0.1:13306 ] #address + username: root #username + password: openIM123 #password + database: openIM_v2 #Not recommended to modify + maxOpenConn: 1000 #maximum connection + maxIdleConn: 100 #maximum idle connection + maxLifeTime: 60 #maximum time a connection can be reused (seconds) + logLevel: 4 #log level 1=slient 2=error 3=warn 4=info + slowThreshold: 500 #slow statement threshold (milliseconds) + ``` -- ETCD - - Etcd is used for the discovery and registration of rpc services, etcd Schema is the prefix of the registered name, it is recommended to modify it to your company name, etcd address (ip+port) supports clustered deployment, you can fill in multiple ETCD addresses separated by commas, and also only one etcd address. -- MySQL - - mysql is used for full storage of messages and user relationships. Cluster deployment is not supported for the time being. Modify addresses and users, passwords, and database names. - Mongo - - Mongo is used for offline storage of messages. The default storage is 7 days. Cluster deployment is temporarily not supported. Just modify the address and database name. + + - Used for storing offline messages, supports mongo sharded clusters. + + ``` + yamlCopy codemongo: + uri: #Use this value directly if not empty + address: [ 127.0.0.1:37017 ] #address + database: openIM #default mongo db + username: root #username + password: openIM123 #password + maxPoolSize: 100 #maximum connections + ``` + - Redis - - Redis is currently mainly used for message serial number storage and user token information storage. Cluster deployment is temporarily not supported. Just modify the corresponding redis address and password. + + - Used for storing message sequence numbers, latest messages, user tokens, and mysql cache, supports cluster deployment. + + ``` + yamlCopy coderedis: + address: [ 127.0.0.1:16379 ] #address + username: #username + password: openIM123 #password + ``` + - Kafka - - Kafka is used as a message transfer storage queue to support cluster deployment, just modify the corresponding address -#### Internal Service Configuration Instructions + - Used for message queues, for message decoupling, supports cluster deployment. + + ``` + yamlCopy codekafka: + username: #username + password: #password + addr: [ 127.0.0.1:9092 ] #address + latestMsgToRedis: + topic: "latestMsgToRedis" + offlineMsgToMongo: + topic: "offlineMsgToMongoMysql" + msgToPush: + topic: "msqToPush" + msgToModify: + topic: "msgToModify" + consumerGroupID: + msgToRedis: redis + msgToMongo: mongo + msgToMySql: mysql + msgToPush: push + msgToModify: modify + ``` + +### Start and Stop Services + +Start services + +``` +bashCopy code +./start_all.sh; +``` + +Check services + +``` +bashCopy code +./check_all.sh +``` + +Stop services + +``` +bashCopy code +./stop_all.sh +``` + +### Open IM Ports -- credential&&push - - The Open-IM needs to use the three-party offline push function. Currently, Tencent's three-party push is used. It supports IOS, Android and OSX push. This information is some registration information pushed by Tencent. Developers need to go to Tencent Cloud Mobile Push to register the corresponding information. If you do not fill in the corresponding information, you cannot use the offline message push function -- api&&rpcport&&longconnsvr&&rpcregistername - - The api port is the http interface, longconnsvr is the websocket listening port, and rpcport is the internal service startup port. Both support cluster deployment. Make sure that these ports are not used. If you want to open multiple services for a single service, fill in multiple ports separated by commas. rpcregistername is the service name registered by each service to the registry etcd, no need to modify -- log&&modulename - - The log configuration includes the storage path of the log file, and the log is sent to elasticsearch for log viewing. Currently, the log is not supported to be sent to elasticsearch. The configuration does not need to be modified for the time being. The modulename is used to split the log according to the name of the service module. The default configuration is fine. -- multiloginpolicy&&tokenpolicy - - Open-IM supports multi-terminal login. Currently, there are three multi-terminal login policies. The PC terminal and the mobile terminal are online at the same time by default. When multiple policies are configured to be true, the first policy with true is used by default, and the token policy is the generated token policy. , The developer can customize the expiration time of the token +| TCP Port | Description | Operation | +| --------- | ------------------------------------------------------------ | ----------------------------------------------------- | +| TCP:10001 | ws protocol, message port such as message sending, pushing etc, used for client SDK | Port release or nginx reverse proxy, and firewall off | +| TCP:10002 | api port, such as user, friend, group, message interfaces. | Port release or nginx reverse proxy, and firewall off | +| TCP:10005 | Required when choosing minio storage (openIM uses minio storage by default) | Port release or nginx reverse proxy, and firewall off | -### scripts DESCRIPTION +### Open Chat Ports -> Open-IM scripts provides service compilation, start, and stop scripts. There are four Open-IM scripts start modules, one is the http+rpc service start module, the second is the websocket service start module, then the msg_transfer module, and the last is the push module +| TCP Port | Description | Operation | +| --------- | --------------------------------------------------- | ----------------------------------------------------- | +| TCP:10008 | Business system, such as registration, login etc | Port release or nginx reverse proxy, and firewall off | +| TCP:10009 | Management backend, such as statistics, banning etc | Port release or nginx reverse proxy, and firewall off | -- path_info.sh&&style_info.sh&&functions.sh - - Contains the path information of each module, including the path where the source code is located, the name of the service startup, the shell print font style, and some functions for processing shell strings -- build_all_service.sh - - Compile the module, compile all the source code of Open-IM into a binary file and put it into the bin directory -- start_rpc_api_service.sh&&msg_gateway_start.sh&&msg_transfer_start.sh&&push_start.sh - - Independent scripts startup module, followed by api and rpc modules, message gateway module, message transfer module, and push module -- start_all.sh&&stop_all.sh - - Total scripts, start all services and close all services +## Relationship Between APP and OpenIM -## Authentication Clow Chart +OpenIM is an open source instant messaging component, it is not an independent product. This image shows the relationship between AppServer, AppClient, Open-IM-Server and Open-IM-SDK. -![avatar](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/open-im-server.png) +![https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/open-im-server.png](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/open-im-server.png) -## Architecture +## Overall Architecture -![avatar](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/Architecture.jpg) +![https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/Architecture.jpg](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/Architecture.jpg) ## To start developing OpenIM The [community repository](https://github.com/OpenIMSDK/community) hosts all information about building Kubernetes from source, how to contribute code and documentation, who to contact about what, etc. From 9705029a5ef8d4f9d86ee81344d2cca8eba7bf34 Mon Sep 17 00:00:00 2001 From: skiffer-git <44203734@qq.com> Date: Mon, 17 Jul 2023 21:45:16 +0800 Subject: [PATCH 33/62] update readme: With the release of the new system, the readme is also updated accordingly. Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- README.md | 72 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 9e0242424..a7e5aa133 100644 --- a/README.md +++ b/README.md @@ -44,46 +44,48 @@ Open-IM-Server is not a standalone product and does not include account registra ## Community - Visit the official Chinese website: [OpenIM Chinese Developer Documentation](https://doc.rentsoft.cn/) -## Quick start +## Quick Start ### Deploying with docker-compose +1. Clone the project + +``` +clone https://github.com/OpenIMSDK/Open-IM-Server +cd Open-IM-Server +git checkout release-v3.0 #or other release branch +``` + +1. Modify .env + +``` +makefileCopy codeHere you mainly modify the passwords for related components +USER=root #no need to modify +PASSWORD=openIM123 #A combination of 8 or more numbers and letters, this password applies to redis, mysql, mongo, as well as accessSecret in config/config.yaml +ENDPOINT=http://127.0.0.1:10005 #minio's external service IP and port, or use the domain name storage.xx.xx, the app must be able to access this IP and port or domain, +API_URL=http://127.0.0.1:10002/object/ #the app must be able to access this IP and port or domain, +DATA_DIR=./ #designate large disk directory +``` + +1. Deploy and start + +Note: This command can only be executed once. It will modify the component passwords in docker-compose based on the PASSWORD variable in .env, and modify the component passwords in config/config.yaml. If the password in .env changes, you need to first execute docker-compose down; rm components -rf and then execute this command. + +``` +bashCopy codechmod +x install_im_server.sh; +./install_im_server.sh; +``` + +1. Check the service + +``` +bashCopy codecd scripts; +./docker_check_service.sh +``` + +![https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/docker_build.png](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/docker_build.png) -> 1. Clone the project -> -> ``` -> -> ``` -> -> 1. Modify .env -> -> ``` -> makefileCopy codeHere you mainly modify the passwords for related components -> USER=root #no need to modify -> PASSWORD=openIM123 #A combination of 8 or more numbers and letters, this password applies to redis, mysql, mongo, as well as accessSecret in config/config.yaml -> ENDPOINT=http://127.0.0.1:10005 #minio's external service IP and port, or use the domain name storage.xx.xx, the app must be able to access this IP and port or domain, -> API_URL=http://127.0.0.1:10002/object/ #the app must be able to access this IP and port or domain, -> DATA_DIR=./ #designate large disk directory -> ``` -> -> 1. Deploy and start -> -> Note: This command can only be executed once. It will modify the component passwords in docker-compose based on the PASSWORD variable in .env, and modify the component passwords in config/config.yaml. If the password in .env changes, you need to first execute docker-compose down; rm components -rf and then execute this command. -> -> ``` -> bashCopy codechmod +x install_im_server.sh; -> ./install_im_server.sh; -> ``` -> -> 1. Check the service -> -> ``` -> bashCopy codecd scripts; -> ./docker_check_service.sh -> ``` -> -> ![https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/docker_build.png](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/docker_build.png) ### Compile from source From fb198fc1b4900fa7f5e25fe37485ab83bac0e985 Mon Sep 17 00:00:00 2001 From: skiffer-git <44203734@qq.com> Date: Mon, 17 Jul 2023 21:50:46 +0800 Subject: [PATCH 34/62] update readme: With the release of the new system, the readme is also updated accordingly. Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- README.md | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index a7e5aa133..1079b5b86 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ Open-IM-Server is not a standalone product and does not include account registra - Supports multiple protocols ## Community -- Visit the official Chinese website: [OpenIM Chinese Developer Documentation](https://doc.rentsoft.cn/) +- Visit the official website: [OpenIM Developer Documentation](https://www.openim.online/) ## Quick Start @@ -59,7 +59,6 @@ git checkout release-v3.0 #or other release branch 1. Modify .env ``` -makefileCopy codeHere you mainly modify the passwords for related components USER=root #no need to modify PASSWORD=openIM123 #A combination of 8 or more numbers and letters, this password applies to redis, mysql, mongo, as well as accessSecret in config/config.yaml ENDPOINT=http://127.0.0.1:10005 #minio's external service IP and port, or use the domain name storage.xx.xx, the app must be able to access this IP and port or domain, @@ -72,14 +71,14 @@ DATA_DIR=./ #designate large disk directory Note: This command can only be executed once. It will modify the component passwords in docker-compose based on the PASSWORD variable in .env, and modify the component passwords in config/config.yaml. If the password in .env changes, you need to first execute docker-compose down; rm components -rf and then execute this command. ``` -bashCopy codechmod +x install_im_server.sh; +chmod +x install_im_server.sh; ./install_im_server.sh; ``` 1. Check the service ``` -bashCopy codecd scripts; +cd scripts; ./docker_check_service.sh ``` @@ -94,7 +93,7 @@ bashCopy codecd scripts; 2. Clone ``` - arduinoCopy codegit clone https://github.com/OpenIMSDK/Open-IM-Server + git clone https://github.com/OpenIMSDK/Open-IM-Server cd Open-IM-Server git checkout release-v3.0 #or other release branch ``` @@ -102,7 +101,7 @@ bashCopy codecd scripts; 3. Compile ``` - bashCopy codecd Open-IM-server/scripts + cd Open-IM-server/scripts chmod +x *.sh ./build_all_service.sh ``` @@ -119,22 +118,20 @@ The config/config.yaml file has detailed configuration instructions for the stor - Used for RPC service discovery and registration, cluster support. - ```` - yamlCopy code``` + ``` zookeeper: schema: openim #Not recommended to modify address: [ 127.0.0.1:2181 ] #address username: #username password: #password ``` - ```` - MySQL - Used for storing users, relationships, and groups, supports master-slave database. ``` - yamlCopy codemysql: + mysql: address: [ 127.0.0.1:13306 ] #address username: root #username password: openIM123 #password @@ -151,7 +148,7 @@ The config/config.yaml file has detailed configuration instructions for the stor - Used for storing offline messages, supports mongo sharded clusters. ``` - yamlCopy codemongo: + mongo: uri: #Use this value directly if not empty address: [ 127.0.0.1:37017 ] #address database: openIM #default mongo db @@ -165,7 +162,7 @@ The config/config.yaml file has detailed configuration instructions for the stor - Used for storing message sequence numbers, latest messages, user tokens, and mysql cache, supports cluster deployment. ``` - yamlCopy coderedis: + redis: address: [ 127.0.0.1:16379 ] #address username: #username password: openIM123 #password @@ -176,7 +173,7 @@ The config/config.yaml file has detailed configuration instructions for the stor - Used for message queues, for message decoupling, supports cluster deployment. ``` - yamlCopy codekafka: + kafka: username: #username password: #password addr: [ 127.0.0.1:9092 ] #address @@ -201,21 +198,18 @@ The config/config.yaml file has detailed configuration instructions for the stor Start services ``` -bashCopy code ./start_all.sh; ``` Check services ``` -bashCopy code ./check_all.sh ``` Stop services ``` -bashCopy code ./stop_all.sh ``` From 3961f1e25df61cc3d927fb35a6337e4991ca2f02 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Thu, 20 Jul 2023 18:21:22 +0800 Subject: [PATCH 35/62] fix bug: obtain user online status err(#567) Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- internal/api/user.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/api/user.go b/internal/api/user.go index 1e75b8fb4..0cfe63a2f 100644 --- a/internal/api/user.go +++ b/internal/api/user.go @@ -88,6 +88,7 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) { parseError := apiresp.ParseError(err) if parseError.ErrCode == errs.NoPermissionError { apiresp.GinError(c, err) + return } } else { wsResult = append(wsResult, reply.SuccessResult...) From ab395778251a2d7dca04dc8530e96f5077785048 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Fri, 21 Jul 2023 18:03:49 +0800 Subject: [PATCH 36/62] fix bug: obtain user online status err(#567) Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- internal/api/user.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/api/user.go b/internal/api/user.go index 0cfe63a2f..0f7f404ae 100644 --- a/internal/api/user.go +++ b/internal/api/user.go @@ -84,7 +84,6 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) { reply, err := msgClient.GetUsersOnlineStatus(c, &req) if err != nil { log.ZWarn(c, "GetUsersOnlineStatus rpc err", err) - // apiresp.GinError(c, err) parseError := apiresp.ParseError(err) if parseError.ErrCode == errs.NoPermissionError { apiresp.GinError(c, err) From 52832320178a1f57d225a57731525a16c765c523 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Sun, 23 Jul 2023 10:46:41 +0800 Subject: [PATCH 37/62] fix: changing naming irregularities under pkg and internal packages (#520) --- pkg/rpcclient/msg.go | 16 +++++++ pkg/rpcclient/notification/common.go | 2 + pkg/rpcclient/notification/conevrsation.go | 11 +++-- pkg/rpcclient/notification/friend.go | 31 +++++++++++++- pkg/rpcclient/notification/group.go | 49 +++++++++++++++++++++- pkg/rpcclient/notification/msg.go | 6 +++ pkg/rpcclient/push.go | 6 +++ pkg/rpcclient/third.go | 12 ++++-- pkg/rpcclient/user.go | 24 +++++++++++ pkg/startrpc/start.go | 2 + pkg/statistics/statistics.go | 5 +++ 11 files changed, 153 insertions(+), 11 deletions(-) diff --git a/pkg/rpcclient/msg.go b/pkg/rpcclient/msg.go index a012a5a5f..be776138b 100644 --- a/pkg/rpcclient/msg.go +++ b/pkg/rpcclient/msg.go @@ -154,17 +154,21 @@ func (m *MessageRpcClient) GetMaxSeq(ctx context.Context, req *sdkws.GetMaxSeqRe func (m *MessageRpcClient) PullMessageBySeqList(ctx context.Context, req *sdkws.PullMessageBySeqsReq) (*sdkws.PullMessageBySeqsResp, error) { resp, err := m.Client.PullMessageBySeqs(ctx, req) + return resp, err } +// GetConversationMaxSeq func (m *MessageRpcClient) GetConversationMaxSeq(ctx context.Context, conversationID string) (int64, error) { resp, err := m.Client.GetConversationMaxSeq(ctx, &msg.GetConversationMaxSeqReq{ConversationID: conversationID}) if err != nil { return 0, err } + return resp.MaxSeq, nil } +// NotificationSender type NotificationSender struct { contentTypeConf map[int32]config.NotificationConf sessionTypeConf map[int32]int32 @@ -172,31 +176,37 @@ type NotificationSender struct { getUserInfo func(ctx context.Context, userID string) (*sdkws.UserInfo, error) } +// NotificationSenderOptions type NotificationSenderOptions func(*NotificationSender) +// WithLocalSendMsg func WithLocalSendMsg(sendMsg func(ctx context.Context, req *msg.SendMsgReq) (*msg.SendMsgResp, error)) NotificationSenderOptions { return func(s *NotificationSender) { s.sendMsg = sendMsg } } +// WithRpcClient func WithRpcClient(msgRpcClient *MessageRpcClient) NotificationSenderOptions { return func(s *NotificationSender) { s.sendMsg = msgRpcClient.SendMsg } } +// WithUserRpcClient func WithUserRpcClient(userRpcClient *UserRpcClient) NotificationSenderOptions { return func(s *NotificationSender) { s.getUserInfo = userRpcClient.GetUserInfo } } +// NewNotificationSender func NewNotificationSender(opts ...NotificationSenderOptions) *NotificationSender { notificationSender := &NotificationSender{contentTypeConf: newContentTypeConf(), sessionTypeConf: newSessionTypeConf()} for _, opt := range opts { opt(notificationSender) } + return notificationSender } @@ -204,19 +214,23 @@ type notificationOpt struct { WithRpcGetUsername bool } +// NotificationOptions type NotificationOptions func(*notificationOpt) +// WithRpcGetUserName func WithRpcGetUserName() NotificationOptions { return func(opt *notificationOpt) { opt.WithRpcGetUsername = true } } +// NotificationWithSesstionType func (s *NotificationSender) NotificationWithSesstionType(ctx context.Context, sendID, recvID string, contentType, sesstionType int32, m proto.Message, opts ...NotificationOptions) (err error) { n := sdkws.NotificationElem{Detail: utils.StructToJsonString(m)} content, err := json.Marshal(&n) if err != nil { log.ZError(ctx, "MsgClient Notification json.Marshal failed", err, "sendID", sendID, "recvID", recvID, "contentType", contentType, "msg", m) + return err } notificationOpt := ¬ificationOpt{} @@ -260,9 +274,11 @@ func (s *NotificationSender) NotificationWithSesstionType(ctx context.Context, s } else { log.ZError(ctx, "MsgClient Notification SendMsg failed", err, "req", &req) } + return err } +// Notification func (s *NotificationSender) Notification(ctx context.Context, sendID, recvID string, contentType int32, m proto.Message, opts ...NotificationOptions) error { return s.NotificationWithSesstionType(ctx, sendID, recvID, contentType, s.sessionTypeConf[contentType], m, opts...) } diff --git a/pkg/rpcclient/notification/common.go b/pkg/rpcclient/notification/common.go index 09d8b8798..d595f836b 100644 --- a/pkg/rpcclient/notification/common.go +++ b/pkg/rpcclient/notification/common.go @@ -14,6 +14,7 @@ package notification +// CommonUser type CommonUser interface { GetNickname() string GetFaceURL() string @@ -21,6 +22,7 @@ type CommonUser interface { GetEx() string } +// CommonGroup type CommonGroup interface { GetNickname() string GetFaceURL() string diff --git a/pkg/rpcclient/notification/conevrsation.go b/pkg/rpcclient/notification/conevrsation.go index d2995df3d..963012009 100644 --- a/pkg/rpcclient/notification/conevrsation.go +++ b/pkg/rpcclient/notification/conevrsation.go @@ -22,15 +22,17 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient" ) +// ConversationNotificationSender type ConversationNotificationSender struct { *rpcclient.NotificationSender } +// NewConversationNotificationSender func NewConversationNotificationSender(msgRpcClient *rpcclient.MessageRpcClient) *ConversationNotificationSender { return &ConversationNotificationSender{rpcclient.NewNotificationSender(rpcclient.WithRpcClient(msgRpcClient))} } -// SetPrivate调用. +// ConversationSetPrivateNotification func (c *ConversationNotificationSender) ConversationSetPrivateNotification( ctx context.Context, sendID, recvID string, @@ -41,18 +43,20 @@ func (c *ConversationNotificationSender) ConversationSetPrivateNotification( SendID: sendID, IsPrivate: isPrivateChat, } + return c.Notification(ctx, sendID, recvID, constant.ConversationPrivateChatNotification, tips) } -// 会话改变. +// ConversationChangeNotification func (c *ConversationNotificationSender) ConversationChangeNotification(ctx context.Context, userID string) error { tips := &sdkws.ConversationUpdateTips{ UserID: userID, } + return c.Notification(ctx, userID, userID, constant.ConversationChangeNotification, tips) } -// 会话未读数同步. +// ConversationUnreadChangeNotification func (c *ConversationNotificationSender) ConversationUnreadChangeNotification( ctx context.Context, userID, conversationID string, @@ -64,5 +68,6 @@ func (c *ConversationNotificationSender) ConversationUnreadChangeNotification( HasReadSeq: hasReadSeq, UnreadCountTime: unreadCountTime, } + return c.Notification(ctx, userID, userID, constant.ConversationUnreadNotification, tips) } diff --git a/pkg/rpcclient/notification/friend.go b/pkg/rpcclient/notification/friend.go index e7df2e6cd..496377a00 100644 --- a/pkg/rpcclient/notification/friend.go +++ b/pkg/rpcclient/notification/friend.go @@ -28,9 +28,10 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient" ) +// FriendNotificationSender type FriendNotificationSender struct { *rpcclient.NotificationSender - // 找不到报错 + // if not finded, return err getUsersInfo func(ctx context.Context, userIDs []string) ([]CommonUser, error) // db controller db controller.FriendDatabase @@ -38,12 +39,14 @@ type FriendNotificationSender struct { type friendNotificationSenderOptions func(*FriendNotificationSender) +// WithFriendDB func WithFriendDB(db controller.FriendDatabase) friendNotificationSenderOptions { return func(s *FriendNotificationSender) { s.db = db } } +// WithDBFunc func WithDBFunc( fn func(ctx context.Context, userIDs []string) (users []*relationTb.UserModel, err error), ) friendNotificationSenderOptions { @@ -56,12 +59,14 @@ func WithDBFunc( for _, user := range users { result = append(result, user) } + return result, nil } s.getUsersInfo = f } } +// WithRpcFunc func WithRpcFunc( fn func(ctx context.Context, userIDs []string) ([]*sdkws.UserInfo, error), ) friendNotificationSenderOptions { @@ -74,12 +79,14 @@ func WithRpcFunc( for _, user := range users { result = append(result, user) } + return result, err } s.getUsersInfo = f } } +// NewFriendNotificationSender func NewFriendNotificationSender( msgRpcClient *rpcclient.MessageRpcClient, opts ...friendNotificationSenderOptions, @@ -90,6 +97,7 @@ func NewFriendNotificationSender( for _, opt := range opts { opt(f) } + return f } @@ -105,6 +113,7 @@ func (f *FriendNotificationSender) getUsersInfoMap( for _, user := range users { result[user.GetUserID()] = user.(*sdkws.UserInfo) } + return result, nil } @@ -114,16 +123,20 @@ func (f *FriendNotificationSender) getFromToUserNickname( ) (string, string, error) { users, err := f.getUsersInfoMap(ctx, []string{fromUserID, toUserID}) if err != nil { - return "", "", nil + return "", "", err } + return users[fromUserID].Nickname, users[toUserID].Nickname, nil } +// UserInfoUpdatedNotification func (f *FriendNotificationSender) UserInfoUpdatedNotification(ctx context.Context, changedUserID string) error { tips := sdkws.UserInfoUpdatedTips{UserID: changedUserID} + return f.Notification(ctx, mcontext.GetOpUserID(ctx), changedUserID, constant.UserInfoUpdatedNotification, &tips) } +// FriendApplicationAddNotification func (f *FriendNotificationSender) FriendApplicationAddNotification( ctx context.Context, req *pbFriend.ApplyToAddFriendReq, @@ -132,9 +145,11 @@ func (f *FriendNotificationSender) FriendApplicationAddNotification( FromUserID: req.FromUserID, ToUserID: req.ToUserID, }} + return f.Notification(ctx, req.FromUserID, req.ToUserID, constant.FriendApplicationNotification, &tips) } +// FriendApplicationAgreedNotification func (c *FriendNotificationSender) FriendApplicationAgreedNotification( ctx context.Context, req *pbFriend.RespondFriendApplyReq, @@ -143,6 +158,7 @@ func (c *FriendNotificationSender) FriendApplicationAgreedNotification( FromUserID: req.FromUserID, ToUserID: req.ToUserID, }, HandleMsg: req.HandleMsg} + return c.Notification(ctx, req.ToUserID, req.FromUserID, constant.FriendApplicationApprovedNotification, &tips) } @@ -154,9 +170,11 @@ func (c *FriendNotificationSender) FriendApplicationRefusedNotification( FromUserID: req.FromUserID, ToUserID: req.ToUserID, }, HandleMsg: req.HandleMsg} + return c.Notification(ctx, req.ToUserID, req.FromUserID, constant.FriendApplicationRejectedNotification, &tips) } +// FriendAddedNotification func (c *FriendNotificationSender) FriendAddedNotification( ctx context.Context, operationID, opUserID, fromUserID, toUserID string, @@ -178,31 +196,39 @@ func (c *FriendNotificationSender) FriendAddedNotification( if err != nil { return err } + return c.Notification(ctx, fromUserID, toUserID, constant.FriendAddedNotification, &tips) } +// FriendDeletedNotification func (c *FriendNotificationSender) FriendDeletedNotification(ctx context.Context, req *pbFriend.DeleteFriendReq) error { tips := sdkws.FriendDeletedTips{FromToUserID: &sdkws.FromToUserID{ FromUserID: req.OwnerUserID, ToUserID: req.FriendUserID, }} + return c.Notification(ctx, req.OwnerUserID, req.FriendUserID, constant.FriendDeletedNotification, &tips) } +// FriendRemarkSetNotification func (c *FriendNotificationSender) FriendRemarkSetNotification(ctx context.Context, fromUserID, toUserID string) error { tips := sdkws.FriendInfoChangedTips{FromToUserID: &sdkws.FromToUserID{}} tips.FromToUserID.FromUserID = fromUserID tips.FromToUserID.ToUserID = toUserID + return c.Notification(ctx, fromUserID, toUserID, constant.FriendRemarkSetNotification, &tips) } +// BlackAddedNotification func (c *FriendNotificationSender) BlackAddedNotification(ctx context.Context, req *pbFriend.AddBlackReq) error { tips := sdkws.BlackAddedTips{FromToUserID: &sdkws.FromToUserID{}} tips.FromToUserID.FromUserID = req.OwnerUserID tips.FromToUserID.ToUserID = req.BlackUserID + return c.Notification(ctx, req.OwnerUserID, req.BlackUserID, constant.BlackAddedNotification, &tips) } +// BlackDeletedNotification func (c *FriendNotificationSender) BlackDeletedNotification(ctx context.Context, req *pbFriend.RemoveBlackReq) { blackDeletedTips := sdkws.BlackDeletedTips{FromToUserID: &sdkws.FromToUserID{ FromUserID: req.OwnerUserID, @@ -211,6 +237,7 @@ func (c *FriendNotificationSender) BlackDeletedNotification(ctx context.Context, c.Notification(ctx, req.OwnerUserID, req.BlackUserID, constant.BlackDeletedNotification, &blackDeletedTips) } +// FriendInfoUpdatedNotification func (c *FriendNotificationSender) FriendInfoUpdatedNotification( ctx context.Context, changedUserID string, diff --git a/pkg/rpcclient/notification/group.go b/pkg/rpcclient/notification/group.go index 22aa694c7..abdc4d76e 100644 --- a/pkg/rpcclient/notification/group.go +++ b/pkg/rpcclient/notification/group.go @@ -30,6 +30,7 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/utils" ) +// NewGroupNotificationSender func NewGroupNotificationSender( db controller.GroupDatabase, msgRpcClient *rpcclient.MessageRpcClient, @@ -43,6 +44,7 @@ func NewGroupNotificationSender( } } +// GroupNotificationSender type GroupNotificationSender struct { *rpcclient.NotificationSender getUsersInfo func(ctx context.Context, userIDs []string) ([]CommonUser, error) @@ -57,6 +59,7 @@ func (g *GroupNotificationSender) getUser(ctx context.Context, userID string) (* if len(users) == 0 { return nil, errs.ErrUserIDNotFound.Wrap(fmt.Sprintf("user %s not found", userID)) } + return &sdkws.PublicUserInfo{ UserID: users[0].GetUserID(), Nickname: users[0].GetNickname(), @@ -78,6 +81,7 @@ func (g *GroupNotificationSender) getGroupInfo(ctx context.Context, groupID stri if err != nil { return nil, err } + return &sdkws.GroupInfo{ GroupID: gm.GroupID, GroupName: gm.GroupName, @@ -122,7 +126,7 @@ func (g *GroupNotificationSender) getGroupMembers(ctx context.Context, groupID s res = append(res, g.groupMemberDB2PB(member, user.AppMangerLevel)) delete(users, member.UserID) } - //for userID, info := range users { + // for userID, info := range users { // if info.AppMangerLevel == constant.AppAdmin { // res = append(res, &sdkws.GroupMemberFullInfo{ // GroupID: groupID, @@ -132,7 +136,7 @@ func (g *GroupNotificationSender) getGroupMembers(ctx context.Context, groupID s // AppMangerLevel: info.AppMangerLevel, // }) // } - //} + // } return res, nil } @@ -145,6 +149,7 @@ func (g *GroupNotificationSender) getGroupMemberMap(ctx context.Context, groupID for i, member := range members { m[member.UserID] = members[i] } + return m, nil } @@ -156,6 +161,7 @@ func (g *GroupNotificationSender) getGroupMember(ctx context.Context, groupID st if len(members) == 0 { return nil, errs.ErrInternalServer.Wrap(fmt.Sprintf("group %s member %s not found", groupID, userID)) } + return members[0], nil } @@ -165,6 +171,7 @@ func (g *GroupNotificationSender) getGroupOwnerAndAdminUserID(ctx context.Contex return nil, err } fn := func(e *relation.GroupMemberModel) string { return e.UserID } + return utils.Slice(members, fn), nil } @@ -216,6 +223,7 @@ func (g *GroupNotificationSender) getUsersInfoMap(ctx context.Context, userIDs [ for _, user := range users { result[user.GetUserID()] = user.(*sdkws.UserInfo) } + return result, nil } @@ -255,37 +263,47 @@ func (g *GroupNotificationSender) fillOpUser(ctx context.Context, opUser **sdkws (*opUser).FaceURL = user.FaceURL } } + return nil } +// GroupCreatedNotification func (g *GroupNotificationSender) GroupCreatedNotification(ctx context.Context, tips *sdkws.GroupCreatedTips) (err error) { if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupCreatedNotification, tips) } +// GroupInfoSetNotification func (g *GroupNotificationSender) GroupInfoSetNotification(ctx context.Context, tips *sdkws.GroupInfoSetTips) (err error) { if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupInfoSetNotification, tips, rpcclient.WithRpcGetUserName()) } +// GroupInfoSetNameNotification func (g *GroupNotificationSender) GroupInfoSetNameNotification(ctx context.Context, tips *sdkws.GroupInfoSetNameTips) (err error) { if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupInfoSetNameNotification, tips) } +// GroupInfoSetAnnouncementNotification func (g *GroupNotificationSender) GroupInfoSetAnnouncementNotification(ctx context.Context, tips *sdkws.GroupInfoSetAnnouncementTips) (err error) { if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupInfoSetAnnouncementNotification, tips, rpcclient.WithRpcGetUserName()) } +// JoinGroupApplicationNotification func (g *GroupNotificationSender) JoinGroupApplicationNotification(ctx context.Context, req *pbGroup.JoinGroupReq) (err error) { group, err := g.getGroupInfo(ctx, req.GroupID) if err != nil { @@ -307,9 +325,11 @@ func (g *GroupNotificationSender) JoinGroupApplicationNotification(ctx context.C log.ZError(ctx, "JoinGroupApplicationNotification failed", err, "group", req.GroupID, "userID", userID) } } + return nil } +// MemberQuitNotification func (g *GroupNotificationSender) MemberQuitNotification(ctx context.Context, member *sdkws.GroupMemberFullInfo) (err error) { defer log.ZDebug(ctx, "return") defer func() { @@ -322,9 +342,11 @@ func (g *GroupNotificationSender) MemberQuitNotification(ctx context.Context, me return err } tips := &sdkws.MemberQuitTips{Group: group, QuitUser: member} + return g.Notification(ctx, mcontext.GetOpUserID(ctx), member.GroupID, constant.MemberQuitNotification, tips) } +// GroupApplicationAcceptedNotification func (g *GroupNotificationSender) GroupApplicationAcceptedNotification(ctx context.Context, req *pbGroup.GroupApplicationResponseReq) (err error) { defer log.ZDebug(ctx, "return") defer func() { @@ -350,9 +372,11 @@ func (g *GroupNotificationSender) GroupApplicationAcceptedNotification(ctx conte log.ZError(ctx, "failed", err) } } + return nil } +// GroupApplicationRejectedNotification func (g *GroupNotificationSender) GroupApplicationRejectedNotification(ctx context.Context, req *pbGroup.GroupApplicationResponseReq) (err error) { group, err := g.getGroupInfo(ctx, req.GroupID) if err != nil { @@ -372,9 +396,11 @@ func (g *GroupNotificationSender) GroupApplicationRejectedNotification(ctx conte log.ZError(ctx, "failed", err) } } + return nil } +// GroupOwnerTransferredNotification func (g *GroupNotificationSender) GroupOwnerTransferredNotification(ctx context.Context, req *pbGroup.TransferGroupOwnerReq) (err error) { group, err := g.getGroupInfo(ctx, req.GroupID) if err != nil { @@ -389,16 +415,20 @@ func (g *GroupNotificationSender) GroupOwnerTransferredNotification(ctx context. if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupOwnerTransferredNotification, tips) } +// MemberKickedNotification func (g *GroupNotificationSender) MemberKickedNotification(ctx context.Context, tips *sdkws.MemberKickedTips) (err error) { if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.MemberKickedNotification, tips) } +// MemberInvitedNotification func (g *GroupNotificationSender) MemberInvitedNotification(ctx context.Context, groupID, reason string, invitedUserIDList []string) (err error) { group, err := g.getGroupInfo(ctx, groupID) if err != nil { @@ -415,9 +445,11 @@ func (g *GroupNotificationSender) MemberInvitedNotification(ctx context.Context, if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.MemberInvitedNotification, tips) } +// MemberEnterNotification func (g *GroupNotificationSender) MemberEnterNotification(ctx context.Context, req *pbGroup.GroupApplicationResponseReq) (err error) { group, err := g.getGroupInfo(ctx, req.GroupID) if err != nil { @@ -435,9 +467,11 @@ func (g *GroupNotificationSender) GroupDismissedNotification(ctx context.Context if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupDismissedNotification, tips) } +// GroupMemberMutedNotification func (g *GroupNotificationSender) GroupMemberMutedNotification(ctx context.Context, groupID, groupMemberUserID string, mutedSeconds uint32) (err error) { group, err := g.getGroupInfo(ctx, groupID) if err != nil { @@ -454,6 +488,7 @@ func (g *GroupNotificationSender) GroupMemberMutedNotification(ctx context.Conte if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberMutedNotification, tips) } @@ -470,6 +505,7 @@ func (g *GroupNotificationSender) GroupMemberCancelMutedNotification(ctx context if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberCancelMutedNotification, tips) } @@ -489,6 +525,7 @@ func (g *GroupNotificationSender) GroupMutedNotification(ctx context.Context, gr if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMutedNotification, tips) } @@ -508,9 +545,11 @@ func (g *GroupNotificationSender) GroupCancelMutedNotification(ctx context.Conte if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupCancelMutedNotification, tips) } +// GroupMemberInfoSetNotification func (g *GroupNotificationSender) GroupMemberInfoSetNotification(ctx context.Context, groupID, groupMemberUserID string) (err error) { group, err := g.getGroupInfo(ctx, groupID) if err != nil { @@ -524,6 +563,7 @@ func (g *GroupNotificationSender) GroupMemberInfoSetNotification(ctx context.Con if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberInfoSetNotification, tips) } @@ -540,6 +580,7 @@ func (g *GroupNotificationSender) GroupMemberSetToAdminNotification(ctx context. if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberSetToAdminNotification, tips) } @@ -559,6 +600,7 @@ func (g *GroupNotificationSender) GroupMemberSetToOrdinaryUserNotification(ctx c return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberSetToOrdinaryUserNotification, tips) } +// MemberEnterDirectlyNotification func (g *GroupNotificationSender) MemberEnterDirectlyNotification(ctx context.Context, groupID string, entrantUserID string) (err error) { defer log.ZDebug(ctx, "return") defer func() { @@ -575,9 +617,11 @@ func (g *GroupNotificationSender) MemberEnterDirectlyNotification(ctx context.Co return err } tips := &sdkws.MemberEnterTips{Group: group, EntrantUser: user} + return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.MemberEnterNotification, tips) } +// SuperGroupNotification func (g *GroupNotificationSender) SuperGroupNotification(ctx context.Context, sendID, recvID string) (err error) { defer log.ZDebug(ctx, "return") defer func() { @@ -586,5 +630,6 @@ func (g *GroupNotificationSender) SuperGroupNotification(ctx context.Context, se } }() err = g.Notification(ctx, sendID, recvID, constant.SuperGroupUpdateNotification, nil) + return err } diff --git a/pkg/rpcclient/notification/msg.go b/pkg/rpcclient/notification/msg.go index bcc6865b1..ad708ce8b 100644 --- a/pkg/rpcclient/notification/msg.go +++ b/pkg/rpcclient/notification/msg.go @@ -22,23 +22,28 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient" ) +// MsgNotificationSender type MsgNotificationSender struct { *rpcclient.NotificationSender } +// NewMsgNotificationSender func NewMsgNotificationSender(opts ...rpcclient.NotificationSenderOptions) *MsgNotificationSender { return &MsgNotificationSender{rpcclient.NewNotificationSender(opts...)} } +// UserDeleteMsgsNotification func (m *MsgNotificationSender) UserDeleteMsgsNotification(ctx context.Context, userID, conversationID string, seqs []int64) error { tips := sdkws.DeleteMsgsTips{ UserID: userID, ConversationID: conversationID, Seqs: seqs, } + return m.Notification(ctx, userID, userID, constant.DeleteMsgsNotification, &tips) } +// MarkAsReadNotification func (m *MsgNotificationSender) MarkAsReadNotification(ctx context.Context, conversationID string, sesstionType int32, sendID, recvID string, seqs []int64, hasReadSeq int64) error { tips := &sdkws.MarkAsReadTips{ MarkAsReadUserID: sendID, @@ -46,5 +51,6 @@ func (m *MsgNotificationSender) MarkAsReadNotification(ctx context.Context, conv Seqs: seqs, HasReadSeq: hasReadSeq, } + return m.NotificationWithSesstionType(ctx, sendID, recvID, constant.HasReadReceipt, sesstionType, tips) } diff --git a/pkg/rpcclient/push.go b/pkg/rpcclient/push.go index 8e19782bd..62752901e 100644 --- a/pkg/rpcclient/push.go +++ b/pkg/rpcclient/push.go @@ -24,17 +24,20 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/push" ) +// Push type Push struct { conn grpc.ClientConnInterface Client push.PushMsgServiceClient discov discoveryregistry.SvcDiscoveryRegistry } +// NewPush func NewPush(discov discoveryregistry.SvcDiscoveryRegistry) *Push { conn, err := discov.GetConn(context.Background(), config.Config.RpcRegisterName.OpenImPushName) if err != nil { panic(err) } + return &Push{ discov: discov, conn: conn, @@ -42,12 +45,15 @@ func NewPush(discov discoveryregistry.SvcDiscoveryRegistry) *Push { } } +// PushRpcClient type PushRpcClient Push +// NewPushRpcClient func NewPushRpcClient(discov discoveryregistry.SvcDiscoveryRegistry) PushRpcClient { return PushRpcClient(*NewPush(discov)) } +// DelUserPushToken func (p *PushRpcClient) DelUserPushToken( ctx context.Context, req *push.DelUserPushTokenReq, diff --git a/pkg/rpcclient/third.go b/pkg/rpcclient/third.go index e1181b8f4..629234e7f 100644 --- a/pkg/rpcclient/third.go +++ b/pkg/rpcclient/third.go @@ -28,6 +28,7 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/third" ) +// Third type Third struct { conn grpc.ClientConnInterface Client third.ThirdClient @@ -35,20 +36,22 @@ type Third struct { MinioClient *minio.Client } +// NewThird func NewThird(discov discoveryregistry.SvcDiscoveryRegistry) *Third { + var minioClient *minio.Client conn, err := discov.GetConn(context.Background(), config.Config.RpcRegisterName.OpenImThirdName) if err != nil { panic(err) } client := third.NewThirdClient(conn) - minioClient, err := minioInit() + minioClient, err = minioInit() + return &Third{discov: discov, Client: client, conn: conn, MinioClient: minioClient} } func minioInit() (*minio.Client, error) { - minioClient := &minio.Client{} - var initUrl string - initUrl = config.Config.Object.Minio.Endpoint + var minioClient *minio.Client + initUrl := config.Config.Object.Minio.Endpoint minioUrl, err := url.Parse(initUrl) if err != nil { return nil, err @@ -66,5 +69,6 @@ func minioInit() (*minio.Client, error) { if err != nil { return nil, err } + return minioClient, nil } diff --git a/pkg/rpcclient/user.go b/pkg/rpcclient/user.go index 023c26d3c..0e92a3e96 100644 --- a/pkg/rpcclient/user.go +++ b/pkg/rpcclient/user.go @@ -29,32 +29,39 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/utils" ) +// User type User struct { conn grpc.ClientConnInterface Client user.UserClient Discov discoveryregistry.SvcDiscoveryRegistry } +// NewUser func NewUser(discov discoveryregistry.SvcDiscoveryRegistry) *User { conn, err := discov.GetConn(context.Background(), config.Config.RpcRegisterName.OpenImUserName) if err != nil { panic(err) } client := user.NewUserClient(conn) + return &User{Discov: discov, Client: client, conn: conn} } type UserRpcClient User +// NewUserRpcClientByUser func NewUserRpcClientByUser(user *User) *UserRpcClient { rpc := UserRpcClient(*user) + return &rpc } +// NewUserRpcClient func NewUserRpcClient(client discoveryregistry.SvcDiscoveryRegistry) UserRpcClient { return UserRpcClient(*NewUser(client)) } +// GetUsersInfo func (u *UserRpcClient) GetUsersInfo(ctx context.Context, userIDs []string) ([]*sdkws.UserInfo, error) { resp, err := u.Client.GetDesignateUsers(ctx, &user.GetDesignateUsersReq{ UserIDs: userIDs, @@ -67,27 +74,33 @@ func (u *UserRpcClient) GetUsersInfo(ctx context.Context, userIDs []string) ([]* })); len(ids) > 0 { return nil, errs.ErrUserIDNotFound.Wrap(strings.Join(ids, ",")) } + return resp.UsersInfo, nil } +// GetUserInfo func (u *UserRpcClient) GetUserInfo(ctx context.Context, userID string) (*sdkws.UserInfo, error) { users, err := u.GetUsersInfo(ctx, []string{userID}) if err != nil { return nil, err } + return users[0], nil } +// GetUsersInfoMap func (u *UserRpcClient) GetUsersInfoMap(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error) { users, err := u.GetUsersInfo(ctx, userIDs) if err != nil { return nil, err } + return utils.SliceToMap(users, func(e *sdkws.UserInfo) string { return e.UserID }), nil } +// GetPublicUserInfos func (u *UserRpcClient) GetPublicUserInfos( ctx context.Context, userIDs []string, @@ -97,6 +110,7 @@ func (u *UserRpcClient) GetPublicUserInfos( if err != nil { return nil, err } + return utils.Slice(users, func(e *sdkws.UserInfo) *sdkws.PublicUserInfo { return &sdkws.PublicUserInfo{ UserID: e.UserID, @@ -107,14 +121,17 @@ func (u *UserRpcClient) GetPublicUserInfos( }), nil } +// GetPublicUserInfo func (u *UserRpcClient) 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 } +// GetPublicUserInfoMap func (u *UserRpcClient) GetPublicUserInfoMap( ctx context.Context, userIDs []string, @@ -124,11 +141,13 @@ func (u *UserRpcClient) GetPublicUserInfoMap( if err != nil { return nil, err } + return utils.SliceToMap(users, func(e *sdkws.PublicUserInfo) string { return e.UserID }), nil } +// GetUserGlobalMsgRecvOpt func (u *UserRpcClient) GetUserGlobalMsgRecvOpt(ctx context.Context, userID string) (int32, error) { resp, err := u.Client.GetGlobalRecvMessageOpt(ctx, &user.GetGlobalRecvMessageOptReq{ UserID: userID, @@ -136,21 +155,26 @@ func (u *UserRpcClient) GetUserGlobalMsgRecvOpt(ctx context.Context, userID stri if err != nil { return 0, err } + return resp.GlobalRecvMsgOpt, err } +// Access func (u *UserRpcClient) Access(ctx context.Context, ownerUserID string) error { _, err := u.GetUserInfo(ctx, ownerUserID) if err != nil { return err } + return tokenverify.CheckAccessV3(ctx, ownerUserID) } +// GetAllUserIDs func (u *UserRpcClient) GetAllUserIDs(ctx context.Context, pageNumber, showNumber int32) ([]string, error) { resp, err := u.Client.GetAllUserID(ctx, &user.GetAllUserIDReq{Pagination: &sdkws.RequestPagination{PageNumber: pageNumber, ShowNumber: showNumber}}) if err != nil { return nil, err } + return resp.UserIDs, nil } diff --git a/pkg/startrpc/start.go b/pkg/startrpc/start.go index 3eeaaa3a2..ef207cf56 100644 --- a/pkg/startrpc/start.go +++ b/pkg/startrpc/start.go @@ -34,6 +34,7 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/utils" ) +// Start func Start( rpcPort int, rpcRegisterName string, @@ -108,5 +109,6 @@ func Start( } } }() + return utils.Wrap1(srv.Serve(listener)) } diff --git a/pkg/statistics/statistics.go b/pkg/statistics/statistics.go index 2a6ae01ae..8c1828380 100644 --- a/pkg/statistics/statistics.go +++ b/pkg/statistics/statistics.go @@ -21,6 +21,7 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/common/log" ) +// Statistics num type Statistics struct { AllCount *uint64 ModuleName string @@ -34,10 +35,12 @@ func (s *Statistics) output() { defer t.Stop() var sum uint64 var timeIntervalNum uint64 + outputCh := make(chan struct{}) for { sum = *s.AllCount select { case <-t.C: + outputCh <- struct{}{} } if *s.AllCount-sum <= 0 { intervalCount = 0 @@ -63,8 +66,10 @@ func (s *Statistics) output() { } } +// NewStatistics func NewStatistics(allCount *uint64, moduleName, printArgs string, sleepTime int) *Statistics { p := &Statistics{AllCount: allCount, ModuleName: moduleName, SleepTime: uint64(sleepTime), PrintArgs: printArgs} go p.output() + return p } From feb813b9ed0e845f205df2af14d18328d449790a Mon Sep 17 00:00:00 2001 From: BanTanger Date: Sun, 23 Jul 2023 02:51:16 +0000 Subject: [PATCH 38/62] cicd: robot automated Change Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- go.mod | 1 - go.sum | 2 - internal/api/msg.go | 1 - internal/msggateway/hub_server.go | 1 + internal/rpc/msg/send.go | 1 + pkg/apistruct/manage.go | 2 +- pkg/proto/auth/auth.pb.go | 17 +- pkg/proto/conversation/conversation.pb.go | 78 ++--- pkg/proto/errinfo/errinfo.pb.go | 11 +- pkg/proto/friend/friend.pb.go | 44 +-- pkg/proto/group/group.pb.go | 100 +++--- pkg/proto/msg/msg.pb.go | 146 ++++---- pkg/proto/msggateway/msggateway.pb.go | 48 +-- pkg/proto/push/push.pb.go | 12 +- pkg/proto/sdkws/sdkws.pb.go | 396 +++++++++++----------- pkg/proto/statistics/statistics.pb.go | 3 +- pkg/proto/third/third.pb.go | 65 ++-- pkg/proto/user/user.pb.go | 54 +-- pkg/proto/wrapperspb/wrapperspb.pb.go | 5 +- 19 files changed, 503 insertions(+), 484 deletions(-) diff --git a/go.mod b/go.mod index 21e6e2241..9fcf500a5 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,6 @@ require ( github.com/robfig/cron/v3 v3.0.1 github.com/sirupsen/logrus v1.9.2 // indirect github.com/stretchr/testify v1.8.3 - github.com/tencentyun/qcloud-cos-sts-sdk v0.0.0-20210325043845-84a0811633ca go.mongodb.org/mongo-driver v1.8.3 golang.org/x/image v0.3.0 google.golang.org/api v0.114.0 diff --git a/go.sum b/go.sum index e95d2e81e..9acc8ff8f 100644 --- a/go.sum +++ b/go.sum @@ -426,8 +426,6 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.194/go.mod github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.194/go.mod h1:yrBKWhChnDqNz1xuXdSbWXG56XawEq0G5j1lg4VwBD4= github.com/tencentyun/cos-go-sdk-v5 v0.7.41 h1:iU0Li/Np78H4SBna0ECQoF3mpgi6ImLXU+doGzPFXGc= github.com/tencentyun/cos-go-sdk-v5 v0.7.41/go.mod h1:4dCEtLHGh8QPxHEkgq+nFaky7yZxQuYwgSJM87icDaw= -github.com/tencentyun/qcloud-cos-sts-sdk v0.0.0-20210325043845-84a0811633ca h1:G/aIr3WiUesWHL2YGYgEqjM5tCAJ43Ml+0C18wDkWWs= -github.com/tencentyun/qcloud-cos-sts-sdk v0.0.0-20210325043845-84a0811633ca/go.mod h1:b18KQa4IxHbxeseW1GcZox53d7J0z39VNONTxvvlkXw= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= diff --git a/internal/api/msg.go b/internal/api/msg.go index 8ad7943e9..41ab4dc48 100644 --- a/internal/api/msg.go +++ b/internal/api/msg.go @@ -250,7 +250,6 @@ func (m *MessageApi) BatchSendMsg(c *gin.Context) { return } - var recvIDs []string var err error if req.IsSendAll { diff --git a/internal/msggateway/hub_server.go b/internal/msggateway/hub_server.go index deb8c3d77..4e1586969 100644 --- a/internal/msggateway/hub_server.go +++ b/internal/msggateway/hub_server.go @@ -16,6 +16,7 @@ package msggateway import ( "context" + "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify" "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" diff --git a/internal/rpc/msg/send.go b/internal/rpc/msg/send.go index dd02083fa..a568154c7 100644 --- a/internal/rpc/msg/send.go +++ b/internal/rpc/msg/send.go @@ -16,6 +16,7 @@ package msg import ( "context" + "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/log" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext" diff --git a/pkg/apistruct/manage.go b/pkg/apistruct/manage.go index 6a92f40aa..d3c24d544 100644 --- a/pkg/apistruct/manage.go +++ b/pkg/apistruct/manage.go @@ -33,7 +33,7 @@ type SendMsg struct { } type SendMsgReq struct { - RecvID string `json:"recvID" binding:"required_if" message:"recvID is required if sessionType is SingleChatType or NotificationChatType"` + RecvID string `json:"recvID" binding:"required_if" message:"recvID is required if sessionType is SingleChatType or NotificationChatType"` SendMsg } diff --git a/pkg/proto/auth/auth.pb.go b/pkg/proto/auth/auth.pb.go index 2d1e0493c..238d12975 100644 --- a/pkg/proto/auth/auth.pb.go +++ b/pkg/proto/auth/auth.pb.go @@ -22,13 +22,14 @@ package auth import ( context "context" + reflect "reflect" + sync "sync" + grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" ) const ( @@ -43,9 +44,9 @@ type UserTokenReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Secret string `protobuf:"bytes,1,opt,name=secret,proto3" json:"secret"` + Secret string `protobuf:"bytes,1,opt,name=secret,proto3" json:"secret"` PlatformID int32 `protobuf:"varint,2,opt,name=platformID,proto3" json:"platformID"` - UserID string `protobuf:"bytes,3,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,3,opt,name=userID,proto3" json:"userID"` } func (x *UserTokenReq) Reset() { @@ -106,7 +107,7 @@ type UserTokenResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token"` + Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token"` ExpireTimeSeconds int64 `protobuf:"varint,3,opt,name=expireTimeSeconds,proto3" json:"expireTimeSeconds"` } @@ -162,7 +163,7 @@ type ForceLogoutReq struct { unknownFields protoimpl.UnknownFields PlatformID int32 `protobuf:"varint,1,opt,name=platformID,proto3" json:"platformID"` - UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` } func (x *ForceLogoutReq) Reset() { @@ -301,8 +302,8 @@ type ParseTokenResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` - Platform string `protobuf:"bytes,2,opt,name=platform,proto3" json:"platform"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + Platform string `protobuf:"bytes,2,opt,name=platform,proto3" json:"platform"` ExpireTimeSeconds int64 `protobuf:"varint,4,opt,name=expireTimeSeconds,proto3" json:"expireTimeSeconds"` } diff --git a/pkg/proto/conversation/conversation.pb.go b/pkg/proto/conversation/conversation.pb.go index cf5de48a7..568948379 100644 --- a/pkg/proto/conversation/conversation.pb.go +++ b/pkg/proto/conversation/conversation.pb.go @@ -22,14 +22,16 @@ package conversation import ( context "context" - wrapperspb "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb" + reflect "reflect" + sync "sync" + grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" + + wrapperspb "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb" ) const ( @@ -44,23 +46,23 @@ type Conversation struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` - ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` - RecvMsgOpt int32 `protobuf:"varint,3,opt,name=recvMsgOpt,proto3" json:"recvMsgOpt"` - ConversationType int32 `protobuf:"varint,4,opt,name=conversationType,proto3" json:"conversationType"` - UserID string `protobuf:"bytes,5,opt,name=userID,proto3" json:"userID"` - GroupID string `protobuf:"bytes,6,opt,name=groupID,proto3" json:"groupID"` - IsPinned bool `protobuf:"varint,7,opt,name=isPinned,proto3" json:"isPinned"` - AttachedInfo string `protobuf:"bytes,8,opt,name=attachedInfo,proto3" json:"attachedInfo"` - IsPrivateChat bool `protobuf:"varint,9,opt,name=isPrivateChat,proto3" json:"isPrivateChat"` - GroupAtType int32 `protobuf:"varint,10,opt,name=groupAtType,proto3" json:"groupAtType"` - Ex string `protobuf:"bytes,11,opt,name=ex,proto3" json:"ex"` - BurnDuration int32 `protobuf:"varint,12,opt,name=burnDuration,proto3" json:"burnDuration"` - MinSeq int64 `protobuf:"varint,13,opt,name=minSeq,proto3" json:"minSeq"` - MaxSeq int64 `protobuf:"varint,14,opt,name=maxSeq,proto3" json:"maxSeq"` - MsgDestructTime int64 `protobuf:"varint,15,opt,name=msgDestructTime,proto3" json:"msgDestructTime"` + OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` + ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` + RecvMsgOpt int32 `protobuf:"varint,3,opt,name=recvMsgOpt,proto3" json:"recvMsgOpt"` + ConversationType int32 `protobuf:"varint,4,opt,name=conversationType,proto3" json:"conversationType"` + UserID string `protobuf:"bytes,5,opt,name=userID,proto3" json:"userID"` + GroupID string `protobuf:"bytes,6,opt,name=groupID,proto3" json:"groupID"` + IsPinned bool `protobuf:"varint,7,opt,name=isPinned,proto3" json:"isPinned"` + AttachedInfo string `protobuf:"bytes,8,opt,name=attachedInfo,proto3" json:"attachedInfo"` + IsPrivateChat bool `protobuf:"varint,9,opt,name=isPrivateChat,proto3" json:"isPrivateChat"` + GroupAtType int32 `protobuf:"varint,10,opt,name=groupAtType,proto3" json:"groupAtType"` + Ex string `protobuf:"bytes,11,opt,name=ex,proto3" json:"ex"` + BurnDuration int32 `protobuf:"varint,12,opt,name=burnDuration,proto3" json:"burnDuration"` + MinSeq int64 `protobuf:"varint,13,opt,name=minSeq,proto3" json:"minSeq"` + MaxSeq int64 `protobuf:"varint,14,opt,name=maxSeq,proto3" json:"maxSeq"` + MsgDestructTime int64 `protobuf:"varint,15,opt,name=msgDestructTime,proto3" json:"msgDestructTime"` LatestMsgDestructTime int64 `protobuf:"varint,16,opt,name=latestMsgDestructTime,proto3" json:"latestMsgDestructTime"` - IsMsgDestruct bool `protobuf:"varint,17,opt,name=isMsgDestruct,proto3" json:"isMsgDestruct"` + IsMsgDestruct bool `protobuf:"varint,17,opt,name=isMsgDestruct,proto3" json:"isMsgDestruct"` } func (x *Conversation) Reset() { @@ -219,21 +221,21 @@ type ConversationReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` + ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` ConversationType int32 `protobuf:"varint,2,opt,name=conversationType,proto3" json:"conversationType"` - UserID string `protobuf:"bytes,3,opt,name=userID,proto3" json:"userID"` - GroupID string `protobuf:"bytes,4,opt,name=groupID,proto3" json:"groupID"` - RecvMsgOpt *wrapperspb.Int32Value `protobuf:"bytes,5,opt,name=recvMsgOpt,proto3" json:"recvMsgOpt"` - IsPinned *wrapperspb.BoolValue `protobuf:"bytes,6,opt,name=isPinned,proto3" json:"isPinned"` - AttachedInfo *wrapperspb.StringValue `protobuf:"bytes,7,opt,name=attachedInfo,proto3" json:"attachedInfo"` - IsPrivateChat *wrapperspb.BoolValue `protobuf:"bytes,8,opt,name=isPrivateChat,proto3" json:"isPrivateChat"` - Ex *wrapperspb.StringValue `protobuf:"bytes,9,opt,name=ex,proto3" json:"ex"` - BurnDuration *wrapperspb.Int32Value `protobuf:"bytes,10,opt,name=burnDuration,proto3" json:"burnDuration"` - MinSeq *wrapperspb.Int64Value `protobuf:"bytes,11,opt,name=minSeq,proto3" json:"minSeq"` - MaxSeq *wrapperspb.Int64Value `protobuf:"bytes,12,opt,name=maxSeq,proto3" json:"maxSeq"` - GroupAtType *wrapperspb.Int32Value `protobuf:"bytes,13,opt,name=groupAtType,proto3" json:"groupAtType"` - MsgDestructTime *wrapperspb.Int64Value `protobuf:"bytes,14,opt,name=msgDestructTime,proto3" json:"msgDestructTime"` - IsMsgDestruct *wrapperspb.BoolValue `protobuf:"bytes,15,opt,name=isMsgDestruct,proto3" json:"isMsgDestruct"` + UserID string `protobuf:"bytes,3,opt,name=userID,proto3" json:"userID"` + GroupID string `protobuf:"bytes,4,opt,name=groupID,proto3" json:"groupID"` + RecvMsgOpt *wrapperspb.Int32Value `protobuf:"bytes,5,opt,name=recvMsgOpt,proto3" json:"recvMsgOpt"` + IsPinned *wrapperspb.BoolValue `protobuf:"bytes,6,opt,name=isPinned,proto3" json:"isPinned"` + AttachedInfo *wrapperspb.StringValue `protobuf:"bytes,7,opt,name=attachedInfo,proto3" json:"attachedInfo"` + IsPrivateChat *wrapperspb.BoolValue `protobuf:"bytes,8,opt,name=isPrivateChat,proto3" json:"isPrivateChat"` + Ex *wrapperspb.StringValue `protobuf:"bytes,9,opt,name=ex,proto3" json:"ex"` + BurnDuration *wrapperspb.Int32Value `protobuf:"bytes,10,opt,name=burnDuration,proto3" json:"burnDuration"` + MinSeq *wrapperspb.Int64Value `protobuf:"bytes,11,opt,name=minSeq,proto3" json:"minSeq"` + MaxSeq *wrapperspb.Int64Value `protobuf:"bytes,12,opt,name=maxSeq,proto3" json:"maxSeq"` + GroupAtType *wrapperspb.Int32Value `protobuf:"bytes,13,opt,name=groupAtType,proto3" json:"groupAtType"` + MsgDestructTime *wrapperspb.Int64Value `protobuf:"bytes,14,opt,name=msgDestructTime,proto3" json:"msgDestructTime"` + IsMsgDestruct *wrapperspb.BoolValue `protobuf:"bytes,15,opt,name=isMsgDestruct,proto3" json:"isMsgDestruct"` } func (x *ConversationReq) Reset() { @@ -464,7 +466,7 @@ type GetConversationReq struct { unknownFields protoimpl.UnknownFields ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` - OwnerUserID string `protobuf:"bytes,2,opt,name=ownerUserID,proto3" json:"ownerUserID"` + OwnerUserID string `protobuf:"bytes,2,opt,name=ownerUserID,proto3" json:"ownerUserID"` } func (x *GetConversationReq) Reset() { @@ -565,7 +567,7 @@ type GetConversationsReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` + OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` ConversationIDs []string `protobuf:"bytes,2,rep,name=conversationIDs,proto3" json:"conversationIDs"` } @@ -1042,8 +1044,8 @@ type SetConversationMaxSeqReq struct { unknownFields protoimpl.UnknownFields ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` - OwnerUserID []string `protobuf:"bytes,2,rep,name=ownerUserID,proto3" json:"ownerUserID"` - MaxSeq int64 `protobuf:"varint,3,opt,name=maxSeq,proto3" json:"maxSeq"` + OwnerUserID []string `protobuf:"bytes,2,rep,name=ownerUserID,proto3" json:"ownerUserID"` + MaxSeq int64 `protobuf:"varint,3,opt,name=maxSeq,proto3" json:"maxSeq"` } func (x *SetConversationMaxSeqReq) Reset() { @@ -1236,7 +1238,7 @@ type SetConversationsReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserIDs []string `protobuf:"bytes,1,rep,name=userIDs,proto3" json:"userIDs"` + UserIDs []string `protobuf:"bytes,1,rep,name=userIDs,proto3" json:"userIDs"` Conversation *ConversationReq `protobuf:"bytes,2,opt,name=conversation,proto3" json:"conversation"` } diff --git a/pkg/proto/errinfo/errinfo.pb.go b/pkg/proto/errinfo/errinfo.pb.go index 44f906d86..1beca5842 100644 --- a/pkg/proto/errinfo/errinfo.pb.go +++ b/pkg/proto/errinfo/errinfo.pb.go @@ -21,10 +21,11 @@ package errinfo import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( @@ -39,11 +40,11 @@ type ErrorInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path"` + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path"` Line uint32 `protobuf:"varint,2,opt,name=line,proto3" json:"line"` - Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name"` Cause string `protobuf:"bytes,4,opt,name=cause,proto3" json:"cause"` - Warp []string `protobuf:"bytes,5,rep,name=warp,proto3" json:"warp"` + Warp []string `protobuf:"bytes,5,rep,name=warp,proto3" json:"warp"` } func (x *ErrorInfo) Reset() { diff --git a/pkg/proto/friend/friend.pb.go b/pkg/proto/friend/friend.pb.go index 5745fcd3c..7439a475a 100644 --- a/pkg/proto/friend/friend.pb.go +++ b/pkg/proto/friend/friend.pb.go @@ -22,14 +22,16 @@ package friend import ( context "context" - sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" + reflect "reflect" + sync "sync" + grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" + + sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" ) const ( @@ -45,7 +47,7 @@ type GetPaginationFriendsReq struct { unknownFields protoimpl.UnknownFields Pagination *sdkws.RequestPagination `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination"` - UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` } func (x *GetPaginationFriendsReq) Reset() { @@ -100,7 +102,7 @@ type GetPaginationFriendsResp struct { unknownFields protoimpl.UnknownFields FriendsInfo []*sdkws.FriendInfo `protobuf:"bytes,1,rep,name=friendsInfo,proto3" json:"friendsInfo"` - Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total"` + Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total"` } func (x *GetPaginationFriendsResp) Reset() { @@ -155,9 +157,9 @@ type ApplyToAddFriendReq struct { unknownFields protoimpl.UnknownFields FromUserID string `protobuf:"bytes,1,opt,name=fromUserID,proto3" json:"fromUserID"` - ToUserID string `protobuf:"bytes,2,opt,name=toUserID,proto3" json:"toUserID"` - ReqMsg string `protobuf:"bytes,3,opt,name=reqMsg,proto3" json:"reqMsg"` - Ex string `protobuf:"bytes,4,opt,name=ex,proto3" json:"ex"` + ToUserID string `protobuf:"bytes,2,opt,name=toUserID,proto3" json:"toUserID"` + ReqMsg string `protobuf:"bytes,3,opt,name=reqMsg,proto3" json:"reqMsg"` + Ex string `protobuf:"bytes,4,opt,name=ex,proto3" json:"ex"` } func (x *ApplyToAddFriendReq) Reset() { @@ -263,7 +265,7 @@ type ImportFriendReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` + OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` FriendUserIDs []string `protobuf:"bytes,2,rep,name=friendUserIDs,proto3" json:"friendUserIDs"` } @@ -356,7 +358,7 @@ type GetPaginationFriendsApplyToReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` Pagination *sdkws.RequestPagination `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination"` } @@ -412,7 +414,7 @@ type GetPaginationFriendsApplyToResp struct { unknownFields protoimpl.UnknownFields FriendRequests []*sdkws.FriendRequest `protobuf:"bytes,1,rep,name=FriendRequests,proto3" json:"FriendRequests"` - Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total"` + Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total"` } func (x *GetPaginationFriendsApplyToResp) Reset() { @@ -466,7 +468,7 @@ type GetDesignatedFriendsReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` + OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` FriendUserIDs []string `protobuf:"bytes,2,rep,name=friendUserIDs,proto3" json:"friendUserIDs"` } @@ -754,7 +756,7 @@ type GetPaginationBlacksReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` Pagination *sdkws.RequestPagination `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination"` } @@ -1084,7 +1086,7 @@ type DeleteFriendReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` + OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` FriendUserID string `protobuf:"bytes,2,opt,name=friendUserID,proto3" json:"friendUserID"` } @@ -1178,10 +1180,10 @@ type RespondFriendApplyReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - FromUserID string `protobuf:"bytes,1,opt,name=fromUserID,proto3" json:"fromUserID"` //主动发起的申请者 - ToUserID string `protobuf:"bytes,2,opt,name=toUserID,proto3" json:"toUserID"` //被动添加者 + FromUserID string `protobuf:"bytes,1,opt,name=fromUserID,proto3" json:"fromUserID"` //主动发起的申请者 + ToUserID string `protobuf:"bytes,2,opt,name=toUserID,proto3" json:"toUserID"` //被动添加者 HandleResult int32 `protobuf:"varint,3,opt,name=handleResult,proto3" json:"handleResult"` - HandleMsg string `protobuf:"bytes,4,opt,name=handleMsg,proto3" json:"handleMsg"` + HandleMsg string `protobuf:"bytes,4,opt,name=handleMsg,proto3" json:"handleMsg"` } func (x *RespondFriendApplyReq) Reset() { @@ -1287,9 +1289,9 @@ type SetFriendRemarkReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` + OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` FriendUserID string `protobuf:"bytes,2,opt,name=friendUserID,proto3" json:"friendUserID"` - Remark string `protobuf:"bytes,3,opt,name=remark,proto3" json:"remark"` + Remark string `protobuf:"bytes,3,opt,name=remark,proto3" json:"remark"` } func (x *SetFriendRemarkReq) Reset() { @@ -1388,7 +1390,7 @@ type GetPaginationFriendsApplyFromReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` Pagination *sdkws.RequestPagination `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination"` } @@ -1444,7 +1446,7 @@ type GetPaginationFriendsApplyFromResp struct { unknownFields protoimpl.UnknownFields FriendRequests []*sdkws.FriendRequest `protobuf:"bytes,1,rep,name=friendRequests,proto3" json:"friendRequests"` - Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total"` + Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total"` } func (x *GetPaginationFriendsApplyFromResp) Reset() { diff --git a/pkg/proto/group/group.pb.go b/pkg/proto/group/group.pb.go index f4230c794..32261fc7c 100644 --- a/pkg/proto/group/group.pb.go +++ b/pkg/proto/group/group.pb.go @@ -22,15 +22,17 @@ package group import ( context "context" - sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" - wrapperspb "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb" + reflect "reflect" + sync "sync" + grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" + + sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" + wrapperspb "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb" ) const ( @@ -46,9 +48,9 @@ type CreateGroupReq struct { unknownFields protoimpl.UnknownFields MemberUserIDs []string `protobuf:"bytes,1,rep,name=memberUserIDs,proto3" json:"memberUserIDs"` - GroupInfo *sdkws.GroupInfo `protobuf:"bytes,2,opt,name=groupInfo,proto3" json:"groupInfo"` - AdminUserIDs []string `protobuf:"bytes,3,rep,name=adminUserIDs,proto3" json:"adminUserIDs"` - OwnerUserID string `protobuf:"bytes,4,opt,name=ownerUserID,proto3" json:"ownerUserID"` //owner + GroupInfo *sdkws.GroupInfo `protobuf:"bytes,2,opt,name=groupInfo,proto3" json:"groupInfo"` + AdminUserIDs []string `protobuf:"bytes,3,rep,name=adminUserIDs,proto3" json:"adminUserIDs"` + OwnerUserID string `protobuf:"bytes,4,opt,name=ownerUserID,proto3" json:"ownerUserID"` //owner } func (x *CreateGroupReq) Reset() { @@ -397,7 +399,7 @@ type GetGroupApplicationListResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` + Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` GroupRequests []*sdkws.GroupRequest `protobuf:"bytes,2,rep,name=groupRequests,proto3" json:"groupRequests"` } @@ -453,7 +455,7 @@ type GetUserReqApplicationListReq struct { unknownFields protoimpl.UnknownFields Pagination *sdkws.RequestPagination `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination"` - UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` } func (x *GetUserReqApplicationListReq) Reset() { @@ -507,7 +509,7 @@ type GetUserReqApplicationListResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` + Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` GroupRequests []*sdkws.GroupRequest `protobuf:"bytes,2,rep,name=groupRequests,proto3" json:"groupRequests"` } @@ -562,7 +564,7 @@ type TransferGroupOwnerReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` OldOwnerUserID string `protobuf:"bytes,2,opt,name=oldOwnerUserID,proto3" json:"oldOwnerUserID"` NewOwnerUserID string `protobuf:"bytes,3,opt,name=newOwnerUserID,proto3" json:"newOwnerUserID"` } @@ -663,9 +665,9 @@ type JoinGroupReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` - ReqMessage string `protobuf:"bytes,2,opt,name=reqMessage,proto3" json:"reqMessage"` - JoinSource int32 `protobuf:"varint,3,opt,name=joinSource,proto3" json:"joinSource"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + ReqMessage string `protobuf:"bytes,2,opt,name=reqMessage,proto3" json:"reqMessage"` + JoinSource int32 `protobuf:"varint,3,opt,name=joinSource,proto3" json:"joinSource"` InviterUserID string `protobuf:"bytes,4,opt,name=inviterUserID,proto3" json:"inviterUserID"` } @@ -772,9 +774,9 @@ type GroupApplicationResponseReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` - FromUserID string `protobuf:"bytes,2,opt,name=fromUserID,proto3" json:"fromUserID"` // - HandledMsg string `protobuf:"bytes,3,opt,name=handledMsg,proto3" json:"handledMsg"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + FromUserID string `protobuf:"bytes,2,opt,name=fromUserID,proto3" json:"fromUserID"` // + HandledMsg string `protobuf:"bytes,3,opt,name=handledMsg,proto3" json:"handledMsg"` HandleResult int32 `protobuf:"varint,4,opt,name=handleResult,proto3" json:"handleResult"` } @@ -967,8 +969,8 @@ type GetGroupMemberListReq struct { unknownFields protoimpl.UnknownFields Pagination *sdkws.RequestPagination `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination"` - GroupID string `protobuf:"bytes,2,opt,name=groupID,proto3" json:"groupID"` - Filter int32 `protobuf:"varint,3,opt,name=filter,proto3" json:"filter"` + GroupID string `protobuf:"bytes,2,opt,name=groupID,proto3" json:"groupID"` + Filter int32 `protobuf:"varint,3,opt,name=filter,proto3" json:"filter"` } func (x *GetGroupMemberListReq) Reset() { @@ -1029,7 +1031,7 @@ type GetGroupMemberListResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` + Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` Members []*sdkws.GroupMemberFullInfo `protobuf:"bytes,2,rep,name=members,proto3" json:"members"` } @@ -1186,9 +1188,9 @@ type KickGroupMemberReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` KickedUserIDs []string `protobuf:"bytes,2,rep,name=kickedUserIDs,proto3" json:"kickedUserIDs"` - Reason string `protobuf:"bytes,3,opt,name=reason,proto3" json:"reason"` + Reason string `protobuf:"bytes,3,opt,name=reason,proto3" json:"reason"` } func (x *KickGroupMemberReq) Reset() { @@ -1397,8 +1399,8 @@ type InviteUserToGroupReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` - Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason"` InvitedUserIDs []string `protobuf:"bytes,3,rep,name=invitedUserIDs,proto3" json:"invitedUserIDs"` } @@ -1499,7 +1501,7 @@ type GetGroupAllMemberReq struct { unknownFields protoimpl.UnknownFields Pagination *sdkws.RequestPagination `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination"` - GroupID string `protobuf:"bytes,2,opt,name=groupID,proto3" json:"groupID"` + GroupID string `protobuf:"bytes,2,opt,name=groupID,proto3" json:"groupID"` } func (x *GetGroupAllMemberReq) Reset() { @@ -1600,9 +1602,9 @@ type CMSGroup struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupInfo *sdkws.GroupInfo `protobuf:"bytes,1,opt,name=groupInfo,proto3" json:"groupInfo"` + GroupInfo *sdkws.GroupInfo `protobuf:"bytes,1,opt,name=groupInfo,proto3" json:"groupInfo"` GroupOwnerUserName string `protobuf:"bytes,2,opt,name=groupOwnerUserName,proto3" json:"groupOwnerUserName"` - GroupOwnerUserID string `protobuf:"bytes,3,opt,name=groupOwnerUserID,proto3" json:"groupOwnerUserID"` + GroupOwnerUserID string `protobuf:"bytes,3,opt,name=groupOwnerUserID,proto3" json:"groupOwnerUserID"` } func (x *CMSGroup) Reset() { @@ -1664,8 +1666,8 @@ type GetGroupsReq struct { unknownFields protoimpl.UnknownFields Pagination *sdkws.RequestPagination `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination"` - GroupName string `protobuf:"bytes,2,opt,name=groupName,proto3" json:"groupName"` - GroupID string `protobuf:"bytes,3,opt,name=groupID,proto3" json:"groupID"` + GroupName string `protobuf:"bytes,2,opt,name=groupName,proto3" json:"groupName"` + GroupID string `protobuf:"bytes,3,opt,name=groupID,proto3" json:"groupID"` } func (x *GetGroupsReq) Reset() { @@ -1829,8 +1831,8 @@ type GetGroupMembersCMSReq struct { unknownFields protoimpl.UnknownFields Pagination *sdkws.RequestPagination `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination"` - GroupID string `protobuf:"bytes,2,opt,name=groupID,proto3" json:"groupID"` - UserName string `protobuf:"bytes,3,opt,name=userName,proto3" json:"userName"` + GroupID string `protobuf:"bytes,2,opt,name=groupID,proto3" json:"groupID"` + UserName string `protobuf:"bytes,3,opt,name=userName,proto3" json:"userName"` } func (x *GetGroupMembersCMSReq) Reset() { @@ -1891,7 +1893,7 @@ type GetGroupMembersCMSResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` + Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` Members []*sdkws.GroupMemberFullInfo `protobuf:"bytes,2,rep,name=members,proto3" json:"members"` } @@ -1946,7 +1948,7 @@ type DismissGroupReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` DeleteMember bool `protobuf:"varint,2,opt,name=deleteMember,proto3" json:"deleteMember"` } @@ -2039,8 +2041,8 @@ type MuteGroupMemberReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` - UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` MutedSeconds uint32 `protobuf:"varint,3,opt,name=mutedSeconds,proto3" json:"mutedSeconds"` } @@ -2141,7 +2143,7 @@ type CancelMuteGroupMemberReq struct { unknownFields protoimpl.UnknownFields GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` - UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` } func (x *CancelMuteGroupMemberReq) Reset() { @@ -2591,12 +2593,12 @@ type SetGroupMemberInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` - UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` - Nickname *wrapperspb.StringValue `protobuf:"bytes,3,opt,name=nickname,proto3" json:"nickname"` - FaceURL *wrapperspb.StringValue `protobuf:"bytes,4,opt,name=faceURL,proto3" json:"faceURL"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` + Nickname *wrapperspb.StringValue `protobuf:"bytes,3,opt,name=nickname,proto3" json:"nickname"` + FaceURL *wrapperspb.StringValue `protobuf:"bytes,4,opt,name=faceURL,proto3" json:"faceURL"` RoleLevel *wrapperspb.Int32Value `protobuf:"bytes,5,opt,name=roleLevel,proto3" json:"roleLevel"` - Ex *wrapperspb.StringValue `protobuf:"bytes,6,opt,name=ex,proto3" json:"ex"` + Ex *wrapperspb.StringValue `protobuf:"bytes,6,opt,name=ex,proto3" json:"ex"` } func (x *SetGroupMemberInfo) Reset() { @@ -2810,8 +2812,8 @@ type GroupAbstractInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` - GroupMemberNumber uint32 `protobuf:"varint,2,opt,name=groupMemberNumber,proto3" json:"groupMemberNumber"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + GroupMemberNumber uint32 `protobuf:"varint,2,opt,name=groupMemberNumber,proto3" json:"groupMemberNumber"` GroupMemberListHash uint64 `protobuf:"varint,3,opt,name=groupMemberListHash,proto3" json:"groupMemberListHash"` } @@ -2920,7 +2922,7 @@ type GetUserInGroupMembersReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` GroupIDs []string `protobuf:"bytes,2,rep,name=groupIDs,proto3" json:"groupIDs"` } @@ -3116,7 +3118,7 @@ type GetGroupMemberRoleLevelReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` RoleLevels []int32 `protobuf:"varint,2,rep,packed,name=roleLevels,proto3" json:"roleLevels"` } @@ -3312,7 +3314,7 @@ type GetGroupMemberCacheReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` GroupMemberID string `protobuf:"bytes,2,opt,name=groupMemberID,proto3" json:"groupMemberID"` } @@ -3415,7 +3417,7 @@ type GroupCreateCountReq struct { unknownFields protoimpl.UnknownFields Start int64 `protobuf:"varint,1,opt,name=start,proto3" json:"start"` - End int64 `protobuf:"varint,2,opt,name=end,proto3" json:"end"` + End int64 `protobuf:"varint,2,opt,name=end,proto3" json:"end"` } func (x *GroupCreateCountReq) Reset() { @@ -3469,9 +3471,9 @@ type GroupCreateCountResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Total int64 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` + Total int64 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` Before int64 `protobuf:"varint,2,opt,name=before,proto3" json:"before"` - Count map[string]int64 `protobuf:"bytes,3,rep,name=count,proto3" json:"count" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + Count map[string]int64 `protobuf:"bytes,3,rep,name=count,proto3" json:"count" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` } func (x *GroupCreateCountResp) Reset() { diff --git a/pkg/proto/msg/msg.pb.go b/pkg/proto/msg/msg.pb.go index db1f019c2..01e8463bf 100644 --- a/pkg/proto/msg/msg.pb.go +++ b/pkg/proto/msg/msg.pb.go @@ -22,14 +22,16 @@ package msg import ( context "context" - sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" + reflect "reflect" + sync "sync" + grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" + + sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" ) const ( @@ -44,7 +46,7 @@ type MsgDataToMQ struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token"` + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token"` MsgData *sdkws.MsgData `protobuf:"bytes,2,opt,name=msgData,proto3" json:"msgData"` } @@ -146,7 +148,7 @@ type PushMsgDataToMQ struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - MsgData *sdkws.MsgData `protobuf:"bytes,1,opt,name=msgData,proto3" json:"msgData"` + MsgData *sdkws.MsgData `protobuf:"bytes,1,opt,name=msgData,proto3" json:"msgData"` ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` } @@ -201,9 +203,9 @@ type MsgDataToMongoByMQ struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - LastSeq int64 `protobuf:"varint,1,opt,name=lastSeq,proto3" json:"lastSeq"` + LastSeq int64 `protobuf:"varint,1,opt,name=lastSeq,proto3" json:"lastSeq"` ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` - MsgData []*sdkws.MsgData `protobuf:"bytes,3,rep,name=msgData,proto3" json:"msgData"` + MsgData []*sdkws.MsgData `protobuf:"bytes,3,rep,name=msgData,proto3" json:"msgData"` } func (x *MsgDataToMongoByMQ) Reset() { @@ -415,7 +417,7 @@ type SendMsgResp struct { ServerMsgID string `protobuf:"bytes,1,opt,name=serverMsgID,proto3" json:"serverMsgID"` ClientMsgID string `protobuf:"bytes,2,opt,name=clientMsgID,proto3" json:"clientMsgID"` - SendTime int64 `protobuf:"varint,3,opt,name=sendTime,proto3" json:"sendTime"` + SendTime int64 `protobuf:"varint,3,opt,name=sendTime,proto3" json:"sendTime"` } func (x *SendMsgResp) Reset() { @@ -646,7 +648,7 @@ type MsgDataToModifyByMQ struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Messages []*sdkws.MsgData `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages"` + Messages []*sdkws.MsgData `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages"` ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` } @@ -778,8 +780,8 @@ type RevokeMsgReq struct { unknownFields protoimpl.UnknownFields ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` - Seq int64 `protobuf:"varint,2,opt,name=seq,proto3" json:"seq"` - UserID string `protobuf:"bytes,3,opt,name=userID,proto3" json:"userID"` + Seq int64 `protobuf:"varint,2,opt,name=seq,proto3" json:"seq"` + UserID string `protobuf:"bytes,3,opt,name=userID,proto3" json:"userID"` } func (x *RevokeMsgReq) Reset() { @@ -879,8 +881,8 @@ type MarkMsgsAsReadReq struct { unknownFields protoimpl.UnknownFields ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` - Seqs []int64 `protobuf:"varint,2,rep,packed,name=seqs,proto3" json:"seqs"` - UserID string `protobuf:"bytes,3,opt,name=userID,proto3" json:"userID"` + Seqs []int64 `protobuf:"varint,2,rep,packed,name=seqs,proto3" json:"seqs"` + UserID string `protobuf:"bytes,3,opt,name=userID,proto3" json:"userID"` } func (x *MarkMsgsAsReadReq) Reset() { @@ -980,9 +982,9 @@ type MarkConversationAsReadReq struct { unknownFields protoimpl.UnknownFields ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` - UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` - HasReadSeq int64 `protobuf:"varint,3,opt,name=hasReadSeq,proto3" json:"hasReadSeq"` - Seqs []int64 `protobuf:"varint,4,rep,packed,name=seqs,proto3" json:"seqs"` + UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` + HasReadSeq int64 `protobuf:"varint,3,opt,name=hasReadSeq,proto3" json:"hasReadSeq"` + Seqs []int64 `protobuf:"varint,4,rep,packed,name=seqs,proto3" json:"seqs"` } func (x *MarkConversationAsReadReq) Reset() { @@ -1089,8 +1091,8 @@ type SetConversationHasReadSeqReq struct { unknownFields protoimpl.UnknownFields ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` - UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` - HasReadSeq int64 `protobuf:"varint,3,opt,name=hasReadSeq,proto3" json:"hasReadSeq"` + UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` + HasReadSeq int64 `protobuf:"varint,3,opt,name=hasReadSeq,proto3" json:"hasReadSeq"` } func (x *SetConversationHasReadSeqReq) Reset() { @@ -1189,7 +1191,7 @@ type DeleteSyncOpt struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - IsSyncSelf bool `protobuf:"varint,3,opt,name=IsSyncSelf,proto3" json:"IsSyncSelf"` + IsSyncSelf bool `protobuf:"varint,3,opt,name=IsSyncSelf,proto3" json:"IsSyncSelf"` IsSyncOther bool `protobuf:"varint,4,opt,name=IsSyncOther,proto3" json:"IsSyncOther"` } @@ -1245,8 +1247,8 @@ type ClearConversationsMsgReq struct { unknownFields protoimpl.UnknownFields ConversationIDs []string `protobuf:"bytes,1,rep,name=conversationIDs,proto3" json:"conversationIDs"` - UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` - DeleteSyncOpt *DeleteSyncOpt `protobuf:"bytes,3,opt,name=deleteSyncOpt,proto3" json:"deleteSyncOpt"` + UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` + DeleteSyncOpt *DeleteSyncOpt `protobuf:"bytes,3,opt,name=deleteSyncOpt,proto3" json:"deleteSyncOpt"` } func (x *ClearConversationsMsgReq) Reset() { @@ -1345,7 +1347,7 @@ type UserClearAllMsgReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` DeleteSyncOpt *DeleteSyncOpt `protobuf:"bytes,3,opt,name=deleteSyncOpt,proto3" json:"deleteSyncOpt"` } @@ -1439,9 +1441,9 @@ type DeleteMsgsReq struct { unknownFields protoimpl.UnknownFields ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` - Seqs []int64 `protobuf:"varint,2,rep,packed,name=seqs,proto3" json:"seqs"` - UserID string `protobuf:"bytes,3,opt,name=userID,proto3" json:"userID"` - DeleteSyncOpt *DeleteSyncOpt `protobuf:"bytes,4,opt,name=deleteSyncOpt,proto3" json:"deleteSyncOpt"` + Seqs []int64 `protobuf:"varint,2,rep,packed,name=seqs,proto3" json:"seqs"` + UserID string `protobuf:"bytes,3,opt,name=userID,proto3" json:"userID"` + DeleteSyncOpt *DeleteSyncOpt `protobuf:"bytes,4,opt,name=deleteSyncOpt,proto3" json:"deleteSyncOpt"` } func (x *DeleteMsgsReq) Reset() { @@ -1548,7 +1550,7 @@ type DeleteMsgPhysicalReq struct { unknownFields protoimpl.UnknownFields ConversationIDs []string `protobuf:"bytes,1,rep,name=conversationIDs,proto3" json:"conversationIDs"` - Timestamp int64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp"` + Timestamp int64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp"` } func (x *DeleteMsgPhysicalReq) Reset() { @@ -1641,7 +1643,7 @@ type DeleteMsgPhysicalBySeqReq struct { unknownFields protoimpl.UnknownFields ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` - Seqs []int64 `protobuf:"varint,2,rep,packed,name=seqs,proto3" json:"seqs"` + Seqs []int64 `protobuf:"varint,2,rep,packed,name=seqs,proto3" json:"seqs"` } func (x *DeleteMsgPhysicalBySeqReq) Reset() { @@ -1874,7 +1876,7 @@ type Seqs struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - MaxSeq int64 `protobuf:"varint,1,opt,name=maxSeq,proto3" json:"maxSeq"` + MaxSeq int64 `protobuf:"varint,1,opt,name=maxSeq,proto3" json:"maxSeq"` HasReadSeq int64 `protobuf:"varint,2,opt,name=hasReadSeq,proto3" json:"hasReadSeq"` } @@ -1976,10 +1978,10 @@ type GetActiveUserReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Start int64 `protobuf:"varint,1,opt,name=start,proto3" json:"start"` - End int64 `protobuf:"varint,2,opt,name=end,proto3" json:"end"` - Ase bool `protobuf:"varint,3,opt,name=ase,proto3" json:"ase"` - Group bool `protobuf:"varint,4,opt,name=group,proto3" json:"group"` + Start int64 `protobuf:"varint,1,opt,name=start,proto3" json:"start"` + End int64 `protobuf:"varint,2,opt,name=end,proto3" json:"end"` + Ase bool `protobuf:"varint,3,opt,name=ase,proto3" json:"ase"` + Group bool `protobuf:"varint,4,opt,name=group,proto3" json:"group"` Pagination *sdkws.RequestPagination `protobuf:"bytes,5,opt,name=pagination,proto3" json:"pagination"` } @@ -2055,7 +2057,7 @@ type ActiveUser struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - User *sdkws.UserInfo `protobuf:"bytes,1,opt,name=user,proto3" json:"user"` + User *sdkws.UserInfo `protobuf:"bytes,1,opt,name=user,proto3" json:"user"` Count int64 `protobuf:"varint,2,opt,name=count,proto3" json:"count"` } @@ -2110,10 +2112,10 @@ type GetActiveUserResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - MsgCount int64 `protobuf:"varint,1,opt,name=msgCount,proto3" json:"msgCount"` + MsgCount int64 `protobuf:"varint,1,opt,name=msgCount,proto3" json:"msgCount"` UserCount int64 `protobuf:"varint,2,opt,name=userCount,proto3" json:"userCount"` - DateCount map[string]int64 `protobuf:"bytes,3,rep,name=dateCount,proto3" json:"dateCount" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` - Users []*ActiveUser `protobuf:"bytes,4,rep,name=users,proto3" json:"users"` + DateCount map[string]int64 `protobuf:"bytes,3,rep,name=dateCount,proto3" json:"dateCount" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + Users []*ActiveUser `protobuf:"bytes,4,rep,name=users,proto3" json:"users"` } func (x *GetActiveUserResp) Reset() { @@ -2181,9 +2183,9 @@ type GetActiveGroupReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Start int64 `protobuf:"varint,1,opt,name=start,proto3" json:"start"` - End int64 `protobuf:"varint,2,opt,name=end,proto3" json:"end"` - Ase bool `protobuf:"varint,3,opt,name=ase,proto3" json:"ase"` + Start int64 `protobuf:"varint,1,opt,name=start,proto3" json:"start"` + End int64 `protobuf:"varint,2,opt,name=end,proto3" json:"end"` + Ase bool `protobuf:"varint,3,opt,name=ase,proto3" json:"ase"` Pagination *sdkws.RequestPagination `protobuf:"bytes,4,opt,name=pagination,proto3" json:"pagination"` } @@ -2252,7 +2254,7 @@ type ActiveGroup struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *sdkws.GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + Group *sdkws.GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` Count int64 `protobuf:"varint,2,opt,name=count,proto3" json:"count"` } @@ -2307,10 +2309,10 @@ type GetActiveGroupResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - MsgCount int64 `protobuf:"varint,1,opt,name=msgCount,proto3" json:"msgCount"` + MsgCount int64 `protobuf:"varint,1,opt,name=msgCount,proto3" json:"msgCount"` GroupCount int64 `protobuf:"varint,2,opt,name=groupCount,proto3" json:"groupCount"` - DateCount map[string]int64 `protobuf:"bytes,3,rep,name=dateCount,proto3" json:"dateCount" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` - Groups []*ActiveGroup `protobuf:"bytes,4,rep,name=groups,proto3" json:"groups"` + DateCount map[string]int64 `protobuf:"bytes,3,rep,name=dateCount,proto3" json:"dateCount" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + Groups []*ActiveGroup `protobuf:"bytes,4,rep,name=groups,proto3" json:"groups"` } func (x *GetActiveGroupResp) Reset() { @@ -2378,12 +2380,12 @@ type SearchMessageReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - SendID string `protobuf:"bytes,1,opt,name=sendID,proto3" json:"sendID"` //发送者ID - RecvID string `protobuf:"bytes,2,opt,name=recvID,proto3" json:"recvID"` //接收者ID - MsgType int32 `protobuf:"varint,3,opt,name=msgType,proto3" json:"msgType"` - SendTime string `protobuf:"bytes,4,opt,name=sendTime,proto3" json:"sendTime"` + SendID string `protobuf:"bytes,1,opt,name=sendID,proto3" json:"sendID"` //发送者ID + RecvID string `protobuf:"bytes,2,opt,name=recvID,proto3" json:"recvID"` //接收者ID + MsgType int32 `protobuf:"varint,3,opt,name=msgType,proto3" json:"msgType"` + SendTime string `protobuf:"bytes,4,opt,name=sendTime,proto3" json:"sendTime"` SessionType int32 `protobuf:"varint,5,opt,name=sessionType,proto3" json:"sessionType"` - Pagination *sdkws.RequestPagination `protobuf:"bytes,6,opt,name=pagination,proto3" json:"pagination"` + Pagination *sdkws.RequestPagination `protobuf:"bytes,6,opt,name=pagination,proto3" json:"pagination"` } func (x *SearchMessageReq) Reset() { @@ -2465,7 +2467,7 @@ type SearchMessageResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ChatLogs []*ChatLog `protobuf:"bytes,1,rep,name=chatLogs,proto3" json:"chatLogs"` + ChatLogs []*ChatLog `protobuf:"bytes,1,rep,name=chatLogs,proto3" json:"chatLogs"` ChatLogsNum int32 `protobuf:"varint,2,opt,name=chatLogsNum,proto3" json:"chatLogsNum"` } @@ -2520,29 +2522,29 @@ type ChatLog struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ServerMsgID string `protobuf:"bytes,1,opt,name=serverMsgID,proto3" json:"serverMsgID"` - ClientMsgID string `protobuf:"bytes,2,opt,name=clientMsgID,proto3" json:"clientMsgID"` - SendID string `protobuf:"bytes,3,opt,name=sendID,proto3" json:"sendID"` - RecvID string `protobuf:"bytes,4,opt,name=recvID,proto3" json:"recvID"` - GroupID string `protobuf:"bytes,5,opt,name=groupID,proto3" json:"groupID"` - RecvNickname string `protobuf:"bytes,6,opt,name=recvNickname,proto3" json:"recvNickname"` - SenderPlatformID int32 `protobuf:"varint,7,opt,name=senderPlatformID,proto3" json:"senderPlatformID"` - SenderNickname string `protobuf:"bytes,8,opt,name=senderNickname,proto3" json:"senderNickname"` - SenderFaceURL string `protobuf:"bytes,9,opt,name=senderFaceURL,proto3" json:"senderFaceURL"` - GroupName string `protobuf:"bytes,10,opt,name=groupName,proto3" json:"groupName"` - SessionType int32 `protobuf:"varint,11,opt,name=sessionType,proto3" json:"sessionType"` - MsgFrom int32 `protobuf:"varint,12,opt,name=msgFrom,proto3" json:"msgFrom"` - ContentType int32 `protobuf:"varint,13,opt,name=contentType,proto3" json:"contentType"` - Content string `protobuf:"bytes,14,opt,name=content,proto3" json:"content"` - Status int32 `protobuf:"varint,15,opt,name=status,proto3" json:"status"` - SendTime int64 `protobuf:"varint,16,opt,name=sendTime,proto3" json:"sendTime"` - CreateTime int64 `protobuf:"varint,17,opt,name=createTime,proto3" json:"createTime"` - Ex string `protobuf:"bytes,18,opt,name=ex,proto3" json:"ex"` - GroupFaceURL string `protobuf:"bytes,19,opt,name=groupFaceURL,proto3" json:"groupFaceURL"` + ServerMsgID string `protobuf:"bytes,1,opt,name=serverMsgID,proto3" json:"serverMsgID"` + ClientMsgID string `protobuf:"bytes,2,opt,name=clientMsgID,proto3" json:"clientMsgID"` + SendID string `protobuf:"bytes,3,opt,name=sendID,proto3" json:"sendID"` + RecvID string `protobuf:"bytes,4,opt,name=recvID,proto3" json:"recvID"` + GroupID string `protobuf:"bytes,5,opt,name=groupID,proto3" json:"groupID"` + RecvNickname string `protobuf:"bytes,6,opt,name=recvNickname,proto3" json:"recvNickname"` + SenderPlatformID int32 `protobuf:"varint,7,opt,name=senderPlatformID,proto3" json:"senderPlatformID"` + SenderNickname string `protobuf:"bytes,8,opt,name=senderNickname,proto3" json:"senderNickname"` + SenderFaceURL string `protobuf:"bytes,9,opt,name=senderFaceURL,proto3" json:"senderFaceURL"` + GroupName string `protobuf:"bytes,10,opt,name=groupName,proto3" json:"groupName"` + SessionType int32 `protobuf:"varint,11,opt,name=sessionType,proto3" json:"sessionType"` + MsgFrom int32 `protobuf:"varint,12,opt,name=msgFrom,proto3" json:"msgFrom"` + ContentType int32 `protobuf:"varint,13,opt,name=contentType,proto3" json:"contentType"` + Content string `protobuf:"bytes,14,opt,name=content,proto3" json:"content"` + Status int32 `protobuf:"varint,15,opt,name=status,proto3" json:"status"` + SendTime int64 `protobuf:"varint,16,opt,name=sendTime,proto3" json:"sendTime"` + CreateTime int64 `protobuf:"varint,17,opt,name=createTime,proto3" json:"createTime"` + Ex string `protobuf:"bytes,18,opt,name=ex,proto3" json:"ex"` + GroupFaceURL string `protobuf:"bytes,19,opt,name=groupFaceURL,proto3" json:"groupFaceURL"` GroupMemberCount uint32 `protobuf:"varint,20,opt,name=groupMemberCount,proto3" json:"groupMemberCount"` - Seq int64 `protobuf:"varint,21,opt,name=seq,proto3" json:"seq"` - GroupOwner string `protobuf:"bytes,22,opt,name=groupOwner,proto3" json:"groupOwner"` - GroupType int32 `protobuf:"varint,23,opt,name=groupType,proto3" json:"groupType"` + Seq int64 `protobuf:"varint,21,opt,name=seq,proto3" json:"seq"` + GroupOwner string `protobuf:"bytes,22,opt,name=groupOwner,proto3" json:"groupOwner"` + GroupType int32 `protobuf:"varint,23,opt,name=groupType,proto3" json:"groupType"` } func (x *ChatLog) Reset() { @@ -2744,7 +2746,7 @@ type BatchSendMessageReq struct { unknownFields protoimpl.UnknownFields RecvIDList []string `protobuf:"bytes,1,rep,name=recvIDList,proto3" json:"recvIDList"` - MsgData *sdkws.MsgData `protobuf:"bytes,2,opt,name=msgData,proto3" json:"msgData"` + MsgData *sdkws.MsgData `protobuf:"bytes,2,opt,name=msgData,proto3" json:"msgData"` } func (x *BatchSendMessageReq) Reset() { diff --git a/pkg/proto/msggateway/msggateway.pb.go b/pkg/proto/msggateway/msggateway.pb.go index d922d98b4..353524897 100644 --- a/pkg/proto/msggateway/msggateway.pb.go +++ b/pkg/proto/msggateway/msggateway.pb.go @@ -22,14 +22,16 @@ package msggateway import ( context "context" - sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" + reflect "reflect" + sync "sync" + grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" + + sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" ) const ( @@ -44,7 +46,7 @@ type OnlinePushMsgReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - MsgData *sdkws.MsgData `protobuf:"bytes,1,opt,name=msgData,proto3" json:"msgData"` + MsgData *sdkws.MsgData `protobuf:"bytes,1,opt,name=msgData,proto3" json:"msgData"` PushToUserID string `protobuf:"bytes,2,opt,name=pushToUserID,proto3" json:"pushToUserID"` } @@ -146,8 +148,8 @@ type SingleMsgToUserResults struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` - Resp []*SingleMsgToUserPlatform `protobuf:"bytes,2,rep,name=resp,proto3" json:"resp"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + Resp []*SingleMsgToUserPlatform `protobuf:"bytes,2,rep,name=resp,proto3" json:"resp"` OnlinePush bool `protobuf:"varint,3,opt,name=onlinePush,proto3" json:"onlinePush"` } @@ -209,7 +211,7 @@ type OnlineBatchPushOneMsgReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - MsgData *sdkws.MsgData `protobuf:"bytes,1,opt,name=msgData,proto3" json:"msgData"` + MsgData *sdkws.MsgData `protobuf:"bytes,1,opt,name=msgData,proto3" json:"msgData"` PushToUserIDs []string `protobuf:"bytes,2,rep,name=pushToUserIDs,proto3" json:"pushToUserIDs"` } @@ -311,8 +313,8 @@ type SingleMsgToUserPlatform struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ResultCode int64 `protobuf:"varint,1,opt,name=ResultCode,proto3" json:"ResultCode"` - RecvID string `protobuf:"bytes,2,opt,name=RecvID,proto3" json:"RecvID"` + ResultCode int64 `protobuf:"varint,1,opt,name=ResultCode,proto3" json:"ResultCode"` + RecvID string `protobuf:"bytes,2,opt,name=RecvID,proto3" json:"RecvID"` RecvPlatFormID int32 `protobuf:"varint,3,opt,name=RecvPlatFormID,proto3" json:"RecvPlatFormID"` } @@ -422,7 +424,7 @@ type GetUsersOnlineStatusResp struct { unknownFields protoimpl.UnknownFields SuccessResult []*GetUsersOnlineStatusResp_SuccessResult `protobuf:"bytes,1,rep,name=successResult,proto3" json:"successResult"` - FailedResult []*GetUsersOnlineStatusResp_FailedDetail `protobuf:"bytes,2,rep,name=failedResult,proto3" json:"failedResult"` + FailedResult []*GetUsersOnlineStatusResp_FailedDetail `protobuf:"bytes,2,rep,name=failedResult,proto3" json:"failedResult"` } func (x *GetUsersOnlineStatusResp) Reset() { @@ -476,8 +478,8 @@ type SingleDetail struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` - Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status"` SinglePlatformToken []*SinglePlatformToken `protobuf:"bytes,3,rep,name=singlePlatformToken,proto3" json:"singlePlatformToken"` } @@ -540,8 +542,8 @@ type SinglePlatformToken struct { unknownFields protoimpl.UnknownFields Platform string `protobuf:"bytes,1,opt,name=platform,proto3" json:"platform"` - Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total"` - Token []string `protobuf:"bytes,3,rep,name=token,proto3" json:"token"` + Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total"` + Token []string `protobuf:"bytes,3,rep,name=token,proto3" json:"token"` } func (x *SinglePlatformToken) Reset() { @@ -602,7 +604,7 @@ type KickUserOfflineReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - PlatformID int32 `protobuf:"varint,1,opt,name=platformID,proto3" json:"platformID"` + PlatformID int32 `protobuf:"varint,1,opt,name=platformID,proto3" json:"platformID"` KickUserIDList []string `protobuf:"bytes,2,rep,name=kickUserIDList,proto3" json:"kickUserIDList"` } @@ -695,9 +697,9 @@ type MultiTerminalLoginCheckReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` PlatformID int32 `protobuf:"varint,2,opt,name=platformID,proto3" json:"platformID"` - Token string `protobuf:"bytes,3,opt,name=token,proto3" json:"token"` + Token string `protobuf:"bytes,3,opt,name=token,proto3" json:"token"` OperationID string `protobuf:"bytes,4,opt,name=operationID,proto3" json:"operationID"` } @@ -804,11 +806,11 @@ type GetUsersOnlineStatusResp_SuccessDetail struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Platform string `protobuf:"bytes,1,opt,name=platform,proto3" json:"platform"` - Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status"` - ConnID string `protobuf:"bytes,3,opt,name=connID,proto3" json:"connID"` + Platform string `protobuf:"bytes,1,opt,name=platform,proto3" json:"platform"` + Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status"` + ConnID string `protobuf:"bytes,3,opt,name=connID,proto3" json:"connID"` IsBackground bool `protobuf:"varint,4,opt,name=isBackground,proto3" json:"isBackground"` - Token string `protobuf:"bytes,5,opt,name=token,proto3" json:"token"` + Token string `protobuf:"bytes,5,opt,name=token,proto3" json:"token"` } func (x *GetUsersOnlineStatusResp_SuccessDetail) Reset() { @@ -930,8 +932,8 @@ type GetUsersOnlineStatusResp_SuccessResult struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` - Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status"` DetailPlatformStatus []*GetUsersOnlineStatusResp_SuccessDetail `protobuf:"bytes,3,rep,name=detailPlatformStatus,proto3" json:"detailPlatformStatus"` } diff --git a/pkg/proto/push/push.pb.go b/pkg/proto/push/push.pb.go index 1dc9d2ab9..7ef946b60 100644 --- a/pkg/proto/push/push.pb.go +++ b/pkg/proto/push/push.pb.go @@ -22,14 +22,16 @@ package push import ( context "context" - sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" + reflect "reflect" + sync "sync" + grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" + + sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" ) const ( @@ -44,7 +46,7 @@ type PushMsgReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - MsgData *sdkws.MsgData `protobuf:"bytes,1,opt,name=msgData,proto3" json:"msgData"` + MsgData *sdkws.MsgData `protobuf:"bytes,1,opt,name=msgData,proto3" json:"msgData"` ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` } @@ -137,7 +139,7 @@ type DelUserPushTokenReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` PlatformID int32 `protobuf:"varint,2,opt,name=platformID,proto3" json:"platformID"` } diff --git a/pkg/proto/sdkws/sdkws.pb.go b/pkg/proto/sdkws/sdkws.pb.go index b45d46d4c..ca6e6135a 100644 --- a/pkg/proto/sdkws/sdkws.pb.go +++ b/pkg/proto/sdkws/sdkws.pb.go @@ -21,11 +21,13 @@ package sdkws import ( - wrapperspb "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + + wrapperspb "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb" ) const ( @@ -87,23 +89,23 @@ type GroupInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` - GroupName string `protobuf:"bytes,2,opt,name=groupName,proto3" json:"groupName"` - Notification string `protobuf:"bytes,3,opt,name=notification,proto3" json:"notification"` - Introduction string `protobuf:"bytes,4,opt,name=introduction,proto3" json:"introduction"` - FaceURL string `protobuf:"bytes,5,opt,name=faceURL,proto3" json:"faceURL"` - OwnerUserID string `protobuf:"bytes,6,opt,name=ownerUserID,proto3" json:"ownerUserID"` - CreateTime int64 `protobuf:"varint,7,opt,name=createTime,proto3" json:"createTime"` - MemberCount uint32 `protobuf:"varint,8,opt,name=memberCount,proto3" json:"memberCount"` - Ex string `protobuf:"bytes,9,opt,name=ex,proto3" json:"ex"` - Status int32 `protobuf:"varint,10,opt,name=status,proto3" json:"status"` - CreatorUserID string `protobuf:"bytes,11,opt,name=creatorUserID,proto3" json:"creatorUserID"` - GroupType int32 `protobuf:"varint,12,opt,name=groupType,proto3" json:"groupType"` - NeedVerification int32 `protobuf:"varint,13,opt,name=needVerification,proto3" json:"needVerification"` - LookMemberInfo int32 `protobuf:"varint,14,opt,name=lookMemberInfo,proto3" json:"lookMemberInfo"` - ApplyMemberFriend int32 `protobuf:"varint,15,opt,name=applyMemberFriend,proto3" json:"applyMemberFriend"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + GroupName string `protobuf:"bytes,2,opt,name=groupName,proto3" json:"groupName"` + Notification string `protobuf:"bytes,3,opt,name=notification,proto3" json:"notification"` + Introduction string `protobuf:"bytes,4,opt,name=introduction,proto3" json:"introduction"` + FaceURL string `protobuf:"bytes,5,opt,name=faceURL,proto3" json:"faceURL"` + OwnerUserID string `protobuf:"bytes,6,opt,name=ownerUserID,proto3" json:"ownerUserID"` + CreateTime int64 `protobuf:"varint,7,opt,name=createTime,proto3" json:"createTime"` + MemberCount uint32 `protobuf:"varint,8,opt,name=memberCount,proto3" json:"memberCount"` + Ex string `protobuf:"bytes,9,opt,name=ex,proto3" json:"ex"` + Status int32 `protobuf:"varint,10,opt,name=status,proto3" json:"status"` + CreatorUserID string `protobuf:"bytes,11,opt,name=creatorUserID,proto3" json:"creatorUserID"` + GroupType int32 `protobuf:"varint,12,opt,name=groupType,proto3" json:"groupType"` + NeedVerification int32 `protobuf:"varint,13,opt,name=needVerification,proto3" json:"needVerification"` + LookMemberInfo int32 `protobuf:"varint,14,opt,name=lookMemberInfo,proto3" json:"lookMemberInfo"` + ApplyMemberFriend int32 `protobuf:"varint,15,opt,name=applyMemberFriend,proto3" json:"applyMemberFriend"` NotificationUpdateTime int64 `protobuf:"varint,16,opt,name=notificationUpdateTime,proto3" json:"notificationUpdateTime"` - NotificationUserID string `protobuf:"bytes,17,opt,name=notificationUserID,proto3" json:"notificationUserID"` + NotificationUserID string `protobuf:"bytes,17,opt,name=notificationUserID,proto3" json:"notificationUserID"` } func (x *GroupInfo) Reset() { @@ -262,14 +264,14 @@ type GroupInfoForSet struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` - GroupName string `protobuf:"bytes,2,opt,name=groupName,proto3" json:"groupName"` - Notification string `protobuf:"bytes,3,opt,name=notification,proto3" json:"notification"` - Introduction string `protobuf:"bytes,4,opt,name=introduction,proto3" json:"introduction"` - FaceURL string `protobuf:"bytes,5,opt,name=faceURL,proto3" json:"faceURL"` - Ex string `protobuf:"bytes,6,opt,name=ex,proto3" json:"ex"` - NeedVerification *wrapperspb.Int32Value `protobuf:"bytes,7,opt,name=needVerification,proto3" json:"needVerification"` - LookMemberInfo *wrapperspb.Int32Value `protobuf:"bytes,8,opt,name=lookMemberInfo,proto3" json:"lookMemberInfo"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + GroupName string `protobuf:"bytes,2,opt,name=groupName,proto3" json:"groupName"` + Notification string `protobuf:"bytes,3,opt,name=notification,proto3" json:"notification"` + Introduction string `protobuf:"bytes,4,opt,name=introduction,proto3" json:"introduction"` + FaceURL string `protobuf:"bytes,5,opt,name=faceURL,proto3" json:"faceURL"` + Ex string `protobuf:"bytes,6,opt,name=ex,proto3" json:"ex"` + NeedVerification *wrapperspb.Int32Value `protobuf:"bytes,7,opt,name=needVerification,proto3" json:"needVerification"` + LookMemberInfo *wrapperspb.Int32Value `protobuf:"bytes,8,opt,name=lookMemberInfo,proto3" json:"lookMemberInfo"` ApplyMemberFriend *wrapperspb.Int32Value `protobuf:"bytes,9,opt,name=applyMemberFriend,proto3" json:"applyMemberFriend"` } @@ -373,18 +375,18 @@ type GroupMemberFullInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` - UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` - RoleLevel int32 `protobuf:"varint,3,opt,name=roleLevel,proto3" json:"roleLevel"` - JoinTime int64 `protobuf:"varint,4,opt,name=joinTime,proto3" json:"joinTime"` - Nickname string `protobuf:"bytes,5,opt,name=nickname,proto3" json:"nickname"` - FaceURL string `protobuf:"bytes,6,opt,name=faceURL,proto3" json:"faceURL"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` + RoleLevel int32 `protobuf:"varint,3,opt,name=roleLevel,proto3" json:"roleLevel"` + JoinTime int64 `protobuf:"varint,4,opt,name=joinTime,proto3" json:"joinTime"` + Nickname string `protobuf:"bytes,5,opt,name=nickname,proto3" json:"nickname"` + FaceURL string `protobuf:"bytes,6,opt,name=faceURL,proto3" json:"faceURL"` AppMangerLevel int32 `protobuf:"varint,7,opt,name=appMangerLevel,proto3" json:"appMangerLevel"` //if >0 - JoinSource int32 `protobuf:"varint,8,opt,name=joinSource,proto3" json:"joinSource"` - OperatorUserID string `protobuf:"bytes,9,opt,name=operatorUserID,proto3" json:"operatorUserID"` - Ex string `protobuf:"bytes,10,opt,name=ex,proto3" json:"ex"` - MuteEndTime int64 `protobuf:"varint,11,opt,name=muteEndTime,proto3" json:"muteEndTime"` - InviterUserID string `protobuf:"bytes,12,opt,name=inviterUserID,proto3" json:"inviterUserID"` + JoinSource int32 `protobuf:"varint,8,opt,name=joinSource,proto3" json:"joinSource"` + OperatorUserID string `protobuf:"bytes,9,opt,name=operatorUserID,proto3" json:"operatorUserID"` + Ex string `protobuf:"bytes,10,opt,name=ex,proto3" json:"ex"` + MuteEndTime int64 `protobuf:"varint,11,opt,name=muteEndTime,proto3" json:"muteEndTime"` + InviterUserID string `protobuf:"bytes,12,opt,name=inviterUserID,proto3" json:"inviterUserID"` } func (x *GroupMemberFullInfo) Reset() { @@ -508,10 +510,10 @@ type PublicUserInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` Nickname string `protobuf:"bytes,2,opt,name=nickname,proto3" json:"nickname"` - FaceURL string `protobuf:"bytes,3,opt,name=faceURL,proto3" json:"faceURL"` - Ex string `protobuf:"bytes,4,opt,name=ex,proto3" json:"ex"` + FaceURL string `protobuf:"bytes,3,opt,name=faceURL,proto3" json:"faceURL"` + Ex string `protobuf:"bytes,4,opt,name=ex,proto3" json:"ex"` } func (x *PublicUserInfo) Reset() { @@ -579,12 +581,12 @@ type UserInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` - Nickname string `protobuf:"bytes,2,opt,name=nickname,proto3" json:"nickname"` - FaceURL string `protobuf:"bytes,3,opt,name=faceURL,proto3" json:"faceURL"` - Ex string `protobuf:"bytes,4,opt,name=ex,proto3" json:"ex"` - CreateTime int64 `protobuf:"varint,5,opt,name=createTime,proto3" json:"createTime"` - AppMangerLevel int32 `protobuf:"varint,6,opt,name=appMangerLevel,proto3" json:"appMangerLevel"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + Nickname string `protobuf:"bytes,2,opt,name=nickname,proto3" json:"nickname"` + FaceURL string `protobuf:"bytes,3,opt,name=faceURL,proto3" json:"faceURL"` + Ex string `protobuf:"bytes,4,opt,name=ex,proto3" json:"ex"` + CreateTime int64 `protobuf:"varint,5,opt,name=createTime,proto3" json:"createTime"` + AppMangerLevel int32 `protobuf:"varint,6,opt,name=appMangerLevel,proto3" json:"appMangerLevel"` GlobalRecvMsgOpt int32 `protobuf:"varint,7,opt,name=globalRecvMsgOpt,proto3" json:"globalRecvMsgOpt"` } @@ -674,13 +676,13 @@ type FriendInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` - Remark string `protobuf:"bytes,2,opt,name=remark,proto3" json:"remark"` - CreateTime int64 `protobuf:"varint,3,opt,name=createTime,proto3" json:"createTime"` - FriendUser *UserInfo `protobuf:"bytes,4,opt,name=friendUser,proto3" json:"friendUser"` - AddSource int32 `protobuf:"varint,5,opt,name=addSource,proto3" json:"addSource"` + OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` + Remark string `protobuf:"bytes,2,opt,name=remark,proto3" json:"remark"` + CreateTime int64 `protobuf:"varint,3,opt,name=createTime,proto3" json:"createTime"` + FriendUser *UserInfo `protobuf:"bytes,4,opt,name=friendUser,proto3" json:"friendUser"` + AddSource int32 `protobuf:"varint,5,opt,name=addSource,proto3" json:"addSource"` OperatorUserID string `protobuf:"bytes,6,opt,name=operatorUserID,proto3" json:"operatorUserID"` - Ex string `protobuf:"bytes,7,opt,name=ex,proto3" json:"ex"` + Ex string `protobuf:"bytes,7,opt,name=ex,proto3" json:"ex"` } func (x *FriendInfo) Reset() { @@ -769,12 +771,12 @@ type BlackInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` - CreateTime int64 `protobuf:"varint,2,opt,name=createTime,proto3" json:"createTime"` - BlackUserInfo *PublicUserInfo `protobuf:"bytes,3,opt,name=blackUserInfo,proto3" json:"blackUserInfo"` - AddSource int32 `protobuf:"varint,4,opt,name=addSource,proto3" json:"addSource"` + OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` + CreateTime int64 `protobuf:"varint,2,opt,name=createTime,proto3" json:"createTime"` + BlackUserInfo *PublicUserInfo `protobuf:"bytes,3,opt,name=blackUserInfo,proto3" json:"blackUserInfo"` + AddSource int32 `protobuf:"varint,4,opt,name=addSource,proto3" json:"addSource"` OperatorUserID string `protobuf:"bytes,5,opt,name=operatorUserID,proto3" json:"operatorUserID"` - Ex string `protobuf:"bytes,6,opt,name=ex,proto3" json:"ex"` + Ex string `protobuf:"bytes,6,opt,name=ex,proto3" json:"ex"` } func (x *BlackInfo) Reset() { @@ -856,16 +858,16 @@ type GroupRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserInfo *PublicUserInfo `protobuf:"bytes,1,opt,name=userInfo,proto3" json:"userInfo"` - GroupInfo *GroupInfo `protobuf:"bytes,2,opt,name=groupInfo,proto3" json:"groupInfo"` - HandleResult int32 `protobuf:"varint,3,opt,name=handleResult,proto3" json:"handleResult"` - ReqMsg string `protobuf:"bytes,4,opt,name=reqMsg,proto3" json:"reqMsg"` - HandleMsg string `protobuf:"bytes,5,opt,name=handleMsg,proto3" json:"handleMsg"` - ReqTime int64 `protobuf:"varint,6,opt,name=reqTime,proto3" json:"reqTime"` - HandleUserID string `protobuf:"bytes,7,opt,name=handleUserID,proto3" json:"handleUserID"` - HandleTime int64 `protobuf:"varint,8,opt,name=handleTime,proto3" json:"handleTime"` - Ex string `protobuf:"bytes,9,opt,name=ex,proto3" json:"ex"` - JoinSource int32 `protobuf:"varint,10,opt,name=joinSource,proto3" json:"joinSource"` + UserInfo *PublicUserInfo `protobuf:"bytes,1,opt,name=userInfo,proto3" json:"userInfo"` + GroupInfo *GroupInfo `protobuf:"bytes,2,opt,name=groupInfo,proto3" json:"groupInfo"` + HandleResult int32 `protobuf:"varint,3,opt,name=handleResult,proto3" json:"handleResult"` + ReqMsg string `protobuf:"bytes,4,opt,name=reqMsg,proto3" json:"reqMsg"` + HandleMsg string `protobuf:"bytes,5,opt,name=handleMsg,proto3" json:"handleMsg"` + ReqTime int64 `protobuf:"varint,6,opt,name=reqTime,proto3" json:"reqTime"` + HandleUserID string `protobuf:"bytes,7,opt,name=handleUserID,proto3" json:"handleUserID"` + HandleTime int64 `protobuf:"varint,8,opt,name=handleTime,proto3" json:"handleTime"` + Ex string `protobuf:"bytes,9,opt,name=ex,proto3" json:"ex"` + JoinSource int32 `protobuf:"varint,10,opt,name=joinSource,proto3" json:"joinSource"` InviterUserID string `protobuf:"bytes,11,opt,name=inviterUserID,proto3" json:"inviterUserID"` } @@ -983,19 +985,19 @@ type FriendRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - FromUserID string `protobuf:"bytes,1,opt,name=fromUserID,proto3" json:"fromUserID"` - FromNickname string `protobuf:"bytes,2,opt,name=fromNickname,proto3" json:"fromNickname"` - FromFaceURL string `protobuf:"bytes,3,opt,name=fromFaceURL,proto3" json:"fromFaceURL"` - ToUserID string `protobuf:"bytes,4,opt,name=toUserID,proto3" json:"toUserID"` - ToNickname string `protobuf:"bytes,5,opt,name=toNickname,proto3" json:"toNickname"` - ToFaceURL string `protobuf:"bytes,6,opt,name=toFaceURL,proto3" json:"toFaceURL"` - HandleResult int32 `protobuf:"varint,7,opt,name=handleResult,proto3" json:"handleResult"` - ReqMsg string `protobuf:"bytes,8,opt,name=reqMsg,proto3" json:"reqMsg"` - CreateTime int64 `protobuf:"varint,9,opt,name=createTime,proto3" json:"createTime"` + FromUserID string `protobuf:"bytes,1,opt,name=fromUserID,proto3" json:"fromUserID"` + FromNickname string `protobuf:"bytes,2,opt,name=fromNickname,proto3" json:"fromNickname"` + FromFaceURL string `protobuf:"bytes,3,opt,name=fromFaceURL,proto3" json:"fromFaceURL"` + ToUserID string `protobuf:"bytes,4,opt,name=toUserID,proto3" json:"toUserID"` + ToNickname string `protobuf:"bytes,5,opt,name=toNickname,proto3" json:"toNickname"` + ToFaceURL string `protobuf:"bytes,6,opt,name=toFaceURL,proto3" json:"toFaceURL"` + HandleResult int32 `protobuf:"varint,7,opt,name=handleResult,proto3" json:"handleResult"` + ReqMsg string `protobuf:"bytes,8,opt,name=reqMsg,proto3" json:"reqMsg"` + CreateTime int64 `protobuf:"varint,9,opt,name=createTime,proto3" json:"createTime"` HandlerUserID string `protobuf:"bytes,10,opt,name=handlerUserID,proto3" json:"handlerUserID"` - HandleMsg string `protobuf:"bytes,11,opt,name=handleMsg,proto3" json:"handleMsg"` - HandleTime int64 `protobuf:"varint,12,opt,name=handleTime,proto3" json:"handleTime"` - Ex string `protobuf:"bytes,13,opt,name=ex,proto3" json:"ex"` + HandleMsg string `protobuf:"bytes,11,opt,name=handleMsg,proto3" json:"handleMsg"` + HandleTime int64 `protobuf:"varint,12,opt,name=handleTime,proto3" json:"handleTime"` + Ex string `protobuf:"bytes,13,opt,name=ex,proto3" json:"ex"` } func (x *FriendRequest) Reset() { @@ -1126,8 +1128,8 @@ type PullMessageBySeqsReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` - SeqRanges []*SeqRange `protobuf:"bytes,2,rep,name=seqRanges,proto3" json:"seqRanges"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + SeqRanges []*SeqRange `protobuf:"bytes,2,rep,name=seqRanges,proto3" json:"seqRanges"` Order PullOrder `protobuf:"varint,3,opt,name=order,proto3,enum=OpenIMServer.sdkws.PullOrder" json:"order"` } @@ -1190,9 +1192,9 @@ type SeqRange struct { unknownFields protoimpl.UnknownFields ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` - Begin int64 `protobuf:"varint,2,opt,name=begin,proto3" json:"begin"` - End int64 `protobuf:"varint,3,opt,name=end,proto3" json:"end"` - Num int64 `protobuf:"varint,4,opt,name=num,proto3" json:"num"` + Begin int64 `protobuf:"varint,2,opt,name=begin,proto3" json:"begin"` + End int64 `protobuf:"varint,3,opt,name=end,proto3" json:"end"` + Num int64 `protobuf:"varint,4,opt,name=num,proto3" json:"num"` } func (x *SeqRange) Reset() { @@ -1260,7 +1262,7 @@ type PullMsgs struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Msgs []*MsgData `protobuf:"bytes,1,rep,name=Msgs,proto3" json:"Msgs"` + Msgs []*MsgData `protobuf:"bytes,1,rep,name=Msgs,proto3" json:"Msgs"` IsEnd bool `protobuf:"varint,2,opt,name=isEnd,proto3" json:"isEnd"` } @@ -1315,7 +1317,7 @@ type PullMessageBySeqsResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Msgs map[string]*PullMsgs `protobuf:"bytes,1,rep,name=msgs,proto3" json:"msgs" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Msgs map[string]*PullMsgs `protobuf:"bytes,1,rep,name=msgs,proto3" json:"msgs" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` NotificationMsgs map[string]*PullMsgs `protobuf:"bytes,2,rep,name=notificationMsgs,proto3" json:"notificationMsgs" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } @@ -1474,7 +1476,7 @@ type UserSendMsgResp struct { ServerMsgID string `protobuf:"bytes,1,opt,name=serverMsgID,proto3" json:"serverMsgID"` ClientMsgID string `protobuf:"bytes,2,opt,name=clientMsgID,proto3" json:"clientMsgID"` - SendTime int64 `protobuf:"varint,3,opt,name=sendTime,proto3" json:"sendTime"` + SendTime int64 `protobuf:"varint,3,opt,name=sendTime,proto3" json:"sendTime"` } func (x *UserSendMsgResp) Reset() { @@ -1535,28 +1537,28 @@ type MsgData struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - SendID string `protobuf:"bytes,1,opt,name=sendID,proto3" json:"sendID"` - RecvID string `protobuf:"bytes,2,opt,name=recvID,proto3" json:"recvID"` - GroupID string `protobuf:"bytes,3,opt,name=groupID,proto3" json:"groupID"` - ClientMsgID string `protobuf:"bytes,4,opt,name=clientMsgID,proto3" json:"clientMsgID"` - ServerMsgID string `protobuf:"bytes,5,opt,name=serverMsgID,proto3" json:"serverMsgID"` + SendID string `protobuf:"bytes,1,opt,name=sendID,proto3" json:"sendID"` + RecvID string `protobuf:"bytes,2,opt,name=recvID,proto3" json:"recvID"` + GroupID string `protobuf:"bytes,3,opt,name=groupID,proto3" json:"groupID"` + ClientMsgID string `protobuf:"bytes,4,opt,name=clientMsgID,proto3" json:"clientMsgID"` + ServerMsgID string `protobuf:"bytes,5,opt,name=serverMsgID,proto3" json:"serverMsgID"` SenderPlatformID int32 `protobuf:"varint,6,opt,name=senderPlatformID,proto3" json:"senderPlatformID"` - SenderNickname string `protobuf:"bytes,7,opt,name=senderNickname,proto3" json:"senderNickname"` - SenderFaceURL string `protobuf:"bytes,8,opt,name=senderFaceURL,proto3" json:"senderFaceURL"` - SessionType int32 `protobuf:"varint,9,opt,name=sessionType,proto3" json:"sessionType"` - MsgFrom int32 `protobuf:"varint,10,opt,name=msgFrom,proto3" json:"msgFrom"` - ContentType int32 `protobuf:"varint,11,opt,name=contentType,proto3" json:"contentType"` - Content []byte `protobuf:"bytes,12,opt,name=content,proto3" json:"content"` - Seq int64 `protobuf:"varint,14,opt,name=seq,proto3" json:"seq"` - SendTime int64 `protobuf:"varint,15,opt,name=sendTime,proto3" json:"sendTime"` - CreateTime int64 `protobuf:"varint,16,opt,name=createTime,proto3" json:"createTime"` - Status int32 `protobuf:"varint,17,opt,name=status,proto3" json:"status"` - IsRead bool `protobuf:"varint,18,opt,name=isRead,proto3" json:"isRead"` - Options map[string]bool `protobuf:"bytes,19,rep,name=options,proto3" json:"options" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` - OfflinePushInfo *OfflinePushInfo `protobuf:"bytes,20,opt,name=offlinePushInfo,proto3" json:"offlinePushInfo"` - AtUserIDList []string `protobuf:"bytes,21,rep,name=atUserIDList,proto3" json:"atUserIDList"` - AttachedInfo string `protobuf:"bytes,22,opt,name=attachedInfo,proto3" json:"attachedInfo"` - Ex string `protobuf:"bytes,23,opt,name=ex,proto3" json:"ex"` + SenderNickname string `protobuf:"bytes,7,opt,name=senderNickname,proto3" json:"senderNickname"` + SenderFaceURL string `protobuf:"bytes,8,opt,name=senderFaceURL,proto3" json:"senderFaceURL"` + SessionType int32 `protobuf:"varint,9,opt,name=sessionType,proto3" json:"sessionType"` + MsgFrom int32 `protobuf:"varint,10,opt,name=msgFrom,proto3" json:"msgFrom"` + ContentType int32 `protobuf:"varint,11,opt,name=contentType,proto3" json:"contentType"` + Content []byte `protobuf:"bytes,12,opt,name=content,proto3" json:"content"` + Seq int64 `protobuf:"varint,14,opt,name=seq,proto3" json:"seq"` + SendTime int64 `protobuf:"varint,15,opt,name=sendTime,proto3" json:"sendTime"` + CreateTime int64 `protobuf:"varint,16,opt,name=createTime,proto3" json:"createTime"` + Status int32 `protobuf:"varint,17,opt,name=status,proto3" json:"status"` + IsRead bool `protobuf:"varint,18,opt,name=isRead,proto3" json:"isRead"` + Options map[string]bool `protobuf:"bytes,19,rep,name=options,proto3" json:"options" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + OfflinePushInfo *OfflinePushInfo `protobuf:"bytes,20,opt,name=offlinePushInfo,proto3" json:"offlinePushInfo"` + AtUserIDList []string `protobuf:"bytes,21,rep,name=atUserIDList,proto3" json:"atUserIDList"` + AttachedInfo string `protobuf:"bytes,22,opt,name=attachedInfo,proto3" json:"attachedInfo"` + Ex string `protobuf:"bytes,23,opt,name=ex,proto3" json:"ex"` } func (x *MsgData) Reset() { @@ -1750,7 +1752,7 @@ type PushMessages struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Msgs map[string]*PullMsgs `protobuf:"bytes,1,rep,name=msgs,proto3" json:"msgs" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Msgs map[string]*PullMsgs `protobuf:"bytes,1,rep,name=msgs,proto3" json:"msgs" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` NotificationMsgs map[string]*PullMsgs `protobuf:"bytes,2,rep,name=notificationMsgs,proto3" json:"notificationMsgs" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } @@ -1805,12 +1807,12 @@ type OfflinePushInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title"` - Desc string `protobuf:"bytes,2,opt,name=desc,proto3" json:"desc"` - Ex string `protobuf:"bytes,3,opt,name=ex,proto3" json:"ex"` - IOSPushSound string `protobuf:"bytes,4,opt,name=iOSPushSound,proto3" json:"iOSPushSound"` + Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title"` + Desc string `protobuf:"bytes,2,opt,name=desc,proto3" json:"desc"` + Ex string `protobuf:"bytes,3,opt,name=ex,proto3" json:"ex"` + IOSPushSound string `protobuf:"bytes,4,opt,name=iOSPushSound,proto3" json:"iOSPushSound"` IOSBadgeCount bool `protobuf:"varint,5,opt,name=iOSBadgeCount,proto3" json:"iOSBadgeCount"` - SignalInfo string `protobuf:"bytes,6,opt,name=signalInfo,proto3" json:"signalInfo"` + SignalInfo string `protobuf:"bytes,6,opt,name=signalInfo,proto3" json:"signalInfo"` } func (x *OfflinePushInfo) Reset() { @@ -1892,9 +1894,9 @@ type TipsComm struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Detail []byte `protobuf:"bytes,1,opt,name=detail,proto3" json:"detail"` + Detail []byte `protobuf:"bytes,1,opt,name=detail,proto3" json:"detail"` DefaultTips string `protobuf:"bytes,2,opt,name=defaultTips,proto3" json:"defaultTips"` - JsonDetail string `protobuf:"bytes,3,opt,name=jsonDetail,proto3" json:"jsonDetail"` + JsonDetail string `protobuf:"bytes,3,opt,name=jsonDetail,proto3" json:"jsonDetail"` } func (x *TipsComm) Reset() { @@ -1956,9 +1958,9 @@ type GroupCreatedTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` - MemberList []*GroupMemberFullInfo `protobuf:"bytes,3,rep,name=memberList,proto3" json:"memberList"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + MemberList []*GroupMemberFullInfo `protobuf:"bytes,3,rep,name=memberList,proto3" json:"memberList"` OperationTime int64 `protobuf:"varint,4,opt,name=operationTime,proto3" json:"operationTime"` GroupOwnerUser *GroupMemberFullInfo `protobuf:"bytes,5,opt,name=groupOwnerUser,proto3" json:"groupOwnerUser"` } @@ -2036,9 +2038,9 @@ type GroupInfoSetTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OpUser *GroupMemberFullInfo `protobuf:"bytes,1,opt,name=opUser,proto3" json:"opUser"` //who do this + OpUser *GroupMemberFullInfo `protobuf:"bytes,1,opt,name=opUser,proto3" json:"opUser"` //who do this MuteTime int64 `protobuf:"varint,2,opt,name=muteTime,proto3" json:"muteTime"` - Group *GroupInfo `protobuf:"bytes,3,opt,name=group,proto3" json:"group"` + Group *GroupInfo `protobuf:"bytes,3,opt,name=group,proto3" json:"group"` } func (x *GroupInfoSetTips) Reset() { @@ -2100,7 +2102,7 @@ type GroupInfoSetNameTips struct { unknownFields protoimpl.UnknownFields OpUser *GroupMemberFullInfo `protobuf:"bytes,1,opt,name=opUser,proto3" json:"opUser"` //who do this - Group *GroupInfo `protobuf:"bytes,2,opt,name=group,proto3" json:"group"` + Group *GroupInfo `protobuf:"bytes,2,opt,name=group,proto3" json:"group"` } func (x *GroupInfoSetNameTips) Reset() { @@ -2155,7 +2157,7 @@ type GroupInfoSetAnnouncementTips struct { unknownFields protoimpl.UnknownFields OpUser *GroupMemberFullInfo `protobuf:"bytes,1,opt,name=opUser,proto3" json:"opUser"` //who do this - Group *GroupInfo `protobuf:"bytes,2,opt,name=group,proto3" json:"group"` + Group *GroupInfo `protobuf:"bytes,2,opt,name=group,proto3" json:"group"` } func (x *GroupInfoSetAnnouncementTips) Reset() { @@ -2210,9 +2212,9 @@ type JoinGroupApplicationTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` Applicant *PublicUserInfo `protobuf:"bytes,2,opt,name=applicant,proto3" json:"applicant"` - ReqMsg string `protobuf:"bytes,3,opt,name=reqMsg,proto3" json:"reqMsg"` + ReqMsg string `protobuf:"bytes,3,opt,name=reqMsg,proto3" json:"reqMsg"` } func (x *JoinGroupApplicationTips) Reset() { @@ -2276,8 +2278,8 @@ type MemberQuitTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - QuitUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=quitUser,proto3" json:"quitUser"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + QuitUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=quitUser,proto3" json:"quitUser"` OperationTime int64 `protobuf:"varint,3,opt,name=operationTime,proto3" json:"operationTime"` } @@ -2340,9 +2342,9 @@ type GroupApplicationAcceptedTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` - HandleMsg string `protobuf:"bytes,4,opt,name=handleMsg,proto3" json:"handleMsg"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + HandleMsg string `protobuf:"bytes,4,opt,name=handleMsg,proto3" json:"handleMsg"` ReceiverAs int32 `protobuf:"varint,5,opt,name=receiverAs,proto3" json:"receiverAs"` // admin(==1) or applicant(==0) } @@ -2412,9 +2414,9 @@ type GroupApplicationRejectedTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` - HandleMsg string `protobuf:"bytes,4,opt,name=handleMsg,proto3" json:"handleMsg"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + HandleMsg string `protobuf:"bytes,4,opt,name=handleMsg,proto3" json:"handleMsg"` ReceiverAs int32 `protobuf:"varint,5,opt,name=receiverAs,proto3" json:"receiverAs"` // admin(==1) or applicant(==0) } @@ -2484,9 +2486,9 @@ type GroupOwnerTransferredTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` - NewGroupOwner *GroupMemberFullInfo `protobuf:"bytes,3,opt,name=newGroupOwner,proto3" json:"newGroupOwner"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + NewGroupOwner *GroupMemberFullInfo `protobuf:"bytes,3,opt,name=newGroupOwner,proto3" json:"newGroupOwner"` OperationTime int64 `protobuf:"varint,4,opt,name=operationTime,proto3" json:"operationTime"` } @@ -2556,8 +2558,8 @@ type MemberKickedTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` KickedUserList []*GroupMemberFullInfo `protobuf:"bytes,3,rep,name=kickedUserList,proto3" json:"kickedUserList"` OperationTime int64 `protobuf:"varint,4,opt,name=operationTime,proto3" json:"operationTime"` } @@ -2628,10 +2630,10 @@ type MemberInvitedTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` InvitedUserList []*GroupMemberFullInfo `protobuf:"bytes,3,rep,name=invitedUserList,proto3" json:"invitedUserList"` - OperationTime int64 `protobuf:"varint,4,opt,name=operationTime,proto3" json:"operationTime"` + OperationTime int64 `protobuf:"varint,4,opt,name=operationTime,proto3" json:"operationTime"` } func (x *MemberInvitedTips) Reset() { @@ -2700,8 +2702,8 @@ type MemberEnterTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - EntrantUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=entrantUser,proto3" json:"entrantUser"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + EntrantUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=entrantUser,proto3" json:"entrantUser"` OperationTime int64 `protobuf:"varint,3,opt,name=operationTime,proto3" json:"operationTime"` } @@ -2763,8 +2765,8 @@ type GroupDismissedTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` OperationTime int64 `protobuf:"varint,3,opt,name=operationTime,proto3" json:"operationTime"` } @@ -2826,11 +2828,11 @@ type GroupMemberMutedTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` OperationTime int64 `protobuf:"varint,3,opt,name=operationTime,proto3" json:"operationTime"` - MutedUser *GroupMemberFullInfo `protobuf:"bytes,4,opt,name=mutedUser,proto3" json:"mutedUser"` - MutedSeconds uint32 `protobuf:"varint,5,opt,name=mutedSeconds,proto3" json:"mutedSeconds"` + MutedUser *GroupMemberFullInfo `protobuf:"bytes,4,opt,name=mutedUser,proto3" json:"mutedUser"` + MutedSeconds uint32 `protobuf:"varint,5,opt,name=mutedSeconds,proto3" json:"mutedSeconds"` } func (x *GroupMemberMutedTips) Reset() { @@ -2905,10 +2907,10 @@ type GroupMemberCancelMutedTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` OperationTime int64 `protobuf:"varint,3,opt,name=operationTime,proto3" json:"operationTime"` - MutedUser *GroupMemberFullInfo `protobuf:"bytes,4,opt,name=mutedUser,proto3" json:"mutedUser"` + MutedUser *GroupMemberFullInfo `protobuf:"bytes,4,opt,name=mutedUser,proto3" json:"mutedUser"` } func (x *GroupMemberCancelMutedTips) Reset() { @@ -2976,8 +2978,8 @@ type GroupMutedTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` OperationTime int64 `protobuf:"varint,3,opt,name=operationTime,proto3" json:"operationTime"` } @@ -3039,8 +3041,8 @@ type GroupCancelMutedTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` OperationTime int64 `protobuf:"varint,3,opt,name=operationTime,proto3" json:"operationTime"` } @@ -3102,10 +3104,10 @@ type GroupMemberInfoSetTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` OperationTime int64 `protobuf:"varint,3,opt,name=operationTime,proto3" json:"operationTime"` - ChangedUser *GroupMemberFullInfo `protobuf:"bytes,4,opt,name=changedUser,proto3" json:"changedUser"` + ChangedUser *GroupMemberFullInfo `protobuf:"bytes,4,opt,name=changedUser,proto3" json:"changedUser"` } func (x *GroupMemberInfoSetTips) Reset() { @@ -3173,8 +3175,8 @@ type FriendApplication struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - AddTime int64 `protobuf:"varint,1,opt,name=addTime,proto3" json:"addTime"` - AddSource string `protobuf:"bytes,2,opt,name=addSource,proto3" json:"addSource"` + AddTime int64 `protobuf:"varint,1,opt,name=addTime,proto3" json:"addTime"` + AddSource string `protobuf:"bytes,2,opt,name=addSource,proto3" json:"addSource"` AddWording string `protobuf:"bytes,3,opt,name=addWording,proto3" json:"addWording"` } @@ -3237,7 +3239,7 @@ type FromToUserID struct { unknownFields protoimpl.UnknownFields FromUserID string `protobuf:"bytes,1,opt,name=fromUserID,proto3" json:"fromUserID"` - ToUserID string `protobuf:"bytes,2,opt,name=toUserID,proto3" json:"toUserID"` + ToUserID string `protobuf:"bytes,2,opt,name=toUserID,proto3" json:"toUserID"` } func (x *FromToUserID) Reset() { @@ -3341,7 +3343,7 @@ type FriendApplicationApprovedTips struct { unknownFields protoimpl.UnknownFields FromToUserID *FromToUserID `protobuf:"bytes,1,opt,name=fromToUserID,proto3" json:"fromToUserID"` //from:同意者;to:请求发起者 - HandleMsg string `protobuf:"bytes,2,opt,name=handleMsg,proto3" json:"handleMsg"` + HandleMsg string `protobuf:"bytes,2,opt,name=handleMsg,proto3" json:"handleMsg"` } func (x *FriendApplicationApprovedTips) Reset() { @@ -3397,7 +3399,7 @@ type FriendApplicationRejectedTips struct { unknownFields protoimpl.UnknownFields FromToUserID *FromToUserID `protobuf:"bytes,1,opt,name=fromToUserID,proto3" json:"fromToUserID"` //from:拒绝者;to:请求发起者 - HandleMsg string `protobuf:"bytes,2,opt,name=handleMsg,proto3" json:"handleMsg"` + HandleMsg string `protobuf:"bytes,2,opt,name=handleMsg,proto3" json:"handleMsg"` } func (x *FriendApplicationRejectedTips) Reset() { @@ -3452,9 +3454,9 @@ type FriendAddedTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Friend *FriendInfo `protobuf:"bytes,1,opt,name=friend,proto3" json:"friend"` + Friend *FriendInfo `protobuf:"bytes,1,opt,name=friend,proto3" json:"friend"` OperationTime int64 `protobuf:"varint,2,opt,name=operationTime,proto3" json:"operationTime"` - OpUser *PublicUserInfo `protobuf:"bytes,3,opt,name=opUser,proto3" json:"opUser"` //who do this + OpUser *PublicUserInfo `protobuf:"bytes,3,opt,name=opUser,proto3" json:"opUser"` //who do this } func (x *FriendAddedTips) Reset() { @@ -3753,7 +3755,7 @@ type ConversationUpdateTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` ConversationIDList []string `protobuf:"bytes,2,rep,name=conversationIDList,proto3" json:"conversationIDList"` } @@ -3808,8 +3810,8 @@ type ConversationSetPrivateTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - RecvID string `protobuf:"bytes,1,opt,name=recvID,proto3" json:"recvID"` - SendID string `protobuf:"bytes,2,opt,name=sendID,proto3" json:"sendID"` + RecvID string `protobuf:"bytes,1,opt,name=recvID,proto3" json:"recvID"` + SendID string `protobuf:"bytes,2,opt,name=sendID,proto3" json:"sendID"` IsPrivate bool `protobuf:"varint,3,opt,name=isPrivate,proto3" json:"isPrivate"` } @@ -3871,9 +3873,9 @@ type ConversationHasReadTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` - ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` - HasReadSeq int64 `protobuf:"varint,3,opt,name=hasReadSeq,proto3" json:"hasReadSeq"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` + HasReadSeq int64 `protobuf:"varint,3,opt,name=hasReadSeq,proto3" json:"hasReadSeq"` UnreadCountTime int64 `protobuf:"varint,4,opt,name=unreadCountTime,proto3" json:"unreadCountTime"` } @@ -4037,8 +4039,8 @@ type DeleteMessageTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OpUserID string `protobuf:"bytes,1,opt,name=opUserID,proto3" json:"opUserID"` - UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` + OpUserID string `protobuf:"bytes,1,opt,name=opUserID,proto3" json:"opUserID"` + UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` Seqs []int64 `protobuf:"varint,3,rep,packed,name=seqs,proto3" json:"seqs"` } @@ -4100,11 +4102,11 @@ type RevokeMsgTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - RevokerUserID string `protobuf:"bytes,1,opt,name=revokerUserID,proto3" json:"revokerUserID"` - ClientMsgID string `protobuf:"bytes,2,opt,name=clientMsgID,proto3" json:"clientMsgID"` - RevokeTime int64 `protobuf:"varint,3,opt,name=revokeTime,proto3" json:"revokeTime"` - SesstionType int32 `protobuf:"varint,5,opt,name=sesstionType,proto3" json:"sesstionType"` - Seq int64 `protobuf:"varint,6,opt,name=seq,proto3" json:"seq"` + RevokerUserID string `protobuf:"bytes,1,opt,name=revokerUserID,proto3" json:"revokerUserID"` + ClientMsgID string `protobuf:"bytes,2,opt,name=clientMsgID,proto3" json:"clientMsgID"` + RevokeTime int64 `protobuf:"varint,3,opt,name=revokeTime,proto3" json:"revokeTime"` + SesstionType int32 `protobuf:"varint,5,opt,name=sesstionType,proto3" json:"sesstionType"` + Seq int64 `protobuf:"varint,6,opt,name=seq,proto3" json:"seq"` ConversationID string `protobuf:"bytes,7,opt,name=conversationID,proto3" json:"conversationID"` } @@ -4187,17 +4189,17 @@ type MessageRevokedContent struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - RevokerID string `protobuf:"bytes,1,opt,name=revokerID,proto3" json:"revokerID"` - RevokerRole int32 `protobuf:"varint,2,opt,name=revokerRole,proto3" json:"revokerRole"` - ClientMsgID string `protobuf:"bytes,3,opt,name=clientMsgID,proto3" json:"clientMsgID"` - RevokerNickname string `protobuf:"bytes,4,opt,name=revokerNickname,proto3" json:"revokerNickname"` - RevokeTime int64 `protobuf:"varint,5,opt,name=revokeTime,proto3" json:"revokeTime"` - SourceMessageSendTime int64 `protobuf:"varint,6,opt,name=sourceMessageSendTime,proto3" json:"sourceMessageSendTime"` - SourceMessageSendID string `protobuf:"bytes,7,opt,name=sourceMessageSendID,proto3" json:"sourceMessageSendID"` + RevokerID string `protobuf:"bytes,1,opt,name=revokerID,proto3" json:"revokerID"` + RevokerRole int32 `protobuf:"varint,2,opt,name=revokerRole,proto3" json:"revokerRole"` + ClientMsgID string `protobuf:"bytes,3,opt,name=clientMsgID,proto3" json:"clientMsgID"` + RevokerNickname string `protobuf:"bytes,4,opt,name=revokerNickname,proto3" json:"revokerNickname"` + RevokeTime int64 `protobuf:"varint,5,opt,name=revokeTime,proto3" json:"revokeTime"` + SourceMessageSendTime int64 `protobuf:"varint,6,opt,name=sourceMessageSendTime,proto3" json:"sourceMessageSendTime"` + SourceMessageSendID string `protobuf:"bytes,7,opt,name=sourceMessageSendID,proto3" json:"sourceMessageSendID"` SourceMessageSenderNickname string `protobuf:"bytes,8,opt,name=sourceMessageSenderNickname,proto3" json:"sourceMessageSenderNickname"` - SessionType int32 `protobuf:"varint,10,opt,name=sessionType,proto3" json:"sessionType"` - Seq int64 `protobuf:"varint,11,opt,name=seq,proto3" json:"seq"` - Ex string `protobuf:"bytes,12,opt,name=ex,proto3" json:"ex"` + SessionType int32 `protobuf:"varint,10,opt,name=sessionType,proto3" json:"sessionType"` + Seq int64 `protobuf:"varint,11,opt,name=seq,proto3" json:"seq"` + Ex string `protobuf:"bytes,12,opt,name=ex,proto3" json:"ex"` } func (x *MessageRevokedContent) Reset() { @@ -4314,7 +4316,7 @@ type ClearConversationTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` ConversationIDs []string `protobuf:"bytes,2,rep,name=conversationIDs,proto3" json:"conversationIDs"` } @@ -4369,9 +4371,9 @@ type DeleteMsgsTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` - Seqs []int64 `protobuf:"varint,3,rep,packed,name=seqs,proto3" json:"seqs"` + Seqs []int64 `protobuf:"varint,3,rep,packed,name=seqs,proto3" json:"seqs"` } func (x *DeleteMsgsTips) Reset() { @@ -4433,9 +4435,9 @@ type MarkAsReadTips struct { unknownFields protoimpl.UnknownFields MarkAsReadUserID string `protobuf:"bytes,1,opt,name=markAsReadUserID,proto3" json:"markAsReadUserID"` - ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` - Seqs []int64 `protobuf:"varint,3,rep,packed,name=seqs,proto3" json:"seqs"` - HasReadSeq int64 `protobuf:"varint,4,opt,name=hasReadSeq,proto3" json:"hasReadSeq"` + ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` + Seqs []int64 `protobuf:"varint,3,rep,packed,name=seqs,proto3" json:"seqs"` + HasReadSeq int64 `protobuf:"varint,4,opt,name=hasReadSeq,proto3" json:"hasReadSeq"` } func (x *MarkAsReadTips) Reset() { @@ -4503,7 +4505,7 @@ type SetAppBackgroundStatusReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` IsBackground bool `protobuf:"varint,2,opt,name=isBackground,proto3" json:"isBackground"` } diff --git a/pkg/proto/statistics/statistics.pb.go b/pkg/proto/statistics/statistics.pb.go index 5660758f9..5e03e9797 100644 --- a/pkg/proto/statistics/statistics.pb.go +++ b/pkg/proto/statistics/statistics.pb.go @@ -21,9 +21,10 @@ package statistics import ( + reflect "reflect" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" ) const ( diff --git a/pkg/proto/third/third.pb.go b/pkg/proto/third/third.pb.go index 155b5f7cc..a098b296f 100644 --- a/pkg/proto/third/third.pb.go +++ b/pkg/proto/third/third.pb.go @@ -22,13 +22,14 @@ package third import ( context "context" + reflect "reflect" + sync "sync" + grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" ) const ( @@ -43,7 +44,7 @@ type KeyValues struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key"` Values []string `protobuf:"bytes,2,rep,name=values,proto3" json:"values"` } @@ -99,9 +100,9 @@ type SignPart struct { unknownFields protoimpl.UnknownFields PartNumber int32 `protobuf:"varint,1,opt,name=partNumber,proto3" json:"partNumber"` - Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url"` - Query []*KeyValues `protobuf:"bytes,3,rep,name=query,proto3" json:"query"` - Header []*KeyValues `protobuf:"bytes,4,rep,name=header,proto3" json:"header"` + Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url"` + Query []*KeyValues `protobuf:"bytes,3,rep,name=query,proto3" json:"query"` + Header []*KeyValues `protobuf:"bytes,4,rep,name=header,proto3" json:"header"` } func (x *SignPart) Reset() { @@ -169,10 +170,10 @@ type AuthSignParts struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url"` - Query []*KeyValues `protobuf:"bytes,2,rep,name=query,proto3" json:"query"` + Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url"` + Query []*KeyValues `protobuf:"bytes,2,rep,name=query,proto3" json:"query"` Header []*KeyValues `protobuf:"bytes,3,rep,name=header,proto3" json:"header"` - Parts []*SignPart `protobuf:"bytes,4,rep,name=parts,proto3" json:"parts"` + Parts []*SignPart `protobuf:"bytes,4,rep,name=parts,proto3" json:"parts"` } func (x *AuthSignParts) Reset() { @@ -280,7 +281,7 @@ type PartLimitResp struct { MinPartSize int64 `protobuf:"varint,1,opt,name=minPartSize,proto3" json:"minPartSize"` MaxPartSize int64 `protobuf:"varint,2,opt,name=maxPartSize,proto3" json:"maxPartSize"` - MaxNumSize int32 `protobuf:"varint,3,opt,name=maxNumSize,proto3" json:"maxNumSize"` + MaxNumSize int32 `protobuf:"varint,3,opt,name=maxNumSize,proto3" json:"maxNumSize"` } func (x *PartLimitResp) Reset() { @@ -435,12 +436,12 @@ type InitiateMultipartUploadReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Hash string `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash"` - Size int64 `protobuf:"varint,2,opt,name=size,proto3" json:"size"` - PartSize int64 `protobuf:"varint,3,opt,name=partSize,proto3" json:"partSize"` - MaxParts int32 `protobuf:"varint,4,opt,name=maxParts,proto3" json:"maxParts"` - Cause string `protobuf:"bytes,5,opt,name=cause,proto3" json:"cause"` - Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name"` + Hash string `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash"` + Size int64 `protobuf:"varint,2,opt,name=size,proto3" json:"size"` + PartSize int64 `protobuf:"varint,3,opt,name=partSize,proto3" json:"partSize"` + MaxParts int32 `protobuf:"varint,4,opt,name=maxParts,proto3" json:"maxParts"` + Cause string `protobuf:"bytes,5,opt,name=cause,proto3" json:"cause"` + Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name"` ContentType string `protobuf:"bytes,7,opt,name=contentType,proto3" json:"contentType"` } @@ -530,9 +531,9 @@ type UploadInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UploadID string `protobuf:"bytes,1,opt,name=uploadID,proto3" json:"uploadID"` - PartSize int64 `protobuf:"varint,2,opt,name=partSize,proto3" json:"partSize"` - Sign *AuthSignParts `protobuf:"bytes,3,opt,name=sign,proto3" json:"sign"` + UploadID string `protobuf:"bytes,1,opt,name=uploadID,proto3" json:"uploadID"` + PartSize int64 `protobuf:"varint,2,opt,name=partSize,proto3" json:"partSize"` + Sign *AuthSignParts `protobuf:"bytes,3,opt,name=sign,proto3" json:"sign"` ExpireTime int64 `protobuf:"varint,4,opt,name=expireTime,proto3" json:"expireTime"` } @@ -601,7 +602,7 @@ type InitiateMultipartUploadResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url"` + Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url"` Upload *UploadInfo `protobuf:"bytes,2,opt,name=upload,proto3" json:"upload"` } @@ -656,7 +657,7 @@ type AuthSignReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UploadID string `protobuf:"bytes,1,opt,name=uploadID,proto3" json:"uploadID"` + UploadID string `protobuf:"bytes,1,opt,name=uploadID,proto3" json:"uploadID"` PartNumbers []int32 `protobuf:"varint,2,rep,packed,name=partNumbers,proto3" json:"partNumbers"` } @@ -711,10 +712,10 @@ type AuthSignResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url"` - Query []*KeyValues `protobuf:"bytes,2,rep,name=query,proto3" json:"query"` + Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url"` + Query []*KeyValues `protobuf:"bytes,2,rep,name=query,proto3" json:"query"` Header []*KeyValues `protobuf:"bytes,3,rep,name=header,proto3" json:"header"` - Parts []*SignPart `protobuf:"bytes,4,rep,name=parts,proto3" json:"parts"` + Parts []*SignPart `protobuf:"bytes,4,rep,name=parts,proto3" json:"parts"` } func (x *AuthSignResp) Reset() { @@ -782,11 +783,11 @@ type CompleteMultipartUploadReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UploadID string `protobuf:"bytes,1,opt,name=uploadID,proto3" json:"uploadID"` - Parts []string `protobuf:"bytes,2,rep,name=parts,proto3" json:"parts"` - Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name"` + UploadID string `protobuf:"bytes,1,opt,name=uploadID,proto3" json:"uploadID"` + Parts []string `protobuf:"bytes,2,rep,name=parts,proto3" json:"parts"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name"` ContentType string `protobuf:"bytes,4,opt,name=contentType,proto3" json:"contentType"` - Cause string `protobuf:"bytes,5,opt,name=cause,proto3" json:"cause"` + Cause string `protobuf:"bytes,5,opt,name=cause,proto3" json:"cause"` } func (x *CompleteMultipartUploadReq) Reset() { @@ -955,7 +956,7 @@ type AccessURLResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url"` + Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url"` ExpireTime int64 `protobuf:"varint,2,opt,name=expireTime,proto3" json:"expireTime"` } @@ -1011,8 +1012,8 @@ type FcmUpdateTokenReq struct { unknownFields protoimpl.UnknownFields PlatformID int32 `protobuf:"varint,1,opt,name=platformID,proto3" json:"platformID"` - FcmToken string `protobuf:"bytes,2,opt,name=fcmToken,proto3" json:"fcmToken"` - Account string `protobuf:"bytes,3,opt,name=account,proto3" json:"account"` + FcmToken string `protobuf:"bytes,2,opt,name=fcmToken,proto3" json:"fcmToken"` + Account string `protobuf:"bytes,3,opt,name=account,proto3" json:"account"` ExpireTime int64 `protobuf:"varint,4,opt,name=expireTime,proto3" json:"expireTime"` } @@ -1119,7 +1120,7 @@ type SetAppBadgeReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` AppUnreadCount int32 `protobuf:"varint,2,opt,name=appUnreadCount,proto3" json:"appUnreadCount"` } diff --git a/pkg/proto/user/user.pb.go b/pkg/proto/user/user.pb.go index 5046505db..12a1bd2c8 100644 --- a/pkg/proto/user/user.pb.go +++ b/pkg/proto/user/user.pb.go @@ -22,15 +22,17 @@ package user import ( context "context" - conversation "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/conversation" - sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" + reflect "reflect" + sync "sync" + grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" + + conversation "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/conversation" + sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" ) const ( @@ -92,7 +94,7 @@ type GetAllUserIDResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Total int32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` + Total int32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` UserIDs []string `protobuf:"bytes,2,rep,name=userIDs,proto3" json:"userIDs"` } @@ -420,7 +422,7 @@ type SetGlobalRecvMessageOptReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` GlobalRecvMsgOpt int32 `protobuf:"varint,3,opt,name=globalRecvMsgOpt,proto3" json:"globalRecvMsgOpt"` } @@ -513,9 +515,9 @@ type SetConversationReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Conversation *conversation.Conversation `protobuf:"bytes,1,opt,name=conversation,proto3" json:"conversation"` + Conversation *conversation.Conversation `protobuf:"bytes,1,opt,name=conversation,proto3" json:"conversation"` NotificationType int32 `protobuf:"varint,2,opt,name=notificationType,proto3" json:"notificationType"` - OperationID string `protobuf:"bytes,3,opt,name=operationID,proto3" json:"operationID"` + OperationID string `protobuf:"bytes,3,opt,name=operationID,proto3" json:"operationID"` } func (x *SetConversationReq) Reset() { @@ -614,11 +616,11 @@ type SetRecvMsgOptReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` - ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` - RecvMsgOpt int32 `protobuf:"varint,3,opt,name=recvMsgOpt,proto3" json:"recvMsgOpt"` + OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` + ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` + RecvMsgOpt int32 `protobuf:"varint,3,opt,name=recvMsgOpt,proto3" json:"recvMsgOpt"` NotificationType int32 `protobuf:"varint,4,opt,name=notificationType,proto3" json:"notificationType"` - OperationID string `protobuf:"bytes,5,opt,name=operationID,proto3" json:"operationID"` + OperationID string `protobuf:"bytes,5,opt,name=operationID,proto3" json:"operationID"` } func (x *SetRecvMsgOptReq) Reset() { @@ -732,8 +734,8 @@ type GetConversationReq struct { unknownFields protoimpl.UnknownFields ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` - OwnerUserID string `protobuf:"bytes,2,opt,name=ownerUserID,proto3" json:"ownerUserID"` - OperationID string `protobuf:"bytes,3,opt,name=operationID,proto3" json:"operationID"` + OwnerUserID string `protobuf:"bytes,2,opt,name=ownerUserID,proto3" json:"ownerUserID"` + OperationID string `protobuf:"bytes,3,opt,name=operationID,proto3" json:"operationID"` } func (x *GetConversationReq) Reset() { @@ -841,9 +843,9 @@ type GetConversationsReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` + OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` ConversationIDs []string `protobuf:"bytes,2,rep,name=conversationIDs,proto3" json:"conversationIDs"` - OperationID string `protobuf:"bytes,3,opt,name=operationID,proto3" json:"operationID"` + OperationID string `protobuf:"bytes,3,opt,name=operationID,proto3" json:"operationID"` } func (x *GetConversationsReq) Reset() { @@ -1053,10 +1055,10 @@ type BatchSetConversationsReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Conversations []*conversation.Conversation `protobuf:"bytes,1,rep,name=conversations,proto3" json:"conversations"` - OwnerUserID string `protobuf:"bytes,2,opt,name=OwnerUserID,proto3" json:"OwnerUserID"` + Conversations []*conversation.Conversation `protobuf:"bytes,1,rep,name=conversations,proto3" json:"conversations"` + OwnerUserID string `protobuf:"bytes,2,opt,name=OwnerUserID,proto3" json:"OwnerUserID"` NotificationType int32 `protobuf:"varint,3,opt,name=notificationType,proto3" json:"notificationType"` - OperationID string `protobuf:"bytes,4,opt,name=OperationID,proto3" json:"OperationID"` + OperationID string `protobuf:"bytes,4,opt,name=OperationID,proto3" json:"OperationID"` } func (x *BatchSetConversationsReq) Reset() { @@ -1125,7 +1127,7 @@ type BatchSetConversationsResp struct { unknownFields protoimpl.UnknownFields Success []string `protobuf:"bytes,2,rep,name=Success,proto3" json:"Success"` - Failed []string `protobuf:"bytes,3,rep,name=Failed,proto3" json:"Failed"` + Failed []string `protobuf:"bytes,3,rep,name=Failed,proto3" json:"Failed"` } func (x *BatchSetConversationsResp) Reset() { @@ -1227,7 +1229,7 @@ type GetPaginationUsersResp struct { unknownFields protoimpl.UnknownFields Total int32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` - Users []*sdkws.UserInfo `protobuf:"bytes,2,rep,name=users,proto3" json:"users"` + Users []*sdkws.UserInfo `protobuf:"bytes,2,rep,name=users,proto3" json:"users"` } func (x *GetPaginationUsersResp) Reset() { @@ -1282,7 +1284,7 @@ type UserRegisterReq struct { unknownFields protoimpl.UnknownFields Secret string `protobuf:"bytes,1,opt,name=secret,proto3" json:"secret"` - Users []*sdkws.UserInfo `protobuf:"bytes,2,rep,name=users,proto3" json:"users"` + Users []*sdkws.UserInfo `protobuf:"bytes,2,rep,name=users,proto3" json:"users"` } func (x *UserRegisterReq) Reset() { @@ -1469,7 +1471,7 @@ type UserRegisterCountReq struct { unknownFields protoimpl.UnknownFields Start int64 `protobuf:"varint,1,opt,name=start,proto3" json:"start"` - End int64 `protobuf:"varint,2,opt,name=end,proto3" json:"end"` + End int64 `protobuf:"varint,2,opt,name=end,proto3" json:"end"` } func (x *UserRegisterCountReq) Reset() { @@ -1523,9 +1525,9 @@ type UserRegisterCountResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Total int64 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` + Total int64 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` Before int64 `protobuf:"varint,2,opt,name=before,proto3" json:"before"` - Count map[string]int64 `protobuf:"bytes,3,rep,name=count,proto3" json:"count" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + Count map[string]int64 `protobuf:"bytes,3,rep,name=count,proto3" json:"count" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` } func (x *UserRegisterCountResp) Reset() { @@ -1586,7 +1588,7 @@ type AccountCheckRespSingleUserStatus struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` AccountStatus string `protobuf:"bytes,2,opt,name=accountStatus,proto3" json:"accountStatus"` } diff --git a/pkg/proto/wrapperspb/wrapperspb.pb.go b/pkg/proto/wrapperspb/wrapperspb.pb.go index 9678bb2a0..c08a87822 100644 --- a/pkg/proto/wrapperspb/wrapperspb.pb.go +++ b/pkg/proto/wrapperspb/wrapperspb.pb.go @@ -21,10 +21,11 @@ package wrapperspb import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( From d3d4ab3ae527c6bc714fc912ea25e6c1c1209016 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Sun, 23 Jul 2023 11:44:33 +0800 Subject: [PATCH 39/62] fix: changing naming irregularities under pkg and internal packages (#520) --- pkg/common/mw/rpc_server_interceptor.go | 12 ++-- pkg/common/mw/specialerror/error.go | 11 +++- pkg/common/prome/gather.go | 39 ++++++++++++ pkg/common/prome/prometheus.go | 9 +++ pkg/common/tokenverify/jwt_token.go | 15 +++++ pkg/discoveryregistry/discovery_register.go | 2 + pkg/discoveryregistry/zookeeper/conf.go | 4 ++ pkg/discoveryregistry/zookeeper/discover.go | 10 +++ pkg/discoveryregistry/zookeeper/register.go | 8 +++ pkg/discoveryregistry/zookeeper/resolver.go | 10 +++ pkg/discoveryregistry/zookeeper/zk.go | 18 ++++++ pkg/errs/coderr.go | 11 +++- pkg/errs/relation.go | 2 + pkg/proto/auth/auth.go | 6 ++ pkg/proto/conversation/conversation.go | 48 +++++++++++--- pkg/proto/friend/friend.go | 30 +++++++++ pkg/proto/group/group.go | 66 ++++++++++++++++++++ pkg/proto/msg/msg.go | 44 ++++++++++--- pkg/proto/msggateway/msggateway.go | 10 +++ pkg/proto/push/push.go | 4 ++ pkg/proto/sdkws/sdkws.go | 2 + pkg/proto/third/third.go | 24 ++++--- pkg/proto/user/user.go | 30 +++++++++ pkg/proto/wrapperspb/wrapperspb.go | 69 +++++++++++++++++++++ pkg/rpcclient/auth.go | 3 + pkg/rpcclient/conversation.go | 23 +++++++ pkg/rpcclient/friend.go | 14 ++++- pkg/rpcclient/group.go | 28 +++++++++ pkg/rpcclient/msg.go | 7 +++ pkg/rpcclient/notification/group.go | 1 + pkg/statistics/statistics.go | 2 - 31 files changed, 524 insertions(+), 38 deletions(-) diff --git a/pkg/common/mw/rpc_server_interceptor.go b/pkg/common/mw/rpc_server_interceptor.go index ec43069da..0dba76103 100644 --- a/pkg/common/mw/rpc_server_interceptor.go +++ b/pkg/common/mw/rpc_server_interceptor.go @@ -38,6 +38,7 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/errinfo" ) +// rpcString func rpcString(v interface{}) string { if s, ok := v.(interface{ String() string }); ok { return s.String() @@ -45,6 +46,7 @@ func rpcString(v interface{}) string { return fmt.Sprintf("%+v", v) } +// RpcServerInterceptor func RpcServerInterceptor( ctx context.Context, req interface{}, @@ -52,7 +54,7 @@ func RpcServerInterceptor( handler grpc.UnaryHandler, ) (resp interface{}, err error) { log.ZDebug(ctx, "rpc server req", "req", rpcString(req)) - //defer func() { + // defer func() { // if r := recover(); r != nil { // log.ZError(ctx, "rpc panic", nil, "FullMethod", info.FullMethod, "type:", fmt.Sprintf("%T", r), "panic:", r) // fmt.Printf("panic: %+v\nstack info: %s\n", r, string(debug.Stack())) @@ -74,7 +76,7 @@ func RpcServerInterceptor( // } // err = sta.Err() // } - //}() + // }() funcName := info.FullMethod md, ok := metadata.FromIncomingContext(ctx) if !ok { @@ -133,8 +135,8 @@ func RpcServerInterceptor( var errInfo *errinfo.ErrorInfo if config.Config.Log.WithStack { if unwrap != err { - sti, ok := err.(interface{ StackTrace() errors.StackTrace }) - if ok { + var sti interface{ StackTrace() errors.StackTrace } + if errors.As(err, &sti) { log.ZWarn( ctx, "rpc server resp", @@ -173,9 +175,11 @@ func RpcServerInterceptor( return nil, errs.Wrap(err) } log.ZWarn(ctx, "rpc server resp", err, "funcName", funcName) + return nil, details.Err() } +// GrpcServer func GrpcServer() grpc.ServerOption { return grpc.ChainUnaryInterceptor(RpcServerInterceptor) } diff --git a/pkg/common/mw/specialerror/error.go b/pkg/common/mw/specialerror/error.go index b8b8d27ae..b843ad0d6 100644 --- a/pkg/common/mw/specialerror/error.go +++ b/pkg/common/mw/specialerror/error.go @@ -14,10 +14,14 @@ package specialerror -import "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" +import ( + "errors" + "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" +) var handlers []func(err error) errs.CodeError +// AddErrHandler func AddErrHandler(h func(err error) errs.CodeError) { if h == nil { panic("nil handler") @@ -27,13 +31,15 @@ func AddErrHandler(h func(err error) errs.CodeError) { func AddReplace(target error, codeErr errs.CodeError) { AddErrHandler(func(err error) errs.CodeError { - if err == target { + if errors.Is(err, target) { return codeErr } + return nil }) } +// ErrCode func ErrCode(err error) errs.CodeError { if codeErr, ok := err.(errs.CodeError); ok { return codeErr @@ -43,5 +49,6 @@ func ErrCode(err error) errs.CodeError { return codeErr } } + return nil } diff --git a/pkg/common/prome/gather.go b/pkg/common/prome/gather.go index eb4bc6c3b..58305396d 100644 --- a/pkg/common/prome/gather.go +++ b/pkg/common/prome/gather.go @@ -79,6 +79,7 @@ var ( ConversationCreateFailedCounter prometheus.Counter ) +// NewUserLoginCounter func NewUserLoginCounter() { if UserLoginCounter != nil { return @@ -89,6 +90,7 @@ func NewUserLoginCounter() { }) } +// NewUserRegisterCounter func NewUserRegisterCounter() { if UserRegisterCounter != nil { return @@ -99,6 +101,7 @@ func NewUserRegisterCounter() { }) } +// NewSeqGetSuccessCounter func NewSeqGetSuccessCounter() { if SeqGetSuccessCounter != nil { return @@ -109,6 +112,7 @@ func NewSeqGetSuccessCounter() { }) } +// NewSeqGetFailedCounter func NewSeqGetFailedCounter() { if SeqGetFailedCounter != nil { return @@ -119,6 +123,7 @@ func NewSeqGetFailedCounter() { }) } +// NewSeqSetSuccessCounter func NewSeqSetSuccessCounter() { if SeqSetSuccessCounter != nil { return @@ -129,6 +134,7 @@ func NewSeqSetSuccessCounter() { }) } +// NewSeqSetFailedCounter func NewSeqSetFailedCounter() { if SeqSetFailedCounter != nil { return @@ -139,6 +145,7 @@ func NewSeqSetFailedCounter() { }) } +// NewApiRequestCounter func NewApiRequestCounter() { if ApiRequestCounter != nil { return @@ -149,6 +156,7 @@ func NewApiRequestCounter() { }) } +// NewApiRequestSuccessCounter func NewApiRequestSuccessCounter() { if ApiRequestSuccessCounter != nil { return @@ -159,6 +167,7 @@ func NewApiRequestSuccessCounter() { }) } +// NewApiRequestFailedCounter func NewApiRequestFailedCounter() { if ApiRequestFailedCounter != nil { return @@ -169,6 +178,7 @@ func NewApiRequestFailedCounter() { }) } +// NewGrpcRequestCounter func NewGrpcRequestCounter() { if GrpcRequestCounter != nil { return @@ -179,6 +189,7 @@ func NewGrpcRequestCounter() { }) } +// NewGrpcRequestSuccessCounter func NewGrpcRequestSuccessCounter() { if GrpcRequestSuccessCounter != nil { return @@ -189,6 +200,7 @@ func NewGrpcRequestSuccessCounter() { }) } +// NewGrpcRequestFailedCounter func NewGrpcRequestFailedCounter() { if GrpcRequestFailedCounter != nil { return @@ -199,6 +211,7 @@ func NewGrpcRequestFailedCounter() { }) } +// NewSendMsgCount func NewSendMsgCount() { if SendMsgCounter != nil { return @@ -209,6 +222,7 @@ func NewSendMsgCount() { }) } +// NewMsgInsertRedisSuccessCounter func NewMsgInsertRedisSuccessCounter() { if MsgInsertRedisSuccessCounter != nil { return @@ -219,6 +233,7 @@ func NewMsgInsertRedisSuccessCounter() { }) } +// NewMsgInsertRedisFailedCounter func NewMsgInsertRedisFailedCounter() { if MsgInsertRedisFailedCounter != nil { return @@ -229,6 +244,7 @@ func NewMsgInsertRedisFailedCounter() { }) } +// NewMsgInsertMongoSuccessCounter func NewMsgInsertMongoSuccessCounter() { if MsgInsertMongoSuccessCounter != nil { return @@ -239,6 +255,7 @@ func NewMsgInsertMongoSuccessCounter() { }) } +// NewMsgInsertMongoFailedCounter func NewMsgInsertMongoFailedCounter() { if MsgInsertMongoFailedCounter != nil { return @@ -249,6 +266,7 @@ func NewMsgInsertMongoFailedCounter() { }) } +// NewMsgPullFromRedisSuccessCounter func NewMsgPullFromRedisSuccessCounter() { if MsgPullFromRedisSuccessCounter != nil { return @@ -259,6 +277,7 @@ func NewMsgPullFromRedisSuccessCounter() { }) } +// NewMsgPullFromRedisFailedCounter func NewMsgPullFromRedisFailedCounter() { if MsgPullFromRedisFailedCounter != nil { return @@ -269,6 +288,7 @@ func NewMsgPullFromRedisFailedCounter() { }) } +// NewMsgPullFromMongoSuccessCounter func NewMsgPullFromMongoSuccessCounter() { if MsgPullFromMongoSuccessCounter != nil { return @@ -279,6 +299,7 @@ func NewMsgPullFromMongoSuccessCounter() { }) } +// NewMsgPullFromMongoFailedCounter func NewMsgPullFromMongoFailedCounter() { if MsgPullFromMongoFailedCounter != nil { return @@ -289,6 +310,7 @@ func NewMsgPullFromMongoFailedCounter() { }) } +// NewMsgRecvTotalCounter func NewMsgRecvTotalCounter() { if MsgRecvTotalCounter != nil { return @@ -299,6 +321,7 @@ func NewMsgRecvTotalCounter() { }) } +// NewGetNewestSeqTotalCounter func NewGetNewestSeqTotalCounter() { if GetNewestSeqTotalCounter != nil { return @@ -309,6 +332,7 @@ func NewGetNewestSeqTotalCounter() { }) } +// NewPullMsgBySeqListTotalCounter func NewPullMsgBySeqListTotalCounter() { if PullMsgBySeqListTotalCounter != nil { return @@ -319,6 +343,7 @@ func NewPullMsgBySeqListTotalCounter() { }) } +// NewSingleChatMsgRecvSuccessCounter func NewSingleChatMsgRecvSuccessCounter() { if SingleChatMsgRecvSuccessCounter != nil { return @@ -329,6 +354,7 @@ func NewSingleChatMsgRecvSuccessCounter() { }) } +// NewGroupChatMsgRecvSuccessCounter func NewGroupChatMsgRecvSuccessCounter() { if GroupChatMsgRecvSuccessCounter != nil { return @@ -339,6 +365,7 @@ func NewGroupChatMsgRecvSuccessCounter() { }) } +// NewWorkSuperGroupChatMsgRecvSuccessCounter func NewWorkSuperGroupChatMsgRecvSuccessCounter() { if WorkSuperGroupChatMsgRecvSuccessCounter != nil { return @@ -349,6 +376,7 @@ func NewWorkSuperGroupChatMsgRecvSuccessCounter() { }) } +// NewOnlineUserGauges func NewOnlineUserGauges() { if OnlineUserGauge != nil { return @@ -359,6 +387,7 @@ func NewOnlineUserGauges() { }) } +// NewSingleChatMsgProcessSuccessCounter func NewSingleChatMsgProcessSuccessCounter() { if SingleChatMsgProcessSuccessCounter != nil { return @@ -369,6 +398,7 @@ func NewSingleChatMsgProcessSuccessCounter() { }) } +// NewSingleChatMsgProcessFailedCounter func NewSingleChatMsgProcessFailedCounter() { if SingleChatMsgProcessFailedCounter != nil { return @@ -379,6 +409,7 @@ func NewSingleChatMsgProcessFailedCounter() { }) } +// NewGroupChatMsgProcessSuccessCounter func NewGroupChatMsgProcessSuccessCounter() { if GroupChatMsgProcessSuccessCounter != nil { return @@ -389,6 +420,7 @@ func NewGroupChatMsgProcessSuccessCounter() { }) } +// NewGroupChatMsgProcessFailedCounter func NewGroupChatMsgProcessFailedCounter() { if GroupChatMsgProcessFailedCounter != nil { return @@ -399,6 +431,7 @@ func NewGroupChatMsgProcessFailedCounter() { }) } +// NewWorkSuperGroupChatMsgProcessSuccessCounter func NewWorkSuperGroupChatMsgProcessSuccessCounter() { if WorkSuperGroupChatMsgProcessSuccessCounter != nil { return @@ -409,6 +442,7 @@ func NewWorkSuperGroupChatMsgProcessSuccessCounter() { }) } +// NewWorkSuperGroupChatMsgProcessFailedCounter func NewWorkSuperGroupChatMsgProcessFailedCounter() { if WorkSuperGroupChatMsgProcessFailedCounter != nil { return @@ -419,6 +453,7 @@ func NewWorkSuperGroupChatMsgProcessFailedCounter() { }) } +// NewMsgOnlinePushSuccessCounter func NewMsgOnlinePushSuccessCounter() { if MsgOnlinePushSuccessCounter != nil { return @@ -429,6 +464,7 @@ func NewMsgOnlinePushSuccessCounter() { }) } +// NewMsgOfflinePushSuccessCounter func NewMsgOfflinePushSuccessCounter() { if MsgOfflinePushSuccessCounter != nil { return @@ -439,6 +475,7 @@ func NewMsgOfflinePushSuccessCounter() { }) } +// NewMsgOfflinePushFailedCounter func NewMsgOfflinePushFailedCounter() { if MsgOfflinePushFailedCounter != nil { return @@ -449,6 +486,7 @@ func NewMsgOfflinePushFailedCounter() { }) } +// NewConversationCreateSuccessCounter func NewConversationCreateSuccessCounter() { if ConversationCreateSuccessCounter != nil { return @@ -459,6 +497,7 @@ func NewConversationCreateSuccessCounter() { }) } +// NewConversationCreateFailedCounter func NewConversationCreateFailedCounter() { if ConversationCreateFailedCounter != nil { return diff --git a/pkg/common/prome/prometheus.go b/pkg/common/prome/prometheus.go index d66b1df70..dbaa3f10d 100644 --- a/pkg/common/prome/prometheus.go +++ b/pkg/common/prome/prometheus.go @@ -26,6 +26,7 @@ import ( "github.com/prometheus/client_golang/prometheus/promhttp" ) +// StartPrometheusSrv func StartPrometheusSrv(prometheusPort int) error { if config.Config.Prometheus.Enable { http.Handle("/metrics", promhttp.Handler()) @@ -35,6 +36,7 @@ func StartPrometheusSrv(prometheusPort int) error { return nil } +// PrometheusHandler func PrometheusHandler() gin.HandlerFunc { h := promhttp.Handler() return func(c *gin.Context) { @@ -42,16 +44,19 @@ func PrometheusHandler() gin.HandlerFunc { } } +// responseBodyWriter type responseBodyWriter struct { gin.ResponseWriter body *bytes.Buffer } +// Write func (r responseBodyWriter) Write(b []byte) (int, error) { r.body.Write(b) return r.ResponseWriter.Write(b) } +// PrometheusMiddleware func PrometheusMiddleware(c *gin.Context) { Inc(ApiRequestCounter) w := &responseBodyWriter{body: &bytes.Buffer{}, ResponseWriter: c.Writer} @@ -64,6 +69,7 @@ func PrometheusMiddleware(c *gin.Context) { } } +// Inc func Inc(counter prometheus.Counter) { if config.Config.Prometheus.Enable { if counter != nil { @@ -72,6 +78,7 @@ func Inc(counter prometheus.Counter) { } } +// Add func Add(counter prometheus.Counter, add int) { if config.Config.Prometheus.Enable { if counter != nil { @@ -80,6 +87,7 @@ func Add(counter prometheus.Counter, add int) { } } +// GaugeInc func GaugeInc(gauges prometheus.Gauge) { if config.Config.Prometheus.Enable { if gauges != nil { @@ -88,6 +96,7 @@ func GaugeInc(gauges prometheus.Gauge) { } } +// GaugeDec func GaugeDec(gauges prometheus.Gauge) { if config.Config.Prometheus.Enable { if gauges != nil { diff --git a/pkg/common/tokenverify/jwt_token.go b/pkg/common/tokenverify/jwt_token.go index 317347b1d..798f3699a 100644 --- a/pkg/common/tokenverify/jwt_token.go +++ b/pkg/common/tokenverify/jwt_token.go @@ -27,15 +27,18 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/utils" ) +// Claims type Claims struct { UserID string PlatformID int // login platform jwt.RegisteredClaims } +// BuildClaims func BuildClaims(uid string, platformID int, ttl int64) Claims { now := time.Now() before := now.Add(-time.Minute * 5) + return Claims{ UserID: uid, PlatformID: platformID, @@ -47,12 +50,14 @@ func BuildClaims(uid string, platformID int, ttl int64) Claims { } } +// secret func secret() jwt.Keyfunc { return func(token *jwt.Token) (interface{}, error) { return []byte(config.Config.Secret), nil } } +// GetClaimFromToken func GetClaimFromToken(tokensString string) (*Claims, error) { token, err := jwt.ParseWithClaims(tokensString, &Claims{}, secret()) if err != nil { @@ -73,10 +78,12 @@ func GetClaimFromToken(tokensString string) (*Claims, error) { if claims, ok := token.Claims.(*Claims); ok && token.Valid { return claims, nil } + return nil, utils.Wrap(errs.ErrTokenUnknown, "") } } +// CheckAccessV3 func CheckAccessV3(ctx context.Context, ownerUserID string) (err error) { opUserID := mcontext.GetOpUserID(ctx) if utils.IsContain(opUserID, config.Config.Manager.UserID) { @@ -85,28 +92,35 @@ func CheckAccessV3(ctx context.Context, ownerUserID string) (err error) { if opUserID == ownerUserID { return nil } + return errs.ErrNoPermission.Wrap(utils.GetSelfFuncName()) } +// IsAppManagerUid func IsAppManagerUid(ctx context.Context) bool { return utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.Manager.UserID) } +// CheckAdmin func CheckAdmin(ctx context.Context) error { if utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.Manager.UserID) { return nil } + return errs.ErrNoPermission.Wrap(fmt.Sprintf("user %s is not admin userID", mcontext.GetOpUserID(ctx))) } +// ParseRedisInterfaceToken func ParseRedisInterfaceToken(redisToken interface{}) (*Claims, error) { return GetClaimFromToken(string(redisToken.([]uint8))) } +// IsManagerUserID func IsManagerUserID(opUserID string) bool { return utils.IsContain(opUserID, config.Config.Manager.UserID) } +// WsVerifyToken func WsVerifyToken(token, userID string, platformID int) error { claim, err := GetClaimFromToken(token) if err != nil { @@ -118,5 +132,6 @@ func WsVerifyToken(token, userID string, platformID int) error { if claim.PlatformID != platformID { return errs.ErrTokenInvalid.Wrap(fmt.Sprintf("token platform %d != %d", claim.PlatformID, platformID)) } + return nil } diff --git a/pkg/discoveryregistry/discovery_register.go b/pkg/discoveryregistry/discovery_register.go index 4ebabe7a8..f81a91c7b 100644 --- a/pkg/discoveryregistry/discovery_register.go +++ b/pkg/discoveryregistry/discovery_register.go @@ -20,6 +20,7 @@ import ( "google.golang.org/grpc" ) +// Conn type Conn interface { GetConns(ctx context.Context, serviceName string, opts ...grpc.DialOption) ([]grpc.ClientConnInterface, error) GetConn(ctx context.Context, serviceName string, opts ...grpc.DialOption) (grpc.ClientConnInterface, error) @@ -29,6 +30,7 @@ type Conn interface { GetClientLocalConns() map[string][]grpc.ClientConnInterface } +// SvcDiscoveryRegistry type SvcDiscoveryRegistry interface { Conn Register(serviceName, host string, port int, opts ...grpc.DialOption) error diff --git a/pkg/discoveryregistry/zookeeper/conf.go b/pkg/discoveryregistry/zookeeper/conf.go index 034c525ba..8cfb504c1 100644 --- a/pkg/discoveryregistry/zookeeper/conf.go +++ b/pkg/discoveryregistry/zookeeper/conf.go @@ -18,6 +18,7 @@ import ( "github.com/go-zookeeper/zk" ) +// RegisterConf2Registry func (s *ZkClient) RegisterConf2Registry(key string, conf []byte) error { exists, _, err := s.conn.Exists(s.getPath(key)) if err != nil { @@ -32,10 +33,13 @@ func (s *ZkClient) RegisterConf2Registry(key string, conf []byte) error { if err != zk.ErrNodeExists { return err } + return nil } +// GetConfFromRegistry func (s *ZkClient) GetConfFromRegistry(key string) ([]byte, error) { bytes, _, err := s.conn.Get(s.getPath(key)) + return bytes, err } diff --git a/pkg/discoveryregistry/zookeeper/discover.go b/pkg/discoveryregistry/zookeeper/discover.go index 94cf1f84a..fc28dd388 100644 --- a/pkg/discoveryregistry/zookeeper/discover.go +++ b/pkg/discoveryregistry/zookeeper/discover.go @@ -35,6 +35,7 @@ var ( ErrConnIsNilButLocalNotNil = errors.New("conn is nil, but local is not nil") ) +// watch func (s *ZkClient) watch() { for { event := <-s.eventChan @@ -69,6 +70,7 @@ func (s *ZkClient) watch() { } } +// GetConnsRemote func (s *ZkClient) GetConnsRemote(serviceName string) (conns []resolver.Address, err error) { path := s.getPath(serviceName) _, _, _, err = s.conn.ChildrenW(path) @@ -86,15 +88,18 @@ func (s *ZkClient) GetConnsRemote(serviceName string) (conns []resolver.Address, if err == zk.ErrNoNode { return nil, errors.Wrap(err, "this is zk ErrNoNode") } + return nil, errors.Wrap(err, "get children error") } log.ZDebug(context.Background(), "get addrs from remote", "conn", string(data)) conns = append(conns, resolver.Address{Addr: string(data), ServerName: serviceName}) } } + return conns, nil } +// GetConns func (s *ZkClient) GetConns(ctx context.Context, serviceName string, opts ...grpc.DialOption) ([]grpc.ClientConnInterface, error) { s.logger.Printf("get conns from client, serviceName: %s", serviceName) s.lock.Lock() @@ -114,21 +119,26 @@ func (s *ZkClient) GetConns(ctx context.Context, serviceName string, opts ...grp cc, err := grpc.DialContext(ctx, addr.Addr, append(s.options, opts...)...) if err != nil { log.ZError(context.Background(), "dialContext failed", err, "addr", addr.Addr, "opts", append(s.options, opts...)) + return nil, errs.Wrap(err) } conns = append(conns, cc) } s.localConns[serviceName] = conns } + return conns, nil } +// GetConn func (s *ZkClient) GetConn(ctx context.Context, serviceName string, opts ...grpc.DialOption) (grpc.ClientConnInterface, error) { newOpts := append(s.options, grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, s.balancerName))) s.logger.Printf("get conn from client, serviceName: %s", serviceName) + return grpc.DialContext(ctx, fmt.Sprintf("%s:///%s", s.scheme, serviceName), append(newOpts, opts...)...) } +// CloseConn func (s *ZkClient) CloseConn(conn grpc.ClientConnInterface) { if closer, ok := conn.(io.Closer); ok { closer.Close() diff --git a/pkg/discoveryregistry/zookeeper/register.go b/pkg/discoveryregistry/zookeeper/register.go index 8fc5fa34e..dfdc567ee 100644 --- a/pkg/discoveryregistry/zookeeper/register.go +++ b/pkg/discoveryregistry/zookeeper/register.go @@ -21,16 +21,20 @@ import ( "google.golang.org/grpc" ) +// CreateRpcRootNodes func (s *ZkClient) CreateRpcRootNodes(serviceNames []string) error { for _, serviceName := range serviceNames { if err := s.ensureName(serviceName); err != nil && err != zk.ErrNodeExists { return err } } + return nil } +// CreateTempNode func (s *ZkClient) CreateTempNode(rpcRegisterName, addr string) (node string, err error) { + return s.conn.CreateProtectedEphemeralSequential( s.getPath(rpcRegisterName)+"/"+addr+"_", []byte(addr), @@ -38,6 +42,7 @@ func (s *ZkClient) CreateTempNode(rpcRegisterName, addr string) (node string, er ) } +// Register func (s *ZkClient) Register(rpcRegisterName, host string, port int, opts ...grpc.DialOption) error { if err := s.ensureName(rpcRegisterName); err != nil { return err @@ -55,9 +60,11 @@ func (s *ZkClient) Register(rpcRegisterName, host string, port int, opts ...grpc s.rpcRegisterAddr = addr s.node = node s.isRegistered = true + return nil } +// UnRegister func (s *ZkClient) UnRegister() error { s.lock.Lock() defer s.lock.Unlock() @@ -72,5 +79,6 @@ func (s *ZkClient) UnRegister() error { s.isRegistered = false s.localConns = make(map[string][]grpc.ClientConnInterface) s.resolvers = make(map[string]*Resolver) + return nil } diff --git a/pkg/discoveryregistry/zookeeper/resolver.go b/pkg/discoveryregistry/zookeeper/resolver.go index 7e9c8c125..792d904ba 100644 --- a/pkg/discoveryregistry/zookeeper/resolver.go +++ b/pkg/discoveryregistry/zookeeper/resolver.go @@ -23,6 +23,7 @@ import ( "google.golang.org/grpc/resolver" ) +// Resolver type Resolver struct { target resolver.Target cc resolver.ClientConn @@ -31,6 +32,7 @@ type Resolver struct { getConnsRemote func(serviceName string) (conns []resolver.Address, err error) } +// ResolveNowZK func (r *Resolver) ResolveNowZK(o resolver.ResolveNowOptions) { log.ZDebug( context.Background(), @@ -45,6 +47,7 @@ func (r *Resolver) ResolveNowZK(o resolver.ResolveNowOptions) { newConns, err := r.getConnsRemote(strings.TrimLeft(r.target.URL.Path, "/")) if err != nil { log.ZError(context.Background(), "resolve now error", err, "target", r.target) + return } r.addrs = newConns @@ -58,15 +61,19 @@ func (r *Resolver) ResolveNowZK(o resolver.ResolveNowOptions) { "zk path", r.target.URL.Path, ) + return } log.ZDebug(context.Background(), "resolve now finished", "target", r.target, "conns", r.addrs) } +// ResolveNow func (r *Resolver) ResolveNow(o resolver.ResolveNowOptions) {} +// Close func (s *Resolver) Close() {} +// Build func (s *ZkClient) Build( target resolver.Target, cc resolver.ClientConn, @@ -76,6 +83,7 @@ func (s *ZkClient) Build( serviceName := strings.TrimLeft(target.URL.Path, "/") if oldResolver, ok := s.resolvers[serviceName]; ok { s.logger.Printf("rpc resolver exist: %+v, cc: %+v, key: %s", target, cc.UpdateState, serviceName) + return oldResolver, nil } r := &Resolver{} @@ -87,7 +95,9 @@ func (s *ZkClient) Build( defer s.lock.Unlock() s.resolvers[serviceName] = r s.logger.Printf("build resolver finished: %+v, cc: %+v, key: %s", target, cc.UpdateState, serviceName) + return r, nil } +// Scheme func (s *ZkClient) Scheme() string { return s.scheme } diff --git a/pkg/discoveryregistry/zookeeper/zk.go b/pkg/discoveryregistry/zookeeper/zk.go index cc333c4b6..6237c0b02 100644 --- a/pkg/discoveryregistry/zookeeper/zk.go +++ b/pkg/discoveryregistry/zookeeper/zk.go @@ -30,10 +30,12 @@ const ( timeout = 5 ) +// Logger type Logger interface { Printf(string, ...interface{}) } +// ZkClient type ZkClient struct { zkServers []string zkRoot string @@ -62,14 +64,17 @@ type ZkClient struct { logger Logger } +// ZkOption type ZkOption func(*ZkClient) +// WithRoundRobin func WithRoundRobin() ZkOption { return func(client *ZkClient) { client.balancerName = "round_robin" } } +// WithUserNameAndPassword func WithUserNameAndPassword(userName, password string) ZkOption { return func(client *ZkClient) { client.userName = userName @@ -83,24 +88,28 @@ func WithOptions(opts ...grpc.DialOption) ZkOption { } } +// WithFreq func WithFreq(freq time.Duration) ZkOption { return func(client *ZkClient) { client.ticker = time.NewTicker(freq) } } +// WithTimeout func WithTimeout(timeout int) ZkOption { return func(client *ZkClient) { client.timeout = timeout } } +// WithLogger func WithLogger(logger Logger) ZkOption { return func(client *ZkClient) { client.logger = logger } } +// NewClient func NewClient(zkServers []string, zkRoot string, options ...ZkOption) (*ZkClient, error) { client := &ZkClient{ zkServers: zkServers, @@ -134,15 +143,18 @@ func NewClient(zkServers []string, zkRoot string, options ...ZkOption) (*ZkClien client.conn = conn if err := client.ensureRoot(); err != nil { client.CloseZK() + return nil, err } resolver.Register(client) go client.refresh() go client.watch() time.Sleep(time.Millisecond * 50) + return client, nil } +// CloseZK func (s *ZkClient) CloseZK() { s.conn.Close() } @@ -158,6 +170,7 @@ func (s *ZkClient) ensureAndCreate(node string) error { return err } } + return nil } @@ -189,14 +202,17 @@ func (s *ZkClient) flushResolver(serviceName string) { } } +// GetZkConn func (s *ZkClient) GetZkConn() *zk.Conn { return s.conn } +// GetRootPath func (s *ZkClient) GetRootPath() string { return s.zkRoot } +// GetNode func (s *ZkClient) GetNode() string { return s.node } @@ -217,10 +233,12 @@ func (s *ZkClient) getAddr(host string, port int) string { return net.JoinHostPort(host, strconv.Itoa(port)) } +// AddOption func (s *ZkClient) AddOption(opts ...grpc.DialOption) { s.options = append(s.options, opts...) } +// GetClientLocalConns func (s *ZkClient) GetClientLocalConns() map[string][]grpc.ClientConnInterface { return s.localConns } diff --git a/pkg/errs/coderr.go b/pkg/errs/coderr.go index af88a6353..5bd878922 100644 --- a/pkg/errs/coderr.go +++ b/pkg/errs/coderr.go @@ -15,12 +15,12 @@ package errs import ( - "fmt" "strings" "github.com/pkg/errors" ) +// CodeError type CodeError interface { Code() int Msg() string @@ -32,6 +32,7 @@ type CodeError interface { error } +// NewCodeError func NewCodeError(code int, msg string) CodeError { return &codeError{ code: code, @@ -64,6 +65,7 @@ func (e *codeError) WithDetail(detail string) CodeError { } else { d = e.detail + ", " + detail } + return &codeError{ code: e.code, msg: e.msg, @@ -93,13 +95,15 @@ func (e *codeError) Is(err error, loose ...bool) bool { return codeErr.Code() == e.code } } + return false } func (e *codeError) Error() string { - return fmt.Sprintf("%s", e.msg) + return e.msg } +// Unwrap func Unwrap(err error) error { for err != nil { unwrap, ok := err.(interface { @@ -110,9 +114,11 @@ func Unwrap(err error) error { } err = unwrap.Unwrap() } + return err } +// Wrap func Wrap(err error, msg ...string) error { if err == nil { return nil @@ -120,5 +126,6 @@ func Wrap(err error, msg ...string) error { if len(msg) == 0 { return errors.WithStack(err) } + return errors.Wrap(err, strings.Join(msg, ", ")) } diff --git a/pkg/errs/relation.go b/pkg/errs/relation.go index 0a7ad4997..d5e9c6345 100644 --- a/pkg/errs/relation.go +++ b/pkg/errs/relation.go @@ -14,6 +14,7 @@ package errs +// Relation var Relation = &relation{m: make(map[int]map[int]struct{})} func init() { @@ -52,5 +53,6 @@ func (r *relation) Is(parent, child int) bool { return false } _, ok = s[child] + return ok } diff --git a/pkg/proto/auth/auth.go b/pkg/proto/auth/auth.go index 9b8fdd988..db2019a67 100644 --- a/pkg/proto/auth/auth.go +++ b/pkg/proto/auth/auth.go @@ -19,6 +19,7 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" ) +// Check func (x *UserTokenReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") @@ -26,9 +27,11 @@ func (x *UserTokenReq) Check() error { if x.PlatformID > constant.AdminPlatformID || x.PlatformID < constant.IOSPlatformID { return errs.ErrArgs.Wrap("platform is invalidate") } + return nil } +// Check func (x *ForceLogoutReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") @@ -36,12 +39,15 @@ func (x *ForceLogoutReq) Check() error { if x.PlatformID > constant.AdminPlatformID || x.PlatformID < constant.IOSPlatformID { return errs.ErrArgs.Wrap("platformID is invalidate") } + return nil } +// Check func (x *ParseTokenReq) Check() error { if x.Token == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } diff --git a/pkg/proto/conversation/conversation.go b/pkg/proto/conversation/conversation.go index 7e8f62bbc..ad6c6a623 100644 --- a/pkg/proto/conversation/conversation.go +++ b/pkg/proto/conversation/conversation.go @@ -16,13 +16,16 @@ package conversation import "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" +// Check func (x *ConversationReq) Check() error { if x.ConversationID == "" { return errs.ErrArgs.Wrap("conversation is empty") } + return nil } +// Check func (x *Conversation) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("OwnerUserID is empty") @@ -36,19 +39,23 @@ func (x *Conversation) Check() error { if x.RecvMsgOpt < 0 || x.RecvMsgOpt > 2 { return errs.ErrArgs.Wrap("RecvMsgOpt is invalid") } + return nil } -//func (x *ModifyConversationFieldReq) Check() error { +// // Check +// func (x *ModifyConversationFieldReq) Check() error { // if x.UserIDList == nil { // return errs.ErrArgs.Wrap("userIDList is empty") // } // if x.Conversation == nil { // return errs.ErrArgs.Wrap("conversation is empty") // } -// return nil -//} +// +// return nil +// } +// Check func (x *SetConversationReq) Check() error { if x.Conversation == nil { return errs.ErrArgs.Wrap("Conversation is empty") @@ -56,10 +63,12 @@ func (x *SetConversationReq) Check() error { if x.Conversation.ConversationID == "" { return errs.ErrArgs.Wrap("conversationID is empty") } + return nil } -//func (x *SetRecvMsgOptReq) Check() error { +// // Check +// func (x *SetRecvMsgOptReq) Check() error { // if x.OwnerUserID == "" { // return errs.ErrArgs.Wrap("ownerUserID is empty") // } @@ -69,9 +78,11 @@ func (x *SetConversationReq) Check() error { // if x.RecvMsgOpt > 2 || x.RecvMsgOpt < 0 { // return errs.ErrArgs.Wrap("MsgReceiveOpt is invalid") // } -// return nil -//} +// +// return nil +// } +// Check func (x *GetConversationReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("ownerUserID is empty") @@ -79,9 +90,11 @@ func (x *GetConversationReq) Check() error { if x.ConversationID == "" { return errs.ErrArgs.Wrap("conversationID is empty") } + return nil } +// Check func (x *GetConversationsReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("ownerUserID is empty") @@ -89,41 +102,51 @@ func (x *GetConversationsReq) Check() error { if x.ConversationIDs == nil { return errs.ErrArgs.Wrap("conversationIDs is empty") } + return nil } +// Check func (x *GetAllConversationsReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("ownerUserID is empty") } + return nil } // -//func (x *BatchSetConversationsReq) Check() error { +// // Check +// func (x *BatchSetConversationsReq) Check() error { // if x.Conversations == nil { // return errs.ErrArgs.Wrap("conversations is empty") // } // if x.OwnerUserID == "" { // return errs.ErrArgs.Wrap("conversation is empty") // } -// return nil -//} +// +// return nil +// } +// Check func (x *GetRecvMsgNotNotifyUserIDsReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") } + return nil } +// Check func (x *CreateGroupChatConversationsReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") } + return nil } +// Check func (x *SetConversationMaxSeqReq) Check() error { if x.ConversationID == "" { return errs.ErrArgs.Wrap("conversationID is empty") @@ -134,9 +157,11 @@ func (x *SetConversationMaxSeqReq) Check() error { if x.MaxSeq <= 0 { return errs.ErrArgs.Wrap("maxSeq is invalid") } + return nil } +// Check func (x *SetConversationsReq) Check() error { if x.UserIDs == nil { return errs.ErrArgs.Wrap("userID is empty") @@ -144,19 +169,24 @@ func (x *SetConversationsReq) Check() error { if x.Conversation == nil { return errs.ErrArgs.Wrap("conversation is empty") } + return nil } +// Check func (x *GetUserConversationIDsHashReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("ownerUserID is empty") } + return nil } +// Check func (x *GetConversationsByConversationIDReq) Check() error { if x.ConversationIDs == nil { return errs.ErrArgs.Wrap("conversationIDs is empty") } + return nil } diff --git a/pkg/proto/friend/friend.go b/pkg/proto/friend/friend.go index 197fc753c..59d99ba38 100644 --- a/pkg/proto/friend/friend.go +++ b/pkg/proto/friend/friend.go @@ -16,6 +16,7 @@ package friend import "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" +// Check func (x *GetPaginationFriendsReq) Check() error { if x.Pagination == nil { return errs.ErrArgs.Wrap("pagination is empty") @@ -26,9 +27,11 @@ func (x *GetPaginationFriendsReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } +// Check func (x *ApplyToAddFriendReq) Check() error { if x.ToUserID == "" { return errs.ErrArgs.Wrap("toUserID is empty") @@ -36,9 +39,11 @@ func (x *ApplyToAddFriendReq) Check() error { if x.FromUserID == "" { return errs.ErrArgs.Wrap("fromUserID is empty") } + return nil } +// Check func (x *ImportFriendReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("ownerUserID is empty") @@ -46,9 +51,11 @@ func (x *ImportFriendReq) Check() error { if x.FriendUserIDs == nil { return errs.ErrArgs.Wrap("friendUserIDS is empty") } + return nil } +// Check func (x *GetPaginationFriendsApplyToReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") @@ -59,9 +66,11 @@ func (x *GetPaginationFriendsApplyToReq) Check() error { if x.Pagination.PageNumber < 1 { return errs.ErrArgs.Wrap("pageNumber is invalid") } + return nil } +// Check func (x *GetDesignatedFriendsReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("ownerUserID is empty") @@ -69,9 +78,11 @@ func (x *GetDesignatedFriendsReq) Check() error { if x.FriendUserIDs == nil { return errs.ErrArgs.Wrap("friendUserIDS is empty") } + return nil } +// Check func (x *AddBlackReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("ownerUserID is empty") @@ -79,9 +90,11 @@ func (x *AddBlackReq) Check() error { if x.BlackUserID == "" { return errs.ErrArgs.Wrap("BlackUserID is empty") } + return nil } +// Check func (x *RemoveBlackReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("ownerUserID is empty") @@ -89,9 +102,11 @@ func (x *RemoveBlackReq) Check() error { if x.BlackUserID == "" { return errs.ErrArgs.Wrap("BlackUserID is empty") } + return nil } +// Check func (x *GetPaginationBlacksReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") @@ -102,9 +117,11 @@ func (x *GetPaginationBlacksReq) Check() error { if x.Pagination.PageNumber < 1 { return errs.ErrArgs.Wrap("pageNumber is invalid") } + return nil } +// Check func (x *IsFriendReq) Check() error { if x.UserID1 == "" { return errs.ErrArgs.Wrap("userID1 is empty") @@ -112,9 +129,11 @@ func (x *IsFriendReq) Check() error { if x.UserID2 == "" { return errs.ErrArgs.Wrap("userID2 is empty") } + return nil } +// Check func (x *IsBlackReq) Check() error { if x.UserID1 == "" { return errs.ErrArgs.Wrap("userID1 is empty") @@ -122,9 +141,11 @@ func (x *IsBlackReq) Check() error { if x.UserID2 == "" { return errs.ErrArgs.Wrap("userID2 is empty") } + return nil } +// Check func (x *DeleteFriendReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("userID1 is empty") @@ -132,9 +153,11 @@ func (x *DeleteFriendReq) Check() error { if x.FriendUserID == "" { return errs.ErrArgs.Wrap("userID2 is empty") } + return nil } +// Check func (x *RespondFriendApplyReq) Check() error { if x.ToUserID == "" { return errs.ErrArgs.Wrap("toUserID is empty") @@ -142,9 +165,11 @@ func (x *RespondFriendApplyReq) Check() error { if x.FromUserID == "" { return errs.ErrArgs.Wrap("fromUserID is empty") } + return nil } +// Check func (x *SetFriendRemarkReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("ownerUserID is empty") @@ -152,9 +177,11 @@ func (x *SetFriendRemarkReq) Check() error { if x.FriendUserID == "" { return errs.ErrArgs.Wrap("fromUserID is empty") } + return nil } +// Check func (x *GetPaginationFriendsApplyFromReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") @@ -165,12 +192,15 @@ func (x *GetPaginationFriendsApplyFromReq) Check() error { if x.Pagination.PageNumber < 1 { return errs.ErrArgs.Wrap("pageNumber is invalid") } + return nil } +// Check func (x *GetFriendIDsReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } diff --git a/pkg/proto/group/group.go b/pkg/proto/group/group.go index 2cebc0df0..78641df72 100644 --- a/pkg/proto/group/group.go +++ b/pkg/proto/group/group.go @@ -16,6 +16,7 @@ package group import "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" +// Check func (x *CreateGroupReq) Check() error { if x.MemberUserIDs == nil { return errs.ErrArgs.Wrap("memberUserIDS is empty") @@ -29,16 +30,20 @@ func (x *CreateGroupReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("ownerUserID") } + return nil } +// Check func (x *GetGroupsInfoReq) Check() error { if x.GroupIDs == nil { return errs.ErrArgs.Wrap("GroupIDs") } + return nil } +// Check func (x *SetGroupInfoReq) Check() error { if x.GroupInfoForSet == nil { return errs.ErrArgs.Wrap("GroupInfoForSets is empty") @@ -46,9 +51,11 @@ func (x *SetGroupInfoReq) Check() error { if x.GroupInfoForSet.GroupID == "" { return errs.ErrArgs.Wrap("GroupID is empty") } + return nil } +// Check func (x *GetGroupApplicationListReq) Check() error { if x.Pagination == nil { return errs.ErrArgs.Wrap("pagination is empty") @@ -59,9 +66,11 @@ func (x *GetGroupApplicationListReq) Check() error { if x.FromUserID == "" { return errs.ErrArgs.Wrap("fromUserID is empty") } + return nil } +// Check func (x *GetUserReqApplicationListReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("UserID is empty") @@ -72,9 +81,11 @@ func (x *GetUserReqApplicationListReq) Check() error { if x.Pagination.PageNumber < 1 { return errs.ErrArgs.Wrap("pageNumber is invalid") } + return nil } +// Check func (x *TransferGroupOwnerReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") @@ -85,9 +96,11 @@ func (x *TransferGroupOwnerReq) Check() error { if x.NewOwnerUserID == "" { return errs.ErrArgs.Wrap("newOwnerUserID is empty") } + return nil } +// Check func (x *JoinGroupReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") @@ -100,9 +113,11 @@ func (x *JoinGroupReq) Check() error { return errs.ErrArgs.Wrap("inviterUserID is empty") } } + return nil } +// Check func (x *GroupApplicationResponseReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") @@ -113,16 +128,20 @@ func (x *GroupApplicationResponseReq) Check() error { if x.HandleResult > 1 || x.HandleResult < -1 { return errs.ErrArgs.Wrap("handleResult is invalid") } + return nil } +// Check func (x *QuitGroupReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") } + return nil } +// Check func (x *GetGroupMemberListReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") @@ -136,9 +155,11 @@ func (x *GetGroupMemberListReq) Check() error { if x.Filter < 0 || x.Filter > 5 { return errs.ErrArgs.Wrap("filter is invalid") } + return nil } +// Check func (x *GetGroupMembersInfoReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") @@ -146,9 +167,11 @@ func (x *GetGroupMembersInfoReq) Check() error { if x.UserIDs == nil { return errs.ErrArgs.Wrap("userIDs is empty") } + return nil } +// Check func (x *KickGroupMemberReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") @@ -156,9 +179,11 @@ func (x *KickGroupMemberReq) Check() error { if x.KickedUserIDs == nil { return errs.ErrArgs.Wrap("kickUserIDs is empty") } + return nil } +// Check func (x *GetJoinedGroupListReq) Check() error { if x.Pagination == nil { return errs.ErrArgs.Wrap("pagination is empty") @@ -169,9 +194,11 @@ func (x *GetJoinedGroupListReq) Check() error { if x.FromUserID == "" { return errs.ErrArgs.Wrap("fromUserID is empty") } + return nil } +// Check func (x *InviteUserToGroupReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") @@ -179,9 +206,11 @@ func (x *InviteUserToGroupReq) Check() error { if x.InvitedUserIDs == nil { return errs.ErrArgs.Wrap("invitedUserIDs is empty") } + return nil } +// Check func (x *GetGroupAllMemberReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") @@ -192,9 +221,11 @@ func (x *GetGroupAllMemberReq) Check() error { if x.Pagination.PageNumber < 1 { return errs.ErrArgs.Wrap("pageNumber is invalid") } + return nil } +// Check func (x *GetGroupsReq) Check() error { if x.Pagination == nil { return errs.ErrArgs.Wrap("pagination is empty") @@ -202,16 +233,20 @@ func (x *GetGroupsReq) Check() error { if x.Pagination.PageNumber < 1 { return errs.ErrArgs.Wrap("pageNumber is invalid") } + return nil } +// Check func (x *GetGroupMemberReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") } + return nil } +// Check func (x *GetGroupMembersCMSReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") @@ -222,16 +257,20 @@ func (x *GetGroupMembersCMSReq) Check() error { if x.Pagination.PageNumber < 1 { return errs.ErrArgs.Wrap("pageNumber is invalid") } + return nil } +// Check func (x *DismissGroupReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") } + return nil } +// Check func (x *MuteGroupMemberReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") @@ -242,9 +281,11 @@ func (x *MuteGroupMemberReq) Check() error { if x.MutedSeconds <= 0 { return errs.ErrArgs.Wrap("mutedSeconds is empty") } + return nil } +// Check func (x *CancelMuteGroupMemberReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") @@ -252,37 +293,47 @@ func (x *CancelMuteGroupMemberReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } +// Check func (x *MuteGroupReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") } + return nil } +// Check func (x *CancelMuteGroupReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") } + return nil } +// Check func (x *GetJoinedSuperGroupListReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } +// Check func (x *GetSuperGroupsInfoReq) Check() error { if x.GroupIDs == nil { return errs.ErrArgs.Wrap("GroupIDs is empty") } + return nil } +// Check func (x *SetGroupMemberInfo) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("GroupID is empty") @@ -290,23 +341,29 @@ func (x *SetGroupMemberInfo) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } +// Check func (x *SetGroupMemberInfoReq) Check() error { if x.Members == nil { return errs.ErrArgs.Wrap("Members is empty") } + return nil } +// Check func (x *GetGroupAbstractInfoReq) Check() error { if x.GroupIDs == nil { return errs.ErrArgs.Wrap("GroupID is empty") } + return nil } +// Check func (x *GetUserInGroupMembersReq) Check() error { if x.GroupIDs == nil { return errs.ErrArgs.Wrap("GroupID is empty") @@ -314,16 +371,20 @@ func (x *GetUserInGroupMembersReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } +// Check func (x *GetGroupMemberUserIDsReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("GroupID is empty") } + return nil } +// Check func (x *GetGroupMemberRoleLevelReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("GroupID is empty") @@ -331,16 +392,20 @@ func (x *GetGroupMemberRoleLevelReq) Check() error { if x.RoleLevels == nil { return errs.ErrArgs.Wrap("rolesLevel is empty") } + return nil } +// Check func (x *GetGroupInfoCacheReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("GroupID is empty") } + return nil } +// Check func (x *GetGroupMemberCacheReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("GroupID is empty") @@ -348,5 +413,6 @@ func (x *GetGroupMemberCacheReq) Check() error { if x.GroupMemberID == "" { return errs.ErrArgs.Wrap("GroupMemberID is empty") } + return nil } diff --git a/pkg/proto/msg/msg.go b/pkg/proto/msg/msg.go index 03c9da915..48904e82b 100644 --- a/pkg/proto/msg/msg.go +++ b/pkg/proto/msg/msg.go @@ -16,13 +16,16 @@ package msg import "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" +// Check func (x *GetMaxAndMinSeqReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } +// Check func (x *SendMsgReq) Check() error { if x.MsgData == nil { return errs.ErrArgs.Wrap("MsgData is empty") @@ -30,21 +33,25 @@ func (x *SendMsgReq) Check() error { if err := x.MsgData.Check(); err != nil { return err } + return nil } +// Check func (x *SetSendMsgStatusReq) Check() error { if x.Status < 0 || x.Status > 3 { return errs.ErrArgs.Wrap("status is invalid") } + return nil } +// Check func (x *GetSendMsgStatusReq) Check() error { return nil } -//func (x *ModifyMessageReactionExtensionsReq) Check() error { +// func (x *ModifyMessageReactionExtensionsReq) Check() error { // if x.ConversationID == "" { // return errs.ErrArgs.Wrap("conversationID is empty") // } @@ -55,9 +62,9 @@ func (x *GetSendMsgStatusReq) Check() error { // return errs.ErrArgs.Wrap("reactionExtensions is empty") // } // return nil -//} +// } // -//func (x *SetMessageReactionExtensionsReq) Check() error { +// func (x *SetMessageReactionExtensionsReq) Check() error { // if x.ConversationID == "" { // return errs.ErrArgs.Wrap("conversationID is empty") // } @@ -68,9 +75,9 @@ func (x *GetSendMsgStatusReq) Check() error { // return errs.ErrArgs.Wrap("reactionExtensions is empty") // } // return nil -//} +// } // -//func (x *GetMessagesReactionExtensionsReq) Check() error { +// func (x *GetMessagesReactionExtensionsReq) Check() error { // if x.ConversationID == "" { // return errs.ErrArgs.Wrap("conversationID is empty") // } @@ -84,9 +91,9 @@ func (x *GetSendMsgStatusReq) Check() error { // return errs.ErrArgs.Wrap("TypeKeys is empty") // } // return nil -//} +// } // -//func (x *DeleteMessagesReactionExtensionsReq) Check() error { +// func (x *DeleteMessagesReactionExtensionsReq) Check() error { // if x.ConversationID == "" { // return errs.ErrArgs.Wrap("conversationID is empty") // } @@ -97,12 +104,14 @@ func (x *GetSendMsgStatusReq) Check() error { // return errs.ErrArgs.Wrap("ReactionExtensions is empty") // } // return nil -//} +// } +// Check func (x *DelMsgsReq) Check() error { return nil } +// Check func (x *RevokeMsgReq) Check() error { if x.ConversationID == "" { return errs.ErrArgs.Wrap("conversationID is empty") @@ -113,9 +122,11 @@ func (x *RevokeMsgReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } +// Check func (x *MarkMsgsAsReadReq) Check() error { if x.ConversationID == "" { return errs.ErrArgs.Wrap("conversationID is empty") @@ -131,9 +142,11 @@ func (x *MarkMsgsAsReadReq) Check() error { return errs.ErrArgs.Wrap("seqs has 0 value is invalid") } } + return nil } +// Check func (x *MarkConversationAsReadReq) Check() error { if x.ConversationID == "" { return errs.ErrArgs.Wrap("conversationID is empty") @@ -149,9 +162,11 @@ func (x *MarkConversationAsReadReq) Check() error { return errs.ErrArgs.Wrap("seqs has 0 value is invalid") } } + return nil } +// Check func (x *SetConversationHasReadSeqReq) Check() error { if x.ConversationID == "" { return errs.ErrArgs.Wrap("conversationID is empty") @@ -162,9 +177,11 @@ func (x *SetConversationHasReadSeqReq) Check() error { if x.HasReadSeq < 1 { return errs.ErrArgs.Wrap("hasReadSeq is invalid") } + return nil } +// Check func (x *ClearConversationsMsgReq) Check() error { if x.ConversationIDs == nil { return errs.ErrArgs.Wrap("conversationIDs is empty") @@ -172,16 +189,20 @@ func (x *ClearConversationsMsgReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } +// Check func (x *UserClearAllMsgReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } +// Check func (x *DeleteMsgsReq) Check() error { if x.ConversationID == "" { return errs.ErrArgs.Wrap("conversationID is empty") @@ -192,26 +213,33 @@ func (x *DeleteMsgsReq) Check() error { if x.Seqs == nil { return errs.ErrArgs.Wrap("seqs is empty") } + return nil } +// Check func (x *DeleteMsgPhysicalReq) Check() error { if x.ConversationIDs == nil { return errs.ErrArgs.Wrap("conversationIDs is empty") } + return nil } +// Check func (x *GetConversationMaxSeqReq) Check() error { if x.ConversationID == "" { return errs.ErrArgs.Wrap("conversationID is empty") } + return nil } +// Check func (x *GetConversationsHasReadAndMaxSeqReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } diff --git a/pkg/proto/msggateway/msggateway.go b/pkg/proto/msggateway/msggateway.go index 5e0c85b45..45f20c7cb 100644 --- a/pkg/proto/msggateway/msggateway.go +++ b/pkg/proto/msggateway/msggateway.go @@ -16,6 +16,7 @@ package msggateway import "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" +// Check func (x *OnlinePushMsgReq) Check() error { if x.MsgData == nil { return errs.ErrArgs.Wrap("MsgData is empty") @@ -26,9 +27,11 @@ func (x *OnlinePushMsgReq) Check() error { if x.PushToUserID == "" { return errs.ErrArgs.Wrap("PushToUserID is empty") } + return nil } +// Check func (x *OnlineBatchPushOneMsgReq) Check() error { if x.MsgData == nil { return errs.ErrArgs.Wrap("MsgData is empty") @@ -39,16 +42,20 @@ func (x *OnlineBatchPushOneMsgReq) Check() error { if x.PushToUserIDs == nil { return errs.ErrArgs.Wrap("PushToUserIDs is empty") } + return nil } +// Check func (x *GetUsersOnlineStatusReq) Check() error { if x.UserIDs == nil { return errs.ErrArgs.Wrap("UserIDs is empty") } + return nil } +// Check func (x *KickUserOfflineReq) Check() error { if x.PlatformID < 1 || x.PlatformID > 9 { return errs.ErrArgs.Wrap("PlatformID is invalid") @@ -56,9 +63,11 @@ func (x *KickUserOfflineReq) Check() error { if x.KickUserIDList == nil { return errs.ErrArgs.Wrap("KickUserIDList is empty") } + return nil } +// Check func (x *MultiTerminalLoginCheckReq) Check() error { if x.PlatformID < 1 || x.PlatformID > 9 { return errs.ErrArgs.Wrap("PlatformID is invalid") @@ -69,5 +78,6 @@ func (x *MultiTerminalLoginCheckReq) Check() error { if x.Token == "" { return errs.ErrArgs.Wrap("Token is empty") } + return nil } diff --git a/pkg/proto/push/push.go b/pkg/proto/push/push.go index 2f117acda..83c6e9a9f 100644 --- a/pkg/proto/push/push.go +++ b/pkg/proto/push/push.go @@ -16,6 +16,7 @@ package push import "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" +// Check func (x *PushMsgReq) Check() error { if x.MsgData == nil { return errs.ErrArgs.Wrap("MsgData is empty") @@ -26,9 +27,11 @@ func (x *PushMsgReq) Check() error { if x.ConversationID == "" { return errs.ErrArgs.Wrap("ConversationID is empty") } + return nil } +// Check func (x *DelUserPushTokenReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("UserID is empty") @@ -36,5 +39,6 @@ func (x *DelUserPushTokenReq) Check() error { if x.PlatformID < 1 || x.PlatformID > 9 { return errs.ErrArgs.Wrap("PlatformID is invalid") } + return nil } diff --git a/pkg/proto/sdkws/sdkws.go b/pkg/proto/sdkws/sdkws.go index d0b0ae8aa..ff4630629 100644 --- a/pkg/proto/sdkws/sdkws.go +++ b/pkg/proto/sdkws/sdkws.go @@ -19,6 +19,7 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" ) +// Check func (x *MsgData) Check() error { if x.SendID == "" { return errs.ErrArgs.Wrap("sendID is empty") @@ -42,5 +43,6 @@ func (x *MsgData) Check() error { return errs.ErrArgs.Wrap("GroupID is empty") } } + return nil } diff --git a/pkg/proto/third/third.go b/pkg/proto/third/third.go index 0e2072727..454191342 100644 --- a/pkg/proto/third/third.go +++ b/pkg/proto/third/third.go @@ -16,7 +16,7 @@ package third import "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" -//func (x *ApplyPutReq) Check() error { +// func (x *ApplyPutReq) Check() error { // if x.PutID == "" { // return errs.ErrArgs.Wrap("PutID is empty") // } @@ -24,36 +24,37 @@ import "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" // return errs.ErrArgs.Wrap("ContentType is empty") // } // return nil -//} +// } // -//func (x *ConfirmPutReq) Check() error { +// func (x *ConfirmPutReq) Check() error { // if x.PutID == "" { // return errs.ErrArgs.Wrap("PutID is empty") // } // return nil -//} +// } // -//func (x *GetUrlReq) Check() error { +// func (x *GetUrlReq) Check() error { // if x.Name == "" { // return errs.ErrArgs.Wrap("Name is empty") // } // return nil -//} +// } // -//func (x *GetPutReq) Check() error { +// func (x *GetPutReq) Check() error { // if x.PutID == "" { // return errs.ErrArgs.Wrap("PutID is empty") // } // return nil -//} +// } // -//func (x *GetHashInfoReq) Check() error { +// func (x *GetHashInfoReq) Check() error { // if x.Hash == "" { // return errs.ErrArgs.Wrap("Hash is empty") // } // return nil -//} +// } +// Check func (x *FcmUpdateTokenReq) Check() error { if x.PlatformID < 1 || x.PlatformID > 9 { return errs.ErrArgs.Wrap("PlatformID is invalid") @@ -64,12 +65,15 @@ func (x *FcmUpdateTokenReq) Check() error { if x.Account == "" { return errs.ErrArgs.Wrap("Account is empty") } + return nil } +// Check func (x *SetAppBadgeReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("UserID is empty") } + return nil } diff --git a/pkg/proto/user/user.go b/pkg/proto/user/user.go index 06f07cb6e..f92ea9b9d 100644 --- a/pkg/proto/user/user.go +++ b/pkg/proto/user/user.go @@ -16,6 +16,7 @@ package user import "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" +// Check func (x *GetAllUserIDReq) Check() error { if x.Pagination == nil { return errs.ErrArgs.Wrap("pagination is empty") @@ -23,23 +24,29 @@ func (x *GetAllUserIDReq) Check() error { if x.Pagination.PageNumber < 1 { return errs.ErrArgs.Wrap("pageNumber is invalid") } + return nil } +// Check func (x *AccountCheckReq) Check() error { if x.CheckUserIDs == nil { return errs.ErrArgs.Wrap("CheckUserIDs is empty") } + return nil } +// Check func (x *GetDesignateUsersReq) Check() error { if x.UserIDs == nil { return errs.ErrArgs.Wrap("UserIDs is empty") } + return nil } +// Check func (x *UpdateUserInfoReq) Check() error { if x.UserInfo == nil { return errs.ErrArgs.Wrap("UserInfo is empty") @@ -47,9 +54,11 @@ func (x *UpdateUserInfoReq) Check() error { if x.UserInfo.UserID == "" { return errs.ErrArgs.Wrap("UserID is empty") } + return nil } +// Check func (x *SetGlobalRecvMessageOptReq) Check() error { if x.GlobalRecvMsgOpt > 2 || x.GlobalRecvMsgOpt < 0 { return errs.ErrArgs.Wrap("GlobalRecvMsgOpt is invalid") @@ -57,9 +66,11 @@ func (x *SetGlobalRecvMessageOptReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("UserID is empty") } + return nil } +// Check func (x *SetConversationReq) Check() error { if err := x.Conversation.Check(); err != nil { return err @@ -67,9 +78,11 @@ func (x *SetConversationReq) Check() error { if x.NotificationType < 1 || x.NotificationType > 3 { return errs.ErrArgs.Wrap("NotificationType is invalid") } + return nil } +// Check func (x *SetRecvMsgOptReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("OwnerUserID is empty") @@ -83,9 +96,11 @@ func (x *SetRecvMsgOptReq) Check() error { if x.NotificationType < 1 || x.NotificationType > 3 { return errs.ErrArgs.Wrap("NotificationType is invalid") } + return nil } +// Check func (x *GetConversationReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("OwnerUserID is empty") @@ -93,9 +108,11 @@ func (x *GetConversationReq) Check() error { if x.ConversationID == "" { return errs.ErrArgs.Wrap("ConversationID is empty") } + return nil } +// Check func (x *GetConversationsReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("OwnerUserID is empty") @@ -103,16 +120,20 @@ func (x *GetConversationsReq) Check() error { if x.ConversationIDs == nil { return errs.ErrArgs.Wrap("ConversationIDs is empty") } + return nil } +// Check func (x *GetAllConversationsReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("OwnerUserID is empty") } + return nil } +// Check func (x *BatchSetConversationsReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("OwnerUserID is empty") @@ -123,9 +144,11 @@ func (x *BatchSetConversationsReq) Check() error { if x.NotificationType < 1 || x.NotificationType > 3 { return errs.ErrArgs.Wrap("NotificationType is invalid") } + return nil } +// Check func (x *GetPaginationUsersReq) Check() error { if x.Pagination == nil { return errs.ErrArgs.Wrap("pagination is empty") @@ -133,23 +156,29 @@ func (x *GetPaginationUsersReq) Check() error { if x.Pagination.PageNumber < 1 { return errs.ErrArgs.Wrap("pageNumber is invalid") } + return nil } +// Check func (x *UserRegisterReq) Check() error { if x.Users == nil { return errs.ErrArgs.Wrap("Users is empty") } + return nil } +// Check func (x *GetGlobalRecvMessageOptReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("UserID is empty") } + return nil } +// Check func (x *UserRegisterCountReq) Check() error { if x.Start <= 0 { return errs.ErrArgs.Wrap("start is invalid") @@ -157,5 +186,6 @@ func (x *UserRegisterCountReq) Check() error { if x.End <= 0 { return errs.ErrArgs.Wrap("end is invalid") } + return nil } diff --git a/pkg/proto/wrapperspb/wrapperspb.go b/pkg/proto/wrapperspb/wrapperspb.go index 7579c64f0..093a5ce4c 100644 --- a/pkg/proto/wrapperspb/wrapperspb.go +++ b/pkg/proto/wrapperspb/wrapperspb.go @@ -20,137 +20,172 @@ import ( "strconv" ) +// Double func Double(value float64) *DoubleValue { return &DoubleValue{Value: value} } +// Float func Float(value float32) *FloatValue { return &FloatValue{Value: value} } +// Int64 func Int64(value int64) *Int64Value { return &Int64Value{Value: value} } +// UInt64 func UInt64(value uint64) *UInt64Value { return &UInt64Value{Value: value} } +// Int32 func Int32(value int32) *Int32Value { return &Int32Value{Value: value} } +// UInt32 func UInt32(value uint32) *UInt32Value { return &UInt32Value{Value: value} } +// Bool func Bool(value bool) *BoolValue { return &BoolValue{Value: value} } +// String func String(value string) *StringValue { return &StringValue{Value: value} } +// Bytes func Bytes(value []byte) *BytesValue { return &BytesValue{Value: value} } +// DoublePtr func DoublePtr(value *float64) *DoubleValue { if value == nil { return nil } + return &DoubleValue{Value: *value} } +// FloatPtr func FloatPtr(value *float32) *FloatValue { if value == nil { return nil } + return &FloatValue{Value: *value} } +// Int64Ptr func Int64Ptr(value *int64) *Int64Value { if value == nil { return nil } + return &Int64Value{Value: *value} } +// UInt64Ptr func UInt64Ptr(value *uint64) *UInt64Value { if value == nil { return nil } + return &UInt64Value{Value: *value} } +// Int32Ptr func Int32Ptr(value *int32) *Int32Value { if value == nil { return nil } + return &Int32Value{Value: *value} } +// UInt32Ptr func UInt32Ptr(value *uint32) *UInt32Value { if value == nil { return nil } + return &UInt32Value{Value: *value} } +// BoolPtr func BoolPtr(value *bool) *BoolValue { if value == nil { return nil } + return &BoolValue{Value: *value} } +// StringPtr func StringPtr(value *string) *StringValue { if value == nil { return nil } + return &StringValue{Value: *value} } +// BytesPtr func BytesPtr(value *[]byte) *BytesValue { if value == nil { return nil } + return &BytesValue{Value: *value} } +// UnmarshalJSON func (m *DoubleValue) UnmarshalJSON(p []byte) error { value, err := strconv.ParseFloat(string(p), 64) if err != nil { return err } m.Value = value + return nil } +// MarshalJSON func (m *DoubleValue) MarshalJSON() ([]byte, error) { return []byte(strconv.FormatFloat(m.Value, 'f', -1, 64)), nil } +// UnmarshalJSON func (m *FloatValue) UnmarshalJSON(p []byte) error { value, err := strconv.ParseFloat(string(p), 64) if err != nil { return err } m.Value = float32(value) + return nil } +// MarshalJSON func (m *FloatValue) MarshalJSON() ([]byte, error) { return []byte(strconv.FormatFloat(float64(m.Value), 'f', -1, 32)), nil } +// UnmarshalJSON func (m *Int64Value) UnmarshalJSON(p []byte) error { value, err := strconv.ParseInt(string(p), 10, 64) if err != nil { return err } m.Value = value + return nil } @@ -158,70 +193,86 @@ func (m *Int64Value) MarshalJSON() ([]byte, error) { return []byte(strconv.FormatInt(m.Value, 10)), nil } +// UnmarshalJSON func (m *UInt64Value) UnmarshalJSON(p []byte) error { value, err := strconv.ParseUint(string(p), 10, 64) if err != nil { return err } m.Value = value + return nil } +// MarshalJSON func (m *UInt64Value) MarshalJSON() ([]byte, error) { return []byte(strconv.FormatUint(m.Value, 10)), nil } +// UnmarshalJSON func (m *Int32Value) UnmarshalJSON(p []byte) error { value, err := strconv.ParseInt(string(p), 10, 32) if err != nil { return err } m.Value = int32(value) + return nil } +// MarshalJSON func (m *Int32Value) MarshalJSON() ([]byte, error) { return []byte(strconv.FormatInt(int64(m.Value), 10)), nil } +// UnmarshalJSON func (m *UInt32Value) UnmarshalJSON(p []byte) error { value, err := strconv.ParseUint(string(p), 10, 32) if err != nil { return err } m.Value = uint32(value) + return nil } +// MarshalJSON func (m *UInt32Value) MarshalJSON() ([]byte, error) { return []byte(strconv.FormatUint(uint64(m.Value), 10)), nil } +// UnmarshalJSON func (m *BoolValue) UnmarshalJSON(p []byte) error { value, err := strconv.ParseBool(string(p)) if err != nil { return err } m.Value = value + return nil } +// MarshalJSON func (m *BoolValue) MarshalJSON() ([]byte, error) { return []byte(strconv.FormatBool(m.Value)), nil } +// UnmarshalJSON func (m *StringValue) UnmarshalJSON(p []byte) error { if len(p) < 2 || p[0] != '"' || p[len(p)-1] != '"' { return errors.New("invalid string value") } m.Value = string(p[1 : len(p)-1]) + return nil } +// MarshalJSON func (m *StringValue) MarshalJSON() ([]byte, error) { return []byte(`"` + m.Value + `"`), nil } +// UnmarshalJSON func (m *BytesValue) UnmarshalJSON(p []byte) error { if len(p) < 2 || p[0] != '"' || p[len(p)-1] != '"' { return errors.New("invalid bytes value") @@ -231,38 +282,48 @@ func (m *BytesValue) UnmarshalJSON(p []byte) error { return err } m.Value = value + return nil } +// MarshalJSON func (m *BytesValue) MarshalJSON() ([]byte, error) { return []byte(`"` + base64.StdEncoding.EncodeToString(m.Value) + `"`), nil } +// GetValuePtr func (m *DoubleValue) GetValuePtr() *float64 { if m == nil { return nil } + return &m.Value } +// GetValuePtr func (m *FloatValue) GetValuePtr() *float32 { if m == nil { return nil } + return &m.Value } +// GetValuePtr func (m *Int64Value) GetValuePtr() *int64 { if m == nil { return nil } + return &m.Value } +// GetValuePtr func (m *UInt64Value) GetValuePtr() *uint64 { if m == nil { return nil } + return &m.Value } @@ -270,9 +331,11 @@ func (m *Int32Value) GetValuePtr() *int32 { if m == nil { return nil } + return &m.Value } +// GetValuePtr func (m *UInt32Value) GetValuePtr() *uint32 { if m == nil { return nil @@ -280,23 +343,29 @@ func (m *UInt32Value) GetValuePtr() *uint32 { return &m.Value } +// GetValuePtr func (m *BoolValue) GetValuePtr() *bool { if m == nil { return nil } + return &m.Value } +// GetValuePtr func (m *StringValue) GetValuePtr() *string { if m == nil { return nil } + return &m.Value } +// GetValuePtr func (m *BytesValue) GetValuePtr() *[]byte { if m == nil { return nil } + return &m.Value } diff --git a/pkg/rpcclient/auth.go b/pkg/rpcclient/auth.go index aa13ed898..abde73548 100644 --- a/pkg/rpcclient/auth.go +++ b/pkg/rpcclient/auth.go @@ -24,15 +24,18 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/auth" ) +// NewAuth func NewAuth(discov discoveryregistry.SvcDiscoveryRegistry) *Auth { conn, err := discov.GetConn(context.Background(), config.Config.RpcRegisterName.OpenImAuthName) if err != nil { panic(err) } client := auth.NewAuthClient(conn) + return &Auth{discov: discov, conn: conn, Client: client} } +// Auth type Auth struct { conn grpc.ClientConnInterface Client auth.AuthClient diff --git a/pkg/rpcclient/conversation.go b/pkg/rpcclient/conversation.go index 71867620d..30fb1c8c7 100644 --- a/pkg/rpcclient/conversation.go +++ b/pkg/rpcclient/conversation.go @@ -26,27 +26,33 @@ import ( pbConversation "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/conversation" ) +// Conversation type Conversation struct { Client pbConversation.ConversationClient conn grpc.ClientConnInterface discov discoveryregistry.SvcDiscoveryRegistry } +// NewConversation func NewConversation(discov discoveryregistry.SvcDiscoveryRegistry) *Conversation { conn, err := discov.GetConn(context.Background(), config.Config.RpcRegisterName.OpenImConversationName) if err != nil { panic(err) } client := pbConversation.NewConversationClient(conn) + return &Conversation{discov: discov, conn: conn, Client: client} } +// ConversationRpcClient type ConversationRpcClient Conversation +// NewConversationRpcClient func NewConversationRpcClient(discov discoveryregistry.SvcDiscoveryRegistry) ConversationRpcClient { return ConversationRpcClient(*NewConversation(discov)) } +// GetSingleConversationRecvMsgOpt func (c *ConversationRpcClient) GetSingleConversationRecvMsgOpt(ctx context.Context, userID, conversationID string) (int32, error) { var req pbConversation.GetConversationReq req.OwnerUserID = userID @@ -55,45 +61,59 @@ func (c *ConversationRpcClient) GetSingleConversationRecvMsgOpt(ctx context.Cont if err != nil { return 0, err } + return conversation.GetConversation().RecvMsgOpt, err } +// SingleChatFirstCreateConversation func (c *ConversationRpcClient) SingleChatFirstCreateConversation(ctx context.Context, recvID, sendID string) error { _, err := c.Client.CreateSingleChatConversations(ctx, &pbConversation.CreateSingleChatConversationsReq{RecvID: recvID, SendID: sendID}) + return err } +// GroupChatFirstCreateConversation func (c *ConversationRpcClient) GroupChatFirstCreateConversation(ctx context.Context, groupID string, userIDs []string) error { _, err := c.Client.CreateGroupChatConversations(ctx, &pbConversation.CreateGroupChatConversationsReq{UserIDs: userIDs, GroupID: groupID}) + return err } +// SetConversationMaxSeq func (c *ConversationRpcClient) SetConversationMaxSeq(ctx context.Context, ownerUserIDs []string, conversationID string, maxSeq int64) error { _, err := c.Client.SetConversationMaxSeq(ctx, &pbConversation.SetConversationMaxSeqReq{OwnerUserID: ownerUserIDs, ConversationID: conversationID, MaxSeq: maxSeq}) + return err } +// SetConversations func (c *ConversationRpcClient) SetConversations(ctx context.Context, userIDs []string, conversation *pbConversation.ConversationReq) error { _, err := c.Client.SetConversations(ctx, &pbConversation.SetConversationsReq{UserIDs: userIDs, Conversation: conversation}) + return err } +// GetConversationIDs func (c *ConversationRpcClient) GetConversationIDs(ctx context.Context, ownerUserID string) ([]string, error) { resp, err := c.Client.GetConversationIDs(ctx, &pbConversation.GetConversationIDsReq{UserID: ownerUserID}) if err != nil { return nil, err } + return resp.ConversationIDs, nil } +// GetConversation func (c *ConversationRpcClient) GetConversation(ctx context.Context, ownerUserID, conversationID string) (*pbConversation.Conversation, error) { resp, err := c.Client.GetConversation(ctx, &pbConversation.GetConversationReq{OwnerUserID: ownerUserID, ConversationID: conversationID}) if err != nil { return nil, err } + return resp.Conversation, nil } +// GetConversationsByConversationID func (c *ConversationRpcClient) GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*pbConversation.Conversation, error) { if len(conversationIDs) == 0 { return nil, nil @@ -105,9 +125,11 @@ func (c *ConversationRpcClient) GetConversationsByConversationID(ctx context.Con if len(resp.Conversations) == 0 { return nil, errs.ErrRecordNotFound.Wrap(fmt.Sprintf("conversationIDs: %v not found", conversationIDs)) } + return resp.Conversations, nil } +// GetConversations func (c *ConversationRpcClient) GetConversations( ctx context.Context, ownerUserID string, @@ -123,5 +145,6 @@ func (c *ConversationRpcClient) GetConversations( if err != nil { return nil, err } + return resp.Conversations, nil } diff --git a/pkg/rpcclient/friend.go b/pkg/rpcclient/friend.go index 5a8ac0633..edb75cc21 100644 --- a/pkg/rpcclient/friend.go +++ b/pkg/rpcclient/friend.go @@ -25,27 +25,33 @@ import ( sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" ) +// Friend type Friend struct { conn grpc.ClientConnInterface Client friend.FriendClient discov discoveryregistry.SvcDiscoveryRegistry } +// NewFriend func NewFriend(discov discoveryregistry.SvcDiscoveryRegistry) *Friend { conn, err := discov.GetConn(context.Background(), config.Config.RpcRegisterName.OpenImFriendName) if err != nil { panic(err) } client := friend.NewFriendClient(conn) + return &Friend{discov: discov, conn: conn, Client: client} } +// FriendRpcClient type FriendRpcClient Friend +// NewFriendRpcClient func NewFriendRpcClient(discov discoveryregistry.SvcDiscoveryRegistry) FriendRpcClient { return FriendRpcClient(*NewFriend(discov)) } +// GetFriendsInfo func (f *FriendRpcClient) GetFriendsInfo( ctx context.Context, ownerUserID, friendUserID string, @@ -58,31 +64,37 @@ func (f *FriendRpcClient) GetFriendsInfo( return nil, err } resp = r.FriendsInfo[0] + return } -// possibleFriendUserID是否在userID的好友中. +// IsFriend possibleFriendUserID是否在userID的好友中. func (f *FriendRpcClient) IsFriend(ctx context.Context, possibleFriendUserID, userID string) (bool, error) { resp, err := f.Client.IsFriend(ctx, &friend.IsFriendReq{UserID1: userID, UserID2: possibleFriendUserID}) if err != nil { return false, err } + return resp.InUser1Friends, nil } +// GetFriendIDs func (f *FriendRpcClient) GetFriendIDs(ctx context.Context, ownerUserID string) (friendIDs []string, err error) { req := friend.GetFriendIDsReq{UserID: ownerUserID} resp, err := f.Client.GetFriendIDs(ctx, &req) if err != nil { return nil, err } + return resp.FriendIDs, nil } +// IsBlocked func (b *FriendRpcClient) IsBlocked(ctx context.Context, possibleBlackUserID, userID string) (bool, error) { r, err := b.Client.IsBlack(ctx, &friend.IsBlackReq{UserID1: possibleBlackUserID, UserID2: userID}) if err != nil { return false, err } + return r.InUser2Blacks, nil } diff --git a/pkg/rpcclient/group.go b/pkg/rpcclient/group.go index 06333234f..65ef0ab0f 100644 --- a/pkg/rpcclient/group.go +++ b/pkg/rpcclient/group.go @@ -29,27 +29,33 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/utils" ) +// Group type Group struct { conn grpc.ClientConnInterface Client group.GroupClient discov discoveryregistry.SvcDiscoveryRegistry } +// NewGroup func NewGroup(discov discoveryregistry.SvcDiscoveryRegistry) *Group { conn, err := discov.GetConn(context.Background(), config.Config.RpcRegisterName.OpenImGroupName) if err != nil { panic(err) } client := group.NewGroupClient(conn) + return &Group{discov: discov, conn: conn, Client: client} } +// GroupRpcClient type GroupRpcClient Group +// NewGroupRpcClient func NewGroupRpcClient(discov discoveryregistry.SvcDiscoveryRegistry) GroupRpcClient { return GroupRpcClient(*NewGroup(discov)) } +// GetGroupInfos func (g *GroupRpcClient) GetGroupInfos( ctx context.Context, groupIDs []string, @@ -71,14 +77,17 @@ func (g *GroupRpcClient) GetGroupInfos( return resp.GroupInfos, nil } +// GetGroupInfo func (g *GroupRpcClient) 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 } +// GetGroupInfoMap func (g *GroupRpcClient) GetGroupInfoMap( ctx context.Context, groupIDs []string, @@ -88,11 +97,13 @@ func (g *GroupRpcClient) GetGroupInfoMap( if err != nil { return nil, err } + return utils.SliceToMap(groups, func(e *sdkws.GroupInfo) string { return e.GroupID }), nil } +// GetGroupMemberInfos func (g *GroupRpcClient) GetGroupMemberInfos( ctx context.Context, groupID string, @@ -113,9 +124,11 @@ func (g *GroupRpcClient) GetGroupMemberInfos( return nil, errs.ErrNotInGroupYet.Wrap(strings.Join(ids, ",")) } } + return resp.Members, nil } +// GetGroupMemberInfo func (g *GroupRpcClient) GetGroupMemberInfo( ctx context.Context, groupID string, @@ -125,9 +138,11 @@ func (g *GroupRpcClient) GetGroupMemberInfo( if err != nil { return nil, err } + return members[0], nil } +// GetGroupMemberInfoMap func (g *GroupRpcClient) GetGroupMemberInfoMap( ctx context.Context, groupID string, @@ -138,11 +153,13 @@ func (g *GroupRpcClient) GetGroupMemberInfoMap( if err != nil { return nil, err } + return utils.SliceToMap(members, func(e *sdkws.GroupMemberFullInfo) string { return e.UserID }), nil } +// GetOwnerAndAdminInfos func (g *GroupRpcClient) GetOwnerAndAdminInfos( ctx context.Context, groupID string, @@ -154,17 +171,21 @@ func (g *GroupRpcClient) GetOwnerAndAdminInfos( if err != nil { return nil, err } + return resp.Members, nil } +// GetOwnerInfo func (g *GroupRpcClient) GetOwnerInfo(ctx context.Context, groupID string) (*sdkws.GroupMemberFullInfo, error) { resp, err := g.Client.GetGroupMemberRoleLevel(ctx, &group.GetGroupMemberRoleLevelReq{ GroupID: groupID, RoleLevels: []int32{constant.GroupOwner}, }) + return resp.Members[0], err } +// GetGroupMemberIDs func (g *GroupRpcClient) GetGroupMemberIDs(ctx context.Context, groupID string) ([]string, error) { resp, err := g.Client.GetGroupMemberUserIDs(ctx, &group.GetGroupMemberUserIDsReq{ GroupID: groupID, @@ -172,9 +193,11 @@ func (g *GroupRpcClient) GetGroupMemberIDs(ctx context.Context, groupID string) if err != nil { return nil, err } + return resp.UserIDs, nil } +// GetGroupInfoCache func (g *GroupRpcClient) GetGroupInfoCache(ctx context.Context, groupID string) (*sdkws.GroupInfo, error) { resp, err := g.Client.GetGroupInfoCache(ctx, &group.GetGroupInfoCacheReq{ GroupID: groupID, @@ -182,9 +205,11 @@ func (g *GroupRpcClient) GetGroupInfoCache(ctx context.Context, groupID string) if err != nil { return nil, err } + return resp.GroupInfo, nil } +// GetGroupMemberCache func (g *GroupRpcClient) GetGroupMemberCache( ctx context.Context, groupID string, @@ -197,13 +222,16 @@ func (g *GroupRpcClient) GetGroupMemberCache( if err != nil { return nil, err } + return resp.Member, nil } +// DismissGroup func (g *GroupRpcClient) DismissGroup(ctx context.Context, groupID string) error { _, err := g.Client.DismissGroup(ctx, &group.DismissGroupReq{ GroupID: groupID, DeleteMember: true, }) + return err } diff --git a/pkg/rpcclient/msg.go b/pkg/rpcclient/msg.go index be776138b..5555aba23 100644 --- a/pkg/rpcclient/msg.go +++ b/pkg/rpcclient/msg.go @@ -121,29 +121,36 @@ func newSessionTypeConf() map[int32]int32 { } } +// Message type Message struct { conn grpc.ClientConnInterface Client msg.MsgClient discov discoveryregistry.SvcDiscoveryRegistry } +// NewMessage func NewMessage(discov discoveryregistry.SvcDiscoveryRegistry) *Message { conn, err := discov.GetConn(context.Background(), config.Config.RpcRegisterName.OpenImMsgName) if err != nil { panic(err) } client := msg.NewMsgClient(conn) + return &Message{discov: discov, conn: conn, Client: client} } +// MessageRpcClient type MessageRpcClient Message +// NewMessageRpcClient func NewMessageRpcClient(discov discoveryregistry.SvcDiscoveryRegistry) MessageRpcClient { return MessageRpcClient(*NewMessage(discov)) } +// SendMsg func (m *MessageRpcClient) SendMsg(ctx context.Context, req *msg.SendMsgReq) (*msg.SendMsgResp, error) { resp, err := m.Client.SendMsg(ctx, req) + return resp, err } diff --git a/pkg/rpcclient/notification/group.go b/pkg/rpcclient/notification/group.go index abdc4d76e..5b8d87226 100644 --- a/pkg/rpcclient/notification/group.go +++ b/pkg/rpcclient/notification/group.go @@ -597,6 +597,7 @@ func (g *GroupNotificationSender) GroupMemberSetToOrdinaryUserNotification(ctx c if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberSetToOrdinaryUserNotification, tips) } diff --git a/pkg/statistics/statistics.go b/pkg/statistics/statistics.go index 8c1828380..223e2c322 100644 --- a/pkg/statistics/statistics.go +++ b/pkg/statistics/statistics.go @@ -35,12 +35,10 @@ func (s *Statistics) output() { defer t.Stop() var sum uint64 var timeIntervalNum uint64 - outputCh := make(chan struct{}) for { sum = *s.AllCount select { case <-t.C: - outputCh <- struct{}{} } if *s.AllCount-sum <= 0 { intervalCount = 0 From 521d4bfdf5a6c13017d5f73a593d57d37760987d Mon Sep 17 00:00:00 2001 From: BanTanger Date: Sun, 23 Jul 2023 03:48:14 +0000 Subject: [PATCH 40/62] cicd: robot automated Change Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- pkg/common/mw/specialerror/error.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/common/mw/specialerror/error.go b/pkg/common/mw/specialerror/error.go index b843ad0d6..c2c6de0fe 100644 --- a/pkg/common/mw/specialerror/error.go +++ b/pkg/common/mw/specialerror/error.go @@ -16,6 +16,7 @@ package specialerror import ( "errors" + "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" ) From e67aed5af59dc44391f8a65b40f169e2aa4b224f Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Sun, 23 Jul 2023 11:59:32 +0800 Subject: [PATCH 41/62] fix: changing naming irregularities under pkg and internal packages (#520) --- pkg/common/convert/black.go | 1 + pkg/common/mw/rpc_server_interceptor.go | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pkg/common/convert/black.go b/pkg/common/convert/black.go index ba0e2a5da..f8d69ef29 100644 --- a/pkg/common/convert/black.go +++ b/pkg/common/convert/black.go @@ -54,5 +54,6 @@ func BlackDB2Pb( } blackPbs = append(blackPbs, blackPb) } + return blackPbs, nil } diff --git a/pkg/common/mw/rpc_server_interceptor.go b/pkg/common/mw/rpc_server_interceptor.go index 0dba76103..981f7454d 100644 --- a/pkg/common/mw/rpc_server_interceptor.go +++ b/pkg/common/mw/rpc_server_interceptor.go @@ -110,13 +110,15 @@ func RpcServerInterceptor( } log.ZInfo(ctx, "rpc server req", "funcName", funcName, "req", rpcString(req)) resp, err = func() (interface{}, error) { - if err := checker.Validate(req); err != nil { + if err = checker.Validate(req); err != nil { return nil, err } + return handler(ctx, req) }() if err == nil { log.ZInfo(ctx, "rpc server resp", "funcName", funcName, "resp", rpcString(resp)) + return resp, nil } log.ZError(ctx, "rpc server resp", err, "funcName", funcName) @@ -134,7 +136,7 @@ func RpcServerInterceptor( grpcStatus := status.New(codes.Code(code), codeErr.Msg()) var errInfo *errinfo.ErrorInfo if config.Config.Log.WithStack { - if unwrap != err { + if errors.Is(err, unwrap) { var sti interface{ StackTrace() errors.StackTrace } if errors.As(err, &sti) { log.ZWarn( @@ -172,6 +174,7 @@ func RpcServerInterceptor( details, err := grpcStatus.WithDetails(errInfo) if err != nil { log.ZWarn(ctx, "rpc server resp WithDetails error", err, "funcName", funcName) + return nil, errs.Wrap(err) } log.ZWarn(ctx, "rpc server resp", err, "funcName", funcName) From e2b10c10d44f9308fcf504d3e25b85ce2721eca2 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Sun, 23 Jul 2023 12:05:27 +0800 Subject: [PATCH 42/62] Revert "fix: changing naming irregularities under pkg and internal packages (#520)" This reverts commit e67aed5af59dc44391f8a65b40f169e2aa4b224f. --- pkg/common/convert/black.go | 1 - pkg/common/mw/rpc_server_interceptor.go | 7 ++----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/pkg/common/convert/black.go b/pkg/common/convert/black.go index f8d69ef29..ba0e2a5da 100644 --- a/pkg/common/convert/black.go +++ b/pkg/common/convert/black.go @@ -54,6 +54,5 @@ func BlackDB2Pb( } blackPbs = append(blackPbs, blackPb) } - return blackPbs, nil } diff --git a/pkg/common/mw/rpc_server_interceptor.go b/pkg/common/mw/rpc_server_interceptor.go index 981f7454d..0dba76103 100644 --- a/pkg/common/mw/rpc_server_interceptor.go +++ b/pkg/common/mw/rpc_server_interceptor.go @@ -110,15 +110,13 @@ func RpcServerInterceptor( } log.ZInfo(ctx, "rpc server req", "funcName", funcName, "req", rpcString(req)) resp, err = func() (interface{}, error) { - if err = checker.Validate(req); err != nil { + if err := checker.Validate(req); err != nil { return nil, err } - return handler(ctx, req) }() if err == nil { log.ZInfo(ctx, "rpc server resp", "funcName", funcName, "resp", rpcString(resp)) - return resp, nil } log.ZError(ctx, "rpc server resp", err, "funcName", funcName) @@ -136,7 +134,7 @@ func RpcServerInterceptor( grpcStatus := status.New(codes.Code(code), codeErr.Msg()) var errInfo *errinfo.ErrorInfo if config.Config.Log.WithStack { - if errors.Is(err, unwrap) { + if unwrap != err { var sti interface{ StackTrace() errors.StackTrace } if errors.As(err, &sti) { log.ZWarn( @@ -174,7 +172,6 @@ func RpcServerInterceptor( details, err := grpcStatus.WithDetails(errInfo) if err != nil { log.ZWarn(ctx, "rpc server resp WithDetails error", err, "funcName", funcName) - return nil, errs.Wrap(err) } log.ZWarn(ctx, "rpc server resp", err, "funcName", funcName) From 41bb6137915aa4f85ba786d4e28ebcb7a7efd1f5 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Sun, 23 Jul 2023 12:05:48 +0800 Subject: [PATCH 43/62] fix: changing naming irregularities under pkg and internal packages Signed-off-by: BanTanger <1290288968@qq.com> --- pkg/common/mw/specialerror/error.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/common/mw/specialerror/error.go b/pkg/common/mw/specialerror/error.go index b843ad0d6..c2c6de0fe 100644 --- a/pkg/common/mw/specialerror/error.go +++ b/pkg/common/mw/specialerror/error.go @@ -16,6 +16,7 @@ package specialerror import ( "errors" + "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" ) From 8b58073daf657afaed93e893607c9e3ca203b7ee Mon Sep 17 00:00:00 2001 From: Alan <68671759+hanzhixiao@users.noreply.github.com> Date: Fri, 14 Jul 2023 19:14:18 +0800 Subject: [PATCH 44/62] message for your changes (#565) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’> Co-authored-by: ‘hanzhixiao’ <‘709674996@qq.com’> Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- build.cmd | 1 + 1 file changed, 1 insertion(+) create mode 100644 build.cmd diff --git a/build.cmd b/build.cmd new file mode 100644 index 000000000..4c53576c0 --- /dev/null +++ b/build.cmd @@ -0,0 +1 @@ +go build -o \ No newline at end of file From 05bd5570c0440bf64e8c9d2b080a79a24ecae7ea Mon Sep 17 00:00:00 2001 From: Alan <68671759+hanzhixiao@users.noreply.github.com> Date: Fri, 14 Jul 2023 20:40:41 +0800 Subject: [PATCH 45/62] debug (#566) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * message for your changes Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’> * debug Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’> * Delete start.bat * Delete build.cmd --------- Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’> Co-authored-by: ‘hanzhixiao’ <‘709674996@qq.com’> Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- build.cmd | 1 - 1 file changed, 1 deletion(-) delete mode 100644 build.cmd diff --git a/build.cmd b/build.cmd deleted file mode 100644 index 4c53576c0..000000000 --- a/build.cmd +++ /dev/null @@ -1 +0,0 @@ -go build -o \ No newline at end of file From 4161b9bde5135d8a14a81b56ca80ec7f075ff13d Mon Sep 17 00:00:00 2001 From: WangchuXiao Date: Fri, 14 Jul 2023 20:46:25 +0800 Subject: [PATCH 46/62] fix bug: multiple gateway kick user (#568) * new feature: add batch send msg * new feature: add batch send msg * new feature: add batch send msg * new feature: add batch send msg * new feature: add batch send msg * new feature: add batch send msg * fix bug: multiple gateway kick user * fix bug: multiple gateway kick user * fix bug: multiple gateway kick user * fix bug: multiple gateway kick user * fix bug: multiple gateway kick user Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- internal/tools/cron_task.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/tools/cron_task.go b/internal/tools/cron_task.go index 5e4183615..82343157b 100644 --- a/internal/tools/cron_task.go +++ b/internal/tools/cron_task.go @@ -41,11 +41,11 @@ func StartCronTask() error { panic(err) } log.ZInfo(context.Background(), "start msgDestruct cron task", "cron config", config.Config.MsgDestructTime) - _, err = c.AddFunc(config.Config.MsgDestructTime, msgTool.ConversationsDestructMsgs) - if err != nil { - fmt.Println("start conversationsDestructMsgs cron failed", err.Error(), config.Config.ChatRecordsClearTime) - panic(err) - } + // _, err = c.AddFunc(config.Config.MsgDestructTime, msgTool.ConversationsDestructMsgs) + // if err != nil { + // fmt.Println("start conversationsDestructMsgs cron failed", err.Error(), config.Config.ChatRecordsClearTime) + // panic(err) + // } c.Start() wg.Wait() return nil From ca4483c681c8d69ae39512b0bef0c62a866c9fc5 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Fri, 14 Jul 2023 20:54:24 +0800 Subject: [PATCH 47/62] fix: implement of GetUsersOnlineStatus (#567) (#569) Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- internal/msggateway/hub_server.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/internal/msggateway/hub_server.go b/internal/msggateway/hub_server.go index deb8c3d77..4922437cb 100644 --- a/internal/msggateway/hub_server.go +++ b/internal/msggateway/hub_server.go @@ -83,9 +83,6 @@ func (s *Server) GetUsersOnlineStatus( ctx context.Context, req *msggateway.GetUsersOnlineStatusReq, ) (*msggateway.GetUsersOnlineStatusResp, error) { - if !tokenverify.IsAppManagerUid(ctx) { - return nil, errs.ErrNoPermission.Wrap("only app manager") - } var resp msggateway.GetUsersOnlineStatusResp for _, userID := range req.UserIDs { clients, ok := s.LongConnServer.GetUserAllCons(userID) From 3c2723fd03e5084ce51d2fdef484dad6d1fd2871 Mon Sep 17 00:00:00 2001 From: kubbot <3293172751ysy@gmail.com> Date: Fri, 14 Jul 2023 21:14:22 +0800 Subject: [PATCH 48/62] release: v3.0 release Signed-off-by: kubbot <3293172751ysy@gmail.com> Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- docker-compose.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 23565c23a..0b32d2d50 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -100,7 +100,7 @@ services: openim_server: - image: ghcr.io/openimsdk/openim-server:v3.0 + image: ghcr.io/openimsdk/openim-server:v3.0.1 container_name: openim-server volumes: - ./logs:/Open-IM-Server/logs @@ -123,7 +123,7 @@ services: max-file: "2" openim_chat: - image: ghcr.io/openimsdk/openim-chat:v1.0.0 + image: openim/openim_chat:v1.1.0 container_name: openim_chat restart: always depends_on: From 493ea3e4750f9a3c13d22b07982c0c8c20e9a68f Mon Sep 17 00:00:00 2001 From: kubbot <3293172751ysy@gmail.com> Date: Fri, 14 Jul 2023 21:39:30 +0800 Subject: [PATCH 49/62] fix: script v3.0 Signed-off-by: kubbot <3293172751ysy@gmail.com> Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- install_im_compose.sh | 21 +++++++++++++++++++++ install_im_server.sh | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 install_im_compose.sh create mode 100644 install_im_server.sh diff --git a/install_im_compose.sh b/install_im_compose.sh new file mode 100644 index 000000000..687a827d1 --- /dev/null +++ b/install_im_compose.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +internet_ip=`curl ifconfig.me -s` +echo $internet_ip + +source .env +echo $MINIO_ENDPOINT +if [ $MINIO_ENDPOINT == "http://127.0.0.1:10005" ]; then + sed -i "s/127.0.0.1/${internet_ip}/" .env + +fi + +cd scripts ; +chmod +x *.sh ; +./init_pwd.sh +./env_check.sh; +cd .. ; +docker-compose -f im-compose.yaml up -d +docker ps + + + diff --git a/install_im_server.sh b/install_im_server.sh new file mode 100644 index 000000000..c526d43db --- /dev/null +++ b/install_im_server.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +# Get the public internet IP address +internet_ip=$(curl ifconfig.me -s) +echo $internet_ip + +# Load environment variables from .env file +source .env +echo $MINIO_ENDPOINT + +# Replace local IP address with the public IP address in .env file +if [ $API_URL == "http://127.0.0.1:10002/object/" ]; then + sed -i "s/127.0.0.1/${internet_ip}/" .env +fi + +if [ $MINIO_ENDPOINT == "http://127.0.0.1:10005" ]; then + sed -i "s/127.0.0.1/${internet_ip}/" .env +fi + +# Change directory to scripts folder +cd scripts +chmod +x *.sh + +# Execute necessary scripts +./init_pwd.sh +./env_check.sh + +# Go back to the previous directory +cd .. + +# Check if docker-compose command is available +if command -v docker-compose &> /dev/null +then + docker-compose up -d +else + docker compose up -d +fi + +# Change directory to scripts folder again +cd scripts + +# Check docker services +./docker_check_service.sh \ No newline at end of file From d6ca0dbf3b0178615641363afc5b2cd4a5ded5cc Mon Sep 17 00:00:00 2001 From: kubbot <3293172751ysy@gmail.com> Date: Fri, 14 Jul 2023 21:54:23 +0800 Subject: [PATCH 50/62] build: fix chat docker images Signed-off-by: kubbot <3293172751ysy@gmail.com> Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- docker-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 0b32d2d50..206e008f7 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -123,7 +123,7 @@ services: max-file: "2" openim_chat: - image: openim/openim_chat:v1.1.0 + image: ghcr.io/openimsdk/openim-chat:v1.0.0 container_name: openim_chat restart: always depends_on: From e61e47736437444cfe35d788a44d34eb470ddf12 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Mon, 17 Jul 2023 16:32:28 +0800 Subject: [PATCH 51/62] fix bug: obtain user online status err(#567) Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- internal/msggateway/hub_server.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/msggateway/hub_server.go b/internal/msggateway/hub_server.go index 4922437cb..deb8c3d77 100644 --- a/internal/msggateway/hub_server.go +++ b/internal/msggateway/hub_server.go @@ -83,6 +83,9 @@ func (s *Server) GetUsersOnlineStatus( ctx context.Context, req *msggateway.GetUsersOnlineStatusReq, ) (*msggateway.GetUsersOnlineStatusResp, error) { + if !tokenverify.IsAppManagerUid(ctx) { + return nil, errs.ErrNoPermission.Wrap("only app manager") + } var resp msggateway.GetUsersOnlineStatusResp for _, userID := range req.UserIDs { clients, ok := s.LongConnServer.GetUserAllCons(userID) From 180c07e3570907ce138a9707aa020f2a27fe2bc5 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Fri, 14 Jul 2023 20:07:26 +0800 Subject: [PATCH 52/62] fix: implement of GetUsersOnlineStatus (#567) --- internal/msggateway/hub_server.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/internal/msggateway/hub_server.go b/internal/msggateway/hub_server.go index deb8c3d77..4922437cb 100644 --- a/internal/msggateway/hub_server.go +++ b/internal/msggateway/hub_server.go @@ -83,9 +83,6 @@ func (s *Server) GetUsersOnlineStatus( ctx context.Context, req *msggateway.GetUsersOnlineStatusReq, ) (*msggateway.GetUsersOnlineStatusResp, error) { - if !tokenverify.IsAppManagerUid(ctx) { - return nil, errs.ErrNoPermission.Wrap("only app manager") - } var resp msggateway.GetUsersOnlineStatusResp for _, userID := range req.UserIDs { clients, ok := s.LongConnServer.GetUserAllCons(userID) From a2cf437893d11b30ee30b8838d90ea56fe65f1e6 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Mon, 17 Jul 2023 16:29:01 +0800 Subject: [PATCH 53/62] fix bug: obtain user online status err(#567) Signed-off-by: BanTanger <88583317+BanTanger@users.noreply.github.com> --- internal/msggateway/hub_server.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/msggateway/hub_server.go b/internal/msggateway/hub_server.go index 4922437cb..deb8c3d77 100644 --- a/internal/msggateway/hub_server.go +++ b/internal/msggateway/hub_server.go @@ -83,6 +83,9 @@ func (s *Server) GetUsersOnlineStatus( ctx context.Context, req *msggateway.GetUsersOnlineStatusReq, ) (*msggateway.GetUsersOnlineStatusResp, error) { + if !tokenverify.IsAppManagerUid(ctx) { + return nil, errs.ErrNoPermission.Wrap("only app manager") + } var resp msggateway.GetUsersOnlineStatusResp for _, userID := range req.UserIDs { clients, ok := s.LongConnServer.GetUserAllCons(userID) From 834551b153b5da9a5e7703315808b30f4ae6f552 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Sun, 23 Jul 2023 10:46:41 +0800 Subject: [PATCH 54/62] fix: changing naming irregularities under pkg and internal packages (#520) --- pkg/rpcclient/msg.go | 16 +++++++ pkg/rpcclient/notification/common.go | 2 + pkg/rpcclient/notification/conevrsation.go | 11 +++-- pkg/rpcclient/notification/friend.go | 31 +++++++++++++- pkg/rpcclient/notification/group.go | 49 +++++++++++++++++++++- pkg/rpcclient/notification/msg.go | 6 +++ pkg/rpcclient/push.go | 6 +++ pkg/rpcclient/third.go | 12 ++++-- pkg/rpcclient/user.go | 24 +++++++++++ pkg/startrpc/start.go | 2 + pkg/statistics/statistics.go | 5 +++ 11 files changed, 153 insertions(+), 11 deletions(-) diff --git a/pkg/rpcclient/msg.go b/pkg/rpcclient/msg.go index a012a5a5f..be776138b 100644 --- a/pkg/rpcclient/msg.go +++ b/pkg/rpcclient/msg.go @@ -154,17 +154,21 @@ func (m *MessageRpcClient) GetMaxSeq(ctx context.Context, req *sdkws.GetMaxSeqRe func (m *MessageRpcClient) PullMessageBySeqList(ctx context.Context, req *sdkws.PullMessageBySeqsReq) (*sdkws.PullMessageBySeqsResp, error) { resp, err := m.Client.PullMessageBySeqs(ctx, req) + return resp, err } +// GetConversationMaxSeq func (m *MessageRpcClient) GetConversationMaxSeq(ctx context.Context, conversationID string) (int64, error) { resp, err := m.Client.GetConversationMaxSeq(ctx, &msg.GetConversationMaxSeqReq{ConversationID: conversationID}) if err != nil { return 0, err } + return resp.MaxSeq, nil } +// NotificationSender type NotificationSender struct { contentTypeConf map[int32]config.NotificationConf sessionTypeConf map[int32]int32 @@ -172,31 +176,37 @@ type NotificationSender struct { getUserInfo func(ctx context.Context, userID string) (*sdkws.UserInfo, error) } +// NotificationSenderOptions type NotificationSenderOptions func(*NotificationSender) +// WithLocalSendMsg func WithLocalSendMsg(sendMsg func(ctx context.Context, req *msg.SendMsgReq) (*msg.SendMsgResp, error)) NotificationSenderOptions { return func(s *NotificationSender) { s.sendMsg = sendMsg } } +// WithRpcClient func WithRpcClient(msgRpcClient *MessageRpcClient) NotificationSenderOptions { return func(s *NotificationSender) { s.sendMsg = msgRpcClient.SendMsg } } +// WithUserRpcClient func WithUserRpcClient(userRpcClient *UserRpcClient) NotificationSenderOptions { return func(s *NotificationSender) { s.getUserInfo = userRpcClient.GetUserInfo } } +// NewNotificationSender func NewNotificationSender(opts ...NotificationSenderOptions) *NotificationSender { notificationSender := &NotificationSender{contentTypeConf: newContentTypeConf(), sessionTypeConf: newSessionTypeConf()} for _, opt := range opts { opt(notificationSender) } + return notificationSender } @@ -204,19 +214,23 @@ type notificationOpt struct { WithRpcGetUsername bool } +// NotificationOptions type NotificationOptions func(*notificationOpt) +// WithRpcGetUserName func WithRpcGetUserName() NotificationOptions { return func(opt *notificationOpt) { opt.WithRpcGetUsername = true } } +// NotificationWithSesstionType func (s *NotificationSender) NotificationWithSesstionType(ctx context.Context, sendID, recvID string, contentType, sesstionType int32, m proto.Message, opts ...NotificationOptions) (err error) { n := sdkws.NotificationElem{Detail: utils.StructToJsonString(m)} content, err := json.Marshal(&n) if err != nil { log.ZError(ctx, "MsgClient Notification json.Marshal failed", err, "sendID", sendID, "recvID", recvID, "contentType", contentType, "msg", m) + return err } notificationOpt := ¬ificationOpt{} @@ -260,9 +274,11 @@ func (s *NotificationSender) NotificationWithSesstionType(ctx context.Context, s } else { log.ZError(ctx, "MsgClient Notification SendMsg failed", err, "req", &req) } + return err } +// Notification func (s *NotificationSender) Notification(ctx context.Context, sendID, recvID string, contentType int32, m proto.Message, opts ...NotificationOptions) error { return s.NotificationWithSesstionType(ctx, sendID, recvID, contentType, s.sessionTypeConf[contentType], m, opts...) } diff --git a/pkg/rpcclient/notification/common.go b/pkg/rpcclient/notification/common.go index 09d8b8798..d595f836b 100644 --- a/pkg/rpcclient/notification/common.go +++ b/pkg/rpcclient/notification/common.go @@ -14,6 +14,7 @@ package notification +// CommonUser type CommonUser interface { GetNickname() string GetFaceURL() string @@ -21,6 +22,7 @@ type CommonUser interface { GetEx() string } +// CommonGroup type CommonGroup interface { GetNickname() string GetFaceURL() string diff --git a/pkg/rpcclient/notification/conevrsation.go b/pkg/rpcclient/notification/conevrsation.go index d2995df3d..963012009 100644 --- a/pkg/rpcclient/notification/conevrsation.go +++ b/pkg/rpcclient/notification/conevrsation.go @@ -22,15 +22,17 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient" ) +// ConversationNotificationSender type ConversationNotificationSender struct { *rpcclient.NotificationSender } +// NewConversationNotificationSender func NewConversationNotificationSender(msgRpcClient *rpcclient.MessageRpcClient) *ConversationNotificationSender { return &ConversationNotificationSender{rpcclient.NewNotificationSender(rpcclient.WithRpcClient(msgRpcClient))} } -// SetPrivate调用. +// ConversationSetPrivateNotification func (c *ConversationNotificationSender) ConversationSetPrivateNotification( ctx context.Context, sendID, recvID string, @@ -41,18 +43,20 @@ func (c *ConversationNotificationSender) ConversationSetPrivateNotification( SendID: sendID, IsPrivate: isPrivateChat, } + return c.Notification(ctx, sendID, recvID, constant.ConversationPrivateChatNotification, tips) } -// 会话改变. +// ConversationChangeNotification func (c *ConversationNotificationSender) ConversationChangeNotification(ctx context.Context, userID string) error { tips := &sdkws.ConversationUpdateTips{ UserID: userID, } + return c.Notification(ctx, userID, userID, constant.ConversationChangeNotification, tips) } -// 会话未读数同步. +// ConversationUnreadChangeNotification func (c *ConversationNotificationSender) ConversationUnreadChangeNotification( ctx context.Context, userID, conversationID string, @@ -64,5 +68,6 @@ func (c *ConversationNotificationSender) ConversationUnreadChangeNotification( HasReadSeq: hasReadSeq, UnreadCountTime: unreadCountTime, } + return c.Notification(ctx, userID, userID, constant.ConversationUnreadNotification, tips) } diff --git a/pkg/rpcclient/notification/friend.go b/pkg/rpcclient/notification/friend.go index e7df2e6cd..496377a00 100644 --- a/pkg/rpcclient/notification/friend.go +++ b/pkg/rpcclient/notification/friend.go @@ -28,9 +28,10 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient" ) +// FriendNotificationSender type FriendNotificationSender struct { *rpcclient.NotificationSender - // 找不到报错 + // if not finded, return err getUsersInfo func(ctx context.Context, userIDs []string) ([]CommonUser, error) // db controller db controller.FriendDatabase @@ -38,12 +39,14 @@ type FriendNotificationSender struct { type friendNotificationSenderOptions func(*FriendNotificationSender) +// WithFriendDB func WithFriendDB(db controller.FriendDatabase) friendNotificationSenderOptions { return func(s *FriendNotificationSender) { s.db = db } } +// WithDBFunc func WithDBFunc( fn func(ctx context.Context, userIDs []string) (users []*relationTb.UserModel, err error), ) friendNotificationSenderOptions { @@ -56,12 +59,14 @@ func WithDBFunc( for _, user := range users { result = append(result, user) } + return result, nil } s.getUsersInfo = f } } +// WithRpcFunc func WithRpcFunc( fn func(ctx context.Context, userIDs []string) ([]*sdkws.UserInfo, error), ) friendNotificationSenderOptions { @@ -74,12 +79,14 @@ func WithRpcFunc( for _, user := range users { result = append(result, user) } + return result, err } s.getUsersInfo = f } } +// NewFriendNotificationSender func NewFriendNotificationSender( msgRpcClient *rpcclient.MessageRpcClient, opts ...friendNotificationSenderOptions, @@ -90,6 +97,7 @@ func NewFriendNotificationSender( for _, opt := range opts { opt(f) } + return f } @@ -105,6 +113,7 @@ func (f *FriendNotificationSender) getUsersInfoMap( for _, user := range users { result[user.GetUserID()] = user.(*sdkws.UserInfo) } + return result, nil } @@ -114,16 +123,20 @@ func (f *FriendNotificationSender) getFromToUserNickname( ) (string, string, error) { users, err := f.getUsersInfoMap(ctx, []string{fromUserID, toUserID}) if err != nil { - return "", "", nil + return "", "", err } + return users[fromUserID].Nickname, users[toUserID].Nickname, nil } +// UserInfoUpdatedNotification func (f *FriendNotificationSender) UserInfoUpdatedNotification(ctx context.Context, changedUserID string) error { tips := sdkws.UserInfoUpdatedTips{UserID: changedUserID} + return f.Notification(ctx, mcontext.GetOpUserID(ctx), changedUserID, constant.UserInfoUpdatedNotification, &tips) } +// FriendApplicationAddNotification func (f *FriendNotificationSender) FriendApplicationAddNotification( ctx context.Context, req *pbFriend.ApplyToAddFriendReq, @@ -132,9 +145,11 @@ func (f *FriendNotificationSender) FriendApplicationAddNotification( FromUserID: req.FromUserID, ToUserID: req.ToUserID, }} + return f.Notification(ctx, req.FromUserID, req.ToUserID, constant.FriendApplicationNotification, &tips) } +// FriendApplicationAgreedNotification func (c *FriendNotificationSender) FriendApplicationAgreedNotification( ctx context.Context, req *pbFriend.RespondFriendApplyReq, @@ -143,6 +158,7 @@ func (c *FriendNotificationSender) FriendApplicationAgreedNotification( FromUserID: req.FromUserID, ToUserID: req.ToUserID, }, HandleMsg: req.HandleMsg} + return c.Notification(ctx, req.ToUserID, req.FromUserID, constant.FriendApplicationApprovedNotification, &tips) } @@ -154,9 +170,11 @@ func (c *FriendNotificationSender) FriendApplicationRefusedNotification( FromUserID: req.FromUserID, ToUserID: req.ToUserID, }, HandleMsg: req.HandleMsg} + return c.Notification(ctx, req.ToUserID, req.FromUserID, constant.FriendApplicationRejectedNotification, &tips) } +// FriendAddedNotification func (c *FriendNotificationSender) FriendAddedNotification( ctx context.Context, operationID, opUserID, fromUserID, toUserID string, @@ -178,31 +196,39 @@ func (c *FriendNotificationSender) FriendAddedNotification( if err != nil { return err } + return c.Notification(ctx, fromUserID, toUserID, constant.FriendAddedNotification, &tips) } +// FriendDeletedNotification func (c *FriendNotificationSender) FriendDeletedNotification(ctx context.Context, req *pbFriend.DeleteFriendReq) error { tips := sdkws.FriendDeletedTips{FromToUserID: &sdkws.FromToUserID{ FromUserID: req.OwnerUserID, ToUserID: req.FriendUserID, }} + return c.Notification(ctx, req.OwnerUserID, req.FriendUserID, constant.FriendDeletedNotification, &tips) } +// FriendRemarkSetNotification func (c *FriendNotificationSender) FriendRemarkSetNotification(ctx context.Context, fromUserID, toUserID string) error { tips := sdkws.FriendInfoChangedTips{FromToUserID: &sdkws.FromToUserID{}} tips.FromToUserID.FromUserID = fromUserID tips.FromToUserID.ToUserID = toUserID + return c.Notification(ctx, fromUserID, toUserID, constant.FriendRemarkSetNotification, &tips) } +// BlackAddedNotification func (c *FriendNotificationSender) BlackAddedNotification(ctx context.Context, req *pbFriend.AddBlackReq) error { tips := sdkws.BlackAddedTips{FromToUserID: &sdkws.FromToUserID{}} tips.FromToUserID.FromUserID = req.OwnerUserID tips.FromToUserID.ToUserID = req.BlackUserID + return c.Notification(ctx, req.OwnerUserID, req.BlackUserID, constant.BlackAddedNotification, &tips) } +// BlackDeletedNotification func (c *FriendNotificationSender) BlackDeletedNotification(ctx context.Context, req *pbFriend.RemoveBlackReq) { blackDeletedTips := sdkws.BlackDeletedTips{FromToUserID: &sdkws.FromToUserID{ FromUserID: req.OwnerUserID, @@ -211,6 +237,7 @@ func (c *FriendNotificationSender) BlackDeletedNotification(ctx context.Context, c.Notification(ctx, req.OwnerUserID, req.BlackUserID, constant.BlackDeletedNotification, &blackDeletedTips) } +// FriendInfoUpdatedNotification func (c *FriendNotificationSender) FriendInfoUpdatedNotification( ctx context.Context, changedUserID string, diff --git a/pkg/rpcclient/notification/group.go b/pkg/rpcclient/notification/group.go index 22aa694c7..abdc4d76e 100644 --- a/pkg/rpcclient/notification/group.go +++ b/pkg/rpcclient/notification/group.go @@ -30,6 +30,7 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/utils" ) +// NewGroupNotificationSender func NewGroupNotificationSender( db controller.GroupDatabase, msgRpcClient *rpcclient.MessageRpcClient, @@ -43,6 +44,7 @@ func NewGroupNotificationSender( } } +// GroupNotificationSender type GroupNotificationSender struct { *rpcclient.NotificationSender getUsersInfo func(ctx context.Context, userIDs []string) ([]CommonUser, error) @@ -57,6 +59,7 @@ func (g *GroupNotificationSender) getUser(ctx context.Context, userID string) (* if len(users) == 0 { return nil, errs.ErrUserIDNotFound.Wrap(fmt.Sprintf("user %s not found", userID)) } + return &sdkws.PublicUserInfo{ UserID: users[0].GetUserID(), Nickname: users[0].GetNickname(), @@ -78,6 +81,7 @@ func (g *GroupNotificationSender) getGroupInfo(ctx context.Context, groupID stri if err != nil { return nil, err } + return &sdkws.GroupInfo{ GroupID: gm.GroupID, GroupName: gm.GroupName, @@ -122,7 +126,7 @@ func (g *GroupNotificationSender) getGroupMembers(ctx context.Context, groupID s res = append(res, g.groupMemberDB2PB(member, user.AppMangerLevel)) delete(users, member.UserID) } - //for userID, info := range users { + // for userID, info := range users { // if info.AppMangerLevel == constant.AppAdmin { // res = append(res, &sdkws.GroupMemberFullInfo{ // GroupID: groupID, @@ -132,7 +136,7 @@ func (g *GroupNotificationSender) getGroupMembers(ctx context.Context, groupID s // AppMangerLevel: info.AppMangerLevel, // }) // } - //} + // } return res, nil } @@ -145,6 +149,7 @@ func (g *GroupNotificationSender) getGroupMemberMap(ctx context.Context, groupID for i, member := range members { m[member.UserID] = members[i] } + return m, nil } @@ -156,6 +161,7 @@ func (g *GroupNotificationSender) getGroupMember(ctx context.Context, groupID st if len(members) == 0 { return nil, errs.ErrInternalServer.Wrap(fmt.Sprintf("group %s member %s not found", groupID, userID)) } + return members[0], nil } @@ -165,6 +171,7 @@ func (g *GroupNotificationSender) getGroupOwnerAndAdminUserID(ctx context.Contex return nil, err } fn := func(e *relation.GroupMemberModel) string { return e.UserID } + return utils.Slice(members, fn), nil } @@ -216,6 +223,7 @@ func (g *GroupNotificationSender) getUsersInfoMap(ctx context.Context, userIDs [ for _, user := range users { result[user.GetUserID()] = user.(*sdkws.UserInfo) } + return result, nil } @@ -255,37 +263,47 @@ func (g *GroupNotificationSender) fillOpUser(ctx context.Context, opUser **sdkws (*opUser).FaceURL = user.FaceURL } } + return nil } +// GroupCreatedNotification func (g *GroupNotificationSender) GroupCreatedNotification(ctx context.Context, tips *sdkws.GroupCreatedTips) (err error) { if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupCreatedNotification, tips) } +// GroupInfoSetNotification func (g *GroupNotificationSender) GroupInfoSetNotification(ctx context.Context, tips *sdkws.GroupInfoSetTips) (err error) { if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupInfoSetNotification, tips, rpcclient.WithRpcGetUserName()) } +// GroupInfoSetNameNotification func (g *GroupNotificationSender) GroupInfoSetNameNotification(ctx context.Context, tips *sdkws.GroupInfoSetNameTips) (err error) { if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupInfoSetNameNotification, tips) } +// GroupInfoSetAnnouncementNotification func (g *GroupNotificationSender) GroupInfoSetAnnouncementNotification(ctx context.Context, tips *sdkws.GroupInfoSetAnnouncementTips) (err error) { if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupInfoSetAnnouncementNotification, tips, rpcclient.WithRpcGetUserName()) } +// JoinGroupApplicationNotification func (g *GroupNotificationSender) JoinGroupApplicationNotification(ctx context.Context, req *pbGroup.JoinGroupReq) (err error) { group, err := g.getGroupInfo(ctx, req.GroupID) if err != nil { @@ -307,9 +325,11 @@ func (g *GroupNotificationSender) JoinGroupApplicationNotification(ctx context.C log.ZError(ctx, "JoinGroupApplicationNotification failed", err, "group", req.GroupID, "userID", userID) } } + return nil } +// MemberQuitNotification func (g *GroupNotificationSender) MemberQuitNotification(ctx context.Context, member *sdkws.GroupMemberFullInfo) (err error) { defer log.ZDebug(ctx, "return") defer func() { @@ -322,9 +342,11 @@ func (g *GroupNotificationSender) MemberQuitNotification(ctx context.Context, me return err } tips := &sdkws.MemberQuitTips{Group: group, QuitUser: member} + return g.Notification(ctx, mcontext.GetOpUserID(ctx), member.GroupID, constant.MemberQuitNotification, tips) } +// GroupApplicationAcceptedNotification func (g *GroupNotificationSender) GroupApplicationAcceptedNotification(ctx context.Context, req *pbGroup.GroupApplicationResponseReq) (err error) { defer log.ZDebug(ctx, "return") defer func() { @@ -350,9 +372,11 @@ func (g *GroupNotificationSender) GroupApplicationAcceptedNotification(ctx conte log.ZError(ctx, "failed", err) } } + return nil } +// GroupApplicationRejectedNotification func (g *GroupNotificationSender) GroupApplicationRejectedNotification(ctx context.Context, req *pbGroup.GroupApplicationResponseReq) (err error) { group, err := g.getGroupInfo(ctx, req.GroupID) if err != nil { @@ -372,9 +396,11 @@ func (g *GroupNotificationSender) GroupApplicationRejectedNotification(ctx conte log.ZError(ctx, "failed", err) } } + return nil } +// GroupOwnerTransferredNotification func (g *GroupNotificationSender) GroupOwnerTransferredNotification(ctx context.Context, req *pbGroup.TransferGroupOwnerReq) (err error) { group, err := g.getGroupInfo(ctx, req.GroupID) if err != nil { @@ -389,16 +415,20 @@ func (g *GroupNotificationSender) GroupOwnerTransferredNotification(ctx context. if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupOwnerTransferredNotification, tips) } +// MemberKickedNotification func (g *GroupNotificationSender) MemberKickedNotification(ctx context.Context, tips *sdkws.MemberKickedTips) (err error) { if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.MemberKickedNotification, tips) } +// MemberInvitedNotification func (g *GroupNotificationSender) MemberInvitedNotification(ctx context.Context, groupID, reason string, invitedUserIDList []string) (err error) { group, err := g.getGroupInfo(ctx, groupID) if err != nil { @@ -415,9 +445,11 @@ func (g *GroupNotificationSender) MemberInvitedNotification(ctx context.Context, if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.MemberInvitedNotification, tips) } +// MemberEnterNotification func (g *GroupNotificationSender) MemberEnterNotification(ctx context.Context, req *pbGroup.GroupApplicationResponseReq) (err error) { group, err := g.getGroupInfo(ctx, req.GroupID) if err != nil { @@ -435,9 +467,11 @@ func (g *GroupNotificationSender) GroupDismissedNotification(ctx context.Context if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupDismissedNotification, tips) } +// GroupMemberMutedNotification func (g *GroupNotificationSender) GroupMemberMutedNotification(ctx context.Context, groupID, groupMemberUserID string, mutedSeconds uint32) (err error) { group, err := g.getGroupInfo(ctx, groupID) if err != nil { @@ -454,6 +488,7 @@ func (g *GroupNotificationSender) GroupMemberMutedNotification(ctx context.Conte if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberMutedNotification, tips) } @@ -470,6 +505,7 @@ func (g *GroupNotificationSender) GroupMemberCancelMutedNotification(ctx context if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberCancelMutedNotification, tips) } @@ -489,6 +525,7 @@ func (g *GroupNotificationSender) GroupMutedNotification(ctx context.Context, gr if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMutedNotification, tips) } @@ -508,9 +545,11 @@ func (g *GroupNotificationSender) GroupCancelMutedNotification(ctx context.Conte if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupCancelMutedNotification, tips) } +// GroupMemberInfoSetNotification func (g *GroupNotificationSender) GroupMemberInfoSetNotification(ctx context.Context, groupID, groupMemberUserID string) (err error) { group, err := g.getGroupInfo(ctx, groupID) if err != nil { @@ -524,6 +563,7 @@ func (g *GroupNotificationSender) GroupMemberInfoSetNotification(ctx context.Con if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberInfoSetNotification, tips) } @@ -540,6 +580,7 @@ func (g *GroupNotificationSender) GroupMemberSetToAdminNotification(ctx context. if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberSetToAdminNotification, tips) } @@ -559,6 +600,7 @@ func (g *GroupNotificationSender) GroupMemberSetToOrdinaryUserNotification(ctx c return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberSetToOrdinaryUserNotification, tips) } +// MemberEnterDirectlyNotification func (g *GroupNotificationSender) MemberEnterDirectlyNotification(ctx context.Context, groupID string, entrantUserID string) (err error) { defer log.ZDebug(ctx, "return") defer func() { @@ -575,9 +617,11 @@ func (g *GroupNotificationSender) MemberEnterDirectlyNotification(ctx context.Co return err } tips := &sdkws.MemberEnterTips{Group: group, EntrantUser: user} + return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.MemberEnterNotification, tips) } +// SuperGroupNotification func (g *GroupNotificationSender) SuperGroupNotification(ctx context.Context, sendID, recvID string) (err error) { defer log.ZDebug(ctx, "return") defer func() { @@ -586,5 +630,6 @@ func (g *GroupNotificationSender) SuperGroupNotification(ctx context.Context, se } }() err = g.Notification(ctx, sendID, recvID, constant.SuperGroupUpdateNotification, nil) + return err } diff --git a/pkg/rpcclient/notification/msg.go b/pkg/rpcclient/notification/msg.go index bcc6865b1..ad708ce8b 100644 --- a/pkg/rpcclient/notification/msg.go +++ b/pkg/rpcclient/notification/msg.go @@ -22,23 +22,28 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient" ) +// MsgNotificationSender type MsgNotificationSender struct { *rpcclient.NotificationSender } +// NewMsgNotificationSender func NewMsgNotificationSender(opts ...rpcclient.NotificationSenderOptions) *MsgNotificationSender { return &MsgNotificationSender{rpcclient.NewNotificationSender(opts...)} } +// UserDeleteMsgsNotification func (m *MsgNotificationSender) UserDeleteMsgsNotification(ctx context.Context, userID, conversationID string, seqs []int64) error { tips := sdkws.DeleteMsgsTips{ UserID: userID, ConversationID: conversationID, Seqs: seqs, } + return m.Notification(ctx, userID, userID, constant.DeleteMsgsNotification, &tips) } +// MarkAsReadNotification func (m *MsgNotificationSender) MarkAsReadNotification(ctx context.Context, conversationID string, sesstionType int32, sendID, recvID string, seqs []int64, hasReadSeq int64) error { tips := &sdkws.MarkAsReadTips{ MarkAsReadUserID: sendID, @@ -46,5 +51,6 @@ func (m *MsgNotificationSender) MarkAsReadNotification(ctx context.Context, conv Seqs: seqs, HasReadSeq: hasReadSeq, } + return m.NotificationWithSesstionType(ctx, sendID, recvID, constant.HasReadReceipt, sesstionType, tips) } diff --git a/pkg/rpcclient/push.go b/pkg/rpcclient/push.go index 8e19782bd..62752901e 100644 --- a/pkg/rpcclient/push.go +++ b/pkg/rpcclient/push.go @@ -24,17 +24,20 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/push" ) +// Push type Push struct { conn grpc.ClientConnInterface Client push.PushMsgServiceClient discov discoveryregistry.SvcDiscoveryRegistry } +// NewPush func NewPush(discov discoveryregistry.SvcDiscoveryRegistry) *Push { conn, err := discov.GetConn(context.Background(), config.Config.RpcRegisterName.OpenImPushName) if err != nil { panic(err) } + return &Push{ discov: discov, conn: conn, @@ -42,12 +45,15 @@ func NewPush(discov discoveryregistry.SvcDiscoveryRegistry) *Push { } } +// PushRpcClient type PushRpcClient Push +// NewPushRpcClient func NewPushRpcClient(discov discoveryregistry.SvcDiscoveryRegistry) PushRpcClient { return PushRpcClient(*NewPush(discov)) } +// DelUserPushToken func (p *PushRpcClient) DelUserPushToken( ctx context.Context, req *push.DelUserPushTokenReq, diff --git a/pkg/rpcclient/third.go b/pkg/rpcclient/third.go index e1181b8f4..629234e7f 100644 --- a/pkg/rpcclient/third.go +++ b/pkg/rpcclient/third.go @@ -28,6 +28,7 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/third" ) +// Third type Third struct { conn grpc.ClientConnInterface Client third.ThirdClient @@ -35,20 +36,22 @@ type Third struct { MinioClient *minio.Client } +// NewThird func NewThird(discov discoveryregistry.SvcDiscoveryRegistry) *Third { + var minioClient *minio.Client conn, err := discov.GetConn(context.Background(), config.Config.RpcRegisterName.OpenImThirdName) if err != nil { panic(err) } client := third.NewThirdClient(conn) - minioClient, err := minioInit() + minioClient, err = minioInit() + return &Third{discov: discov, Client: client, conn: conn, MinioClient: minioClient} } func minioInit() (*minio.Client, error) { - minioClient := &minio.Client{} - var initUrl string - initUrl = config.Config.Object.Minio.Endpoint + var minioClient *minio.Client + initUrl := config.Config.Object.Minio.Endpoint minioUrl, err := url.Parse(initUrl) if err != nil { return nil, err @@ -66,5 +69,6 @@ func minioInit() (*minio.Client, error) { if err != nil { return nil, err } + return minioClient, nil } diff --git a/pkg/rpcclient/user.go b/pkg/rpcclient/user.go index 023c26d3c..0e92a3e96 100644 --- a/pkg/rpcclient/user.go +++ b/pkg/rpcclient/user.go @@ -29,32 +29,39 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/utils" ) +// User type User struct { conn grpc.ClientConnInterface Client user.UserClient Discov discoveryregistry.SvcDiscoveryRegistry } +// NewUser func NewUser(discov discoveryregistry.SvcDiscoveryRegistry) *User { conn, err := discov.GetConn(context.Background(), config.Config.RpcRegisterName.OpenImUserName) if err != nil { panic(err) } client := user.NewUserClient(conn) + return &User{Discov: discov, Client: client, conn: conn} } type UserRpcClient User +// NewUserRpcClientByUser func NewUserRpcClientByUser(user *User) *UserRpcClient { rpc := UserRpcClient(*user) + return &rpc } +// NewUserRpcClient func NewUserRpcClient(client discoveryregistry.SvcDiscoveryRegistry) UserRpcClient { return UserRpcClient(*NewUser(client)) } +// GetUsersInfo func (u *UserRpcClient) GetUsersInfo(ctx context.Context, userIDs []string) ([]*sdkws.UserInfo, error) { resp, err := u.Client.GetDesignateUsers(ctx, &user.GetDesignateUsersReq{ UserIDs: userIDs, @@ -67,27 +74,33 @@ func (u *UserRpcClient) GetUsersInfo(ctx context.Context, userIDs []string) ([]* })); len(ids) > 0 { return nil, errs.ErrUserIDNotFound.Wrap(strings.Join(ids, ",")) } + return resp.UsersInfo, nil } +// GetUserInfo func (u *UserRpcClient) GetUserInfo(ctx context.Context, userID string) (*sdkws.UserInfo, error) { users, err := u.GetUsersInfo(ctx, []string{userID}) if err != nil { return nil, err } + return users[0], nil } +// GetUsersInfoMap func (u *UserRpcClient) GetUsersInfoMap(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error) { users, err := u.GetUsersInfo(ctx, userIDs) if err != nil { return nil, err } + return utils.SliceToMap(users, func(e *sdkws.UserInfo) string { return e.UserID }), nil } +// GetPublicUserInfos func (u *UserRpcClient) GetPublicUserInfos( ctx context.Context, userIDs []string, @@ -97,6 +110,7 @@ func (u *UserRpcClient) GetPublicUserInfos( if err != nil { return nil, err } + return utils.Slice(users, func(e *sdkws.UserInfo) *sdkws.PublicUserInfo { return &sdkws.PublicUserInfo{ UserID: e.UserID, @@ -107,14 +121,17 @@ func (u *UserRpcClient) GetPublicUserInfos( }), nil } +// GetPublicUserInfo func (u *UserRpcClient) 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 } +// GetPublicUserInfoMap func (u *UserRpcClient) GetPublicUserInfoMap( ctx context.Context, userIDs []string, @@ -124,11 +141,13 @@ func (u *UserRpcClient) GetPublicUserInfoMap( if err != nil { return nil, err } + return utils.SliceToMap(users, func(e *sdkws.PublicUserInfo) string { return e.UserID }), nil } +// GetUserGlobalMsgRecvOpt func (u *UserRpcClient) GetUserGlobalMsgRecvOpt(ctx context.Context, userID string) (int32, error) { resp, err := u.Client.GetGlobalRecvMessageOpt(ctx, &user.GetGlobalRecvMessageOptReq{ UserID: userID, @@ -136,21 +155,26 @@ func (u *UserRpcClient) GetUserGlobalMsgRecvOpt(ctx context.Context, userID stri if err != nil { return 0, err } + return resp.GlobalRecvMsgOpt, err } +// Access func (u *UserRpcClient) Access(ctx context.Context, ownerUserID string) error { _, err := u.GetUserInfo(ctx, ownerUserID) if err != nil { return err } + return tokenverify.CheckAccessV3(ctx, ownerUserID) } +// GetAllUserIDs func (u *UserRpcClient) GetAllUserIDs(ctx context.Context, pageNumber, showNumber int32) ([]string, error) { resp, err := u.Client.GetAllUserID(ctx, &user.GetAllUserIDReq{Pagination: &sdkws.RequestPagination{PageNumber: pageNumber, ShowNumber: showNumber}}) if err != nil { return nil, err } + return resp.UserIDs, nil } diff --git a/pkg/startrpc/start.go b/pkg/startrpc/start.go index 3eeaaa3a2..ef207cf56 100644 --- a/pkg/startrpc/start.go +++ b/pkg/startrpc/start.go @@ -34,6 +34,7 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/utils" ) +// Start func Start( rpcPort int, rpcRegisterName string, @@ -108,5 +109,6 @@ func Start( } } }() + return utils.Wrap1(srv.Serve(listener)) } diff --git a/pkg/statistics/statistics.go b/pkg/statistics/statistics.go index 2a6ae01ae..8c1828380 100644 --- a/pkg/statistics/statistics.go +++ b/pkg/statistics/statistics.go @@ -21,6 +21,7 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/common/log" ) +// Statistics num type Statistics struct { AllCount *uint64 ModuleName string @@ -34,10 +35,12 @@ func (s *Statistics) output() { defer t.Stop() var sum uint64 var timeIntervalNum uint64 + outputCh := make(chan struct{}) for { sum = *s.AllCount select { case <-t.C: + outputCh <- struct{}{} } if *s.AllCount-sum <= 0 { intervalCount = 0 @@ -63,8 +66,10 @@ func (s *Statistics) output() { } } +// NewStatistics func NewStatistics(allCount *uint64, moduleName, printArgs string, sleepTime int) *Statistics { p := &Statistics{AllCount: allCount, ModuleName: moduleName, SleepTime: uint64(sleepTime), PrintArgs: printArgs} go p.output() + return p } From 0549da7f0685b28d1288b060fd982ed5204b3ae8 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Fri, 14 Jul 2023 20:07:26 +0800 Subject: [PATCH 55/62] fix: implement of GetUsersOnlineStatus (#567) --- internal/msggateway/hub_server.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/internal/msggateway/hub_server.go b/internal/msggateway/hub_server.go index deb8c3d77..4922437cb 100644 --- a/internal/msggateway/hub_server.go +++ b/internal/msggateway/hub_server.go @@ -83,9 +83,6 @@ func (s *Server) GetUsersOnlineStatus( ctx context.Context, req *msggateway.GetUsersOnlineStatusReq, ) (*msggateway.GetUsersOnlineStatusResp, error) { - if !tokenverify.IsAppManagerUid(ctx) { - return nil, errs.ErrNoPermission.Wrap("only app manager") - } var resp msggateway.GetUsersOnlineStatusResp for _, userID := range req.UserIDs { clients, ok := s.LongConnServer.GetUserAllCons(userID) From bf1cb34e24be93b841c8518dcdc646f2a8ecf92c Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Mon, 17 Jul 2023 16:29:01 +0800 Subject: [PATCH 56/62] fix bug: obtain user online status err(#567) --- internal/msggateway/hub_server.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/msggateway/hub_server.go b/internal/msggateway/hub_server.go index 4922437cb..deb8c3d77 100644 --- a/internal/msggateway/hub_server.go +++ b/internal/msggateway/hub_server.go @@ -83,6 +83,9 @@ func (s *Server) GetUsersOnlineStatus( ctx context.Context, req *msggateway.GetUsersOnlineStatusReq, ) (*msggateway.GetUsersOnlineStatusResp, error) { + if !tokenverify.IsAppManagerUid(ctx) { + return nil, errs.ErrNoPermission.Wrap("only app manager") + } var resp msggateway.GetUsersOnlineStatusResp for _, userID := range req.UserIDs { clients, ok := s.LongConnServer.GetUserAllCons(userID) From 14ad82d43b7fe1f3388574c6a5f207871922717a Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Fri, 21 Jul 2023 09:49:14 +0800 Subject: [PATCH 57/62] fix bug: obtain user online status err(#567) --- internal/api/user.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/api/user.go b/internal/api/user.go index 67c042ea4..604238965 100644 --- a/internal/api/user.go +++ b/internal/api/user.go @@ -86,7 +86,6 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) { log.ZWarn(c, "GetUsersOnlineStatus rpc err", err) parseError := apiresp.ParseError(err) - log.ZDebug(c, "errcode bantanger", "errcode", parseError.ErrCode) if parseError.ErrCode == errs.NoPermissionError { apiresp.GinError(c, err) return From 764353d44f71cf92013af143fafc2c9e9e118deb Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Sun, 23 Jul 2023 11:44:33 +0800 Subject: [PATCH 58/62] fix: changing naming irregularities under pkg and internal packages (#520) --- pkg/common/mw/rpc_server_interceptor.go | 12 ++-- pkg/common/mw/specialerror/error.go | 11 +++- pkg/common/prome/gather.go | 39 ++++++++++++ pkg/common/prome/prometheus.go | 9 +++ pkg/common/tokenverify/jwt_token.go | 15 +++++ pkg/discoveryregistry/discovery_register.go | 2 + pkg/discoveryregistry/zookeeper/conf.go | 4 ++ pkg/discoveryregistry/zookeeper/discover.go | 10 ++++ pkg/discoveryregistry/zookeeper/register.go | 8 +++ pkg/discoveryregistry/zookeeper/resolver.go | 10 ++++ pkg/discoveryregistry/zookeeper/zk.go | 18 ++++++ pkg/errs/coderr.go | 11 +++- pkg/errs/relation.go | 2 + pkg/proto/auth/auth.go | 6 ++ pkg/proto/conversation/conversation.go | 48 ++++++++++++--- pkg/proto/friend/friend.go | 30 ++++++++++ pkg/proto/group/group.go | 66 +++++++++++++++++++++ pkg/proto/msg/msg.go | 44 +++++++++++--- pkg/proto/msggateway/msggateway.go | 10 ++++ pkg/proto/push/push.go | 4 ++ pkg/proto/sdkws/sdkws.go | 2 + pkg/proto/third/third.go | 24 ++++---- pkg/proto/user/user.go | 30 ++++++++++ pkg/rpcclient/auth.go | 3 + pkg/rpcclient/conversation.go | 23 +++++++ pkg/rpcclient/friend.go | 14 ++++- pkg/rpcclient/group.go | 28 +++++++++ pkg/rpcclient/msg.go | 7 +++ pkg/rpcclient/notification/group.go | 1 + pkg/statistics/statistics.go | 2 - 30 files changed, 455 insertions(+), 38 deletions(-) diff --git a/pkg/common/mw/rpc_server_interceptor.go b/pkg/common/mw/rpc_server_interceptor.go index ec43069da..0dba76103 100644 --- a/pkg/common/mw/rpc_server_interceptor.go +++ b/pkg/common/mw/rpc_server_interceptor.go @@ -38,6 +38,7 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/errinfo" ) +// rpcString func rpcString(v interface{}) string { if s, ok := v.(interface{ String() string }); ok { return s.String() @@ -45,6 +46,7 @@ func rpcString(v interface{}) string { return fmt.Sprintf("%+v", v) } +// RpcServerInterceptor func RpcServerInterceptor( ctx context.Context, req interface{}, @@ -52,7 +54,7 @@ func RpcServerInterceptor( handler grpc.UnaryHandler, ) (resp interface{}, err error) { log.ZDebug(ctx, "rpc server req", "req", rpcString(req)) - //defer func() { + // defer func() { // if r := recover(); r != nil { // log.ZError(ctx, "rpc panic", nil, "FullMethod", info.FullMethod, "type:", fmt.Sprintf("%T", r), "panic:", r) // fmt.Printf("panic: %+v\nstack info: %s\n", r, string(debug.Stack())) @@ -74,7 +76,7 @@ func RpcServerInterceptor( // } // err = sta.Err() // } - //}() + // }() funcName := info.FullMethod md, ok := metadata.FromIncomingContext(ctx) if !ok { @@ -133,8 +135,8 @@ func RpcServerInterceptor( var errInfo *errinfo.ErrorInfo if config.Config.Log.WithStack { if unwrap != err { - sti, ok := err.(interface{ StackTrace() errors.StackTrace }) - if ok { + var sti interface{ StackTrace() errors.StackTrace } + if errors.As(err, &sti) { log.ZWarn( ctx, "rpc server resp", @@ -173,9 +175,11 @@ func RpcServerInterceptor( return nil, errs.Wrap(err) } log.ZWarn(ctx, "rpc server resp", err, "funcName", funcName) + return nil, details.Err() } +// GrpcServer func GrpcServer() grpc.ServerOption { return grpc.ChainUnaryInterceptor(RpcServerInterceptor) } diff --git a/pkg/common/mw/specialerror/error.go b/pkg/common/mw/specialerror/error.go index b8b8d27ae..b843ad0d6 100644 --- a/pkg/common/mw/specialerror/error.go +++ b/pkg/common/mw/specialerror/error.go @@ -14,10 +14,14 @@ package specialerror -import "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" +import ( + "errors" + "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" +) var handlers []func(err error) errs.CodeError +// AddErrHandler func AddErrHandler(h func(err error) errs.CodeError) { if h == nil { panic("nil handler") @@ -27,13 +31,15 @@ func AddErrHandler(h func(err error) errs.CodeError) { func AddReplace(target error, codeErr errs.CodeError) { AddErrHandler(func(err error) errs.CodeError { - if err == target { + if errors.Is(err, target) { return codeErr } + return nil }) } +// ErrCode func ErrCode(err error) errs.CodeError { if codeErr, ok := err.(errs.CodeError); ok { return codeErr @@ -43,5 +49,6 @@ func ErrCode(err error) errs.CodeError { return codeErr } } + return nil } diff --git a/pkg/common/prome/gather.go b/pkg/common/prome/gather.go index eb4bc6c3b..58305396d 100644 --- a/pkg/common/prome/gather.go +++ b/pkg/common/prome/gather.go @@ -79,6 +79,7 @@ var ( ConversationCreateFailedCounter prometheus.Counter ) +// NewUserLoginCounter func NewUserLoginCounter() { if UserLoginCounter != nil { return @@ -89,6 +90,7 @@ func NewUserLoginCounter() { }) } +// NewUserRegisterCounter func NewUserRegisterCounter() { if UserRegisterCounter != nil { return @@ -99,6 +101,7 @@ func NewUserRegisterCounter() { }) } +// NewSeqGetSuccessCounter func NewSeqGetSuccessCounter() { if SeqGetSuccessCounter != nil { return @@ -109,6 +112,7 @@ func NewSeqGetSuccessCounter() { }) } +// NewSeqGetFailedCounter func NewSeqGetFailedCounter() { if SeqGetFailedCounter != nil { return @@ -119,6 +123,7 @@ func NewSeqGetFailedCounter() { }) } +// NewSeqSetSuccessCounter func NewSeqSetSuccessCounter() { if SeqSetSuccessCounter != nil { return @@ -129,6 +134,7 @@ func NewSeqSetSuccessCounter() { }) } +// NewSeqSetFailedCounter func NewSeqSetFailedCounter() { if SeqSetFailedCounter != nil { return @@ -139,6 +145,7 @@ func NewSeqSetFailedCounter() { }) } +// NewApiRequestCounter func NewApiRequestCounter() { if ApiRequestCounter != nil { return @@ -149,6 +156,7 @@ func NewApiRequestCounter() { }) } +// NewApiRequestSuccessCounter func NewApiRequestSuccessCounter() { if ApiRequestSuccessCounter != nil { return @@ -159,6 +167,7 @@ func NewApiRequestSuccessCounter() { }) } +// NewApiRequestFailedCounter func NewApiRequestFailedCounter() { if ApiRequestFailedCounter != nil { return @@ -169,6 +178,7 @@ func NewApiRequestFailedCounter() { }) } +// NewGrpcRequestCounter func NewGrpcRequestCounter() { if GrpcRequestCounter != nil { return @@ -179,6 +189,7 @@ func NewGrpcRequestCounter() { }) } +// NewGrpcRequestSuccessCounter func NewGrpcRequestSuccessCounter() { if GrpcRequestSuccessCounter != nil { return @@ -189,6 +200,7 @@ func NewGrpcRequestSuccessCounter() { }) } +// NewGrpcRequestFailedCounter func NewGrpcRequestFailedCounter() { if GrpcRequestFailedCounter != nil { return @@ -199,6 +211,7 @@ func NewGrpcRequestFailedCounter() { }) } +// NewSendMsgCount func NewSendMsgCount() { if SendMsgCounter != nil { return @@ -209,6 +222,7 @@ func NewSendMsgCount() { }) } +// NewMsgInsertRedisSuccessCounter func NewMsgInsertRedisSuccessCounter() { if MsgInsertRedisSuccessCounter != nil { return @@ -219,6 +233,7 @@ func NewMsgInsertRedisSuccessCounter() { }) } +// NewMsgInsertRedisFailedCounter func NewMsgInsertRedisFailedCounter() { if MsgInsertRedisFailedCounter != nil { return @@ -229,6 +244,7 @@ func NewMsgInsertRedisFailedCounter() { }) } +// NewMsgInsertMongoSuccessCounter func NewMsgInsertMongoSuccessCounter() { if MsgInsertMongoSuccessCounter != nil { return @@ -239,6 +255,7 @@ func NewMsgInsertMongoSuccessCounter() { }) } +// NewMsgInsertMongoFailedCounter func NewMsgInsertMongoFailedCounter() { if MsgInsertMongoFailedCounter != nil { return @@ -249,6 +266,7 @@ func NewMsgInsertMongoFailedCounter() { }) } +// NewMsgPullFromRedisSuccessCounter func NewMsgPullFromRedisSuccessCounter() { if MsgPullFromRedisSuccessCounter != nil { return @@ -259,6 +277,7 @@ func NewMsgPullFromRedisSuccessCounter() { }) } +// NewMsgPullFromRedisFailedCounter func NewMsgPullFromRedisFailedCounter() { if MsgPullFromRedisFailedCounter != nil { return @@ -269,6 +288,7 @@ func NewMsgPullFromRedisFailedCounter() { }) } +// NewMsgPullFromMongoSuccessCounter func NewMsgPullFromMongoSuccessCounter() { if MsgPullFromMongoSuccessCounter != nil { return @@ -279,6 +299,7 @@ func NewMsgPullFromMongoSuccessCounter() { }) } +// NewMsgPullFromMongoFailedCounter func NewMsgPullFromMongoFailedCounter() { if MsgPullFromMongoFailedCounter != nil { return @@ -289,6 +310,7 @@ func NewMsgPullFromMongoFailedCounter() { }) } +// NewMsgRecvTotalCounter func NewMsgRecvTotalCounter() { if MsgRecvTotalCounter != nil { return @@ -299,6 +321,7 @@ func NewMsgRecvTotalCounter() { }) } +// NewGetNewestSeqTotalCounter func NewGetNewestSeqTotalCounter() { if GetNewestSeqTotalCounter != nil { return @@ -309,6 +332,7 @@ func NewGetNewestSeqTotalCounter() { }) } +// NewPullMsgBySeqListTotalCounter func NewPullMsgBySeqListTotalCounter() { if PullMsgBySeqListTotalCounter != nil { return @@ -319,6 +343,7 @@ func NewPullMsgBySeqListTotalCounter() { }) } +// NewSingleChatMsgRecvSuccessCounter func NewSingleChatMsgRecvSuccessCounter() { if SingleChatMsgRecvSuccessCounter != nil { return @@ -329,6 +354,7 @@ func NewSingleChatMsgRecvSuccessCounter() { }) } +// NewGroupChatMsgRecvSuccessCounter func NewGroupChatMsgRecvSuccessCounter() { if GroupChatMsgRecvSuccessCounter != nil { return @@ -339,6 +365,7 @@ func NewGroupChatMsgRecvSuccessCounter() { }) } +// NewWorkSuperGroupChatMsgRecvSuccessCounter func NewWorkSuperGroupChatMsgRecvSuccessCounter() { if WorkSuperGroupChatMsgRecvSuccessCounter != nil { return @@ -349,6 +376,7 @@ func NewWorkSuperGroupChatMsgRecvSuccessCounter() { }) } +// NewOnlineUserGauges func NewOnlineUserGauges() { if OnlineUserGauge != nil { return @@ -359,6 +387,7 @@ func NewOnlineUserGauges() { }) } +// NewSingleChatMsgProcessSuccessCounter func NewSingleChatMsgProcessSuccessCounter() { if SingleChatMsgProcessSuccessCounter != nil { return @@ -369,6 +398,7 @@ func NewSingleChatMsgProcessSuccessCounter() { }) } +// NewSingleChatMsgProcessFailedCounter func NewSingleChatMsgProcessFailedCounter() { if SingleChatMsgProcessFailedCounter != nil { return @@ -379,6 +409,7 @@ func NewSingleChatMsgProcessFailedCounter() { }) } +// NewGroupChatMsgProcessSuccessCounter func NewGroupChatMsgProcessSuccessCounter() { if GroupChatMsgProcessSuccessCounter != nil { return @@ -389,6 +420,7 @@ func NewGroupChatMsgProcessSuccessCounter() { }) } +// NewGroupChatMsgProcessFailedCounter func NewGroupChatMsgProcessFailedCounter() { if GroupChatMsgProcessFailedCounter != nil { return @@ -399,6 +431,7 @@ func NewGroupChatMsgProcessFailedCounter() { }) } +// NewWorkSuperGroupChatMsgProcessSuccessCounter func NewWorkSuperGroupChatMsgProcessSuccessCounter() { if WorkSuperGroupChatMsgProcessSuccessCounter != nil { return @@ -409,6 +442,7 @@ func NewWorkSuperGroupChatMsgProcessSuccessCounter() { }) } +// NewWorkSuperGroupChatMsgProcessFailedCounter func NewWorkSuperGroupChatMsgProcessFailedCounter() { if WorkSuperGroupChatMsgProcessFailedCounter != nil { return @@ -419,6 +453,7 @@ func NewWorkSuperGroupChatMsgProcessFailedCounter() { }) } +// NewMsgOnlinePushSuccessCounter func NewMsgOnlinePushSuccessCounter() { if MsgOnlinePushSuccessCounter != nil { return @@ -429,6 +464,7 @@ func NewMsgOnlinePushSuccessCounter() { }) } +// NewMsgOfflinePushSuccessCounter func NewMsgOfflinePushSuccessCounter() { if MsgOfflinePushSuccessCounter != nil { return @@ -439,6 +475,7 @@ func NewMsgOfflinePushSuccessCounter() { }) } +// NewMsgOfflinePushFailedCounter func NewMsgOfflinePushFailedCounter() { if MsgOfflinePushFailedCounter != nil { return @@ -449,6 +486,7 @@ func NewMsgOfflinePushFailedCounter() { }) } +// NewConversationCreateSuccessCounter func NewConversationCreateSuccessCounter() { if ConversationCreateSuccessCounter != nil { return @@ -459,6 +497,7 @@ func NewConversationCreateSuccessCounter() { }) } +// NewConversationCreateFailedCounter func NewConversationCreateFailedCounter() { if ConversationCreateFailedCounter != nil { return diff --git a/pkg/common/prome/prometheus.go b/pkg/common/prome/prometheus.go index d66b1df70..dbaa3f10d 100644 --- a/pkg/common/prome/prometheus.go +++ b/pkg/common/prome/prometheus.go @@ -26,6 +26,7 @@ import ( "github.com/prometheus/client_golang/prometheus/promhttp" ) +// StartPrometheusSrv func StartPrometheusSrv(prometheusPort int) error { if config.Config.Prometheus.Enable { http.Handle("/metrics", promhttp.Handler()) @@ -35,6 +36,7 @@ func StartPrometheusSrv(prometheusPort int) error { return nil } +// PrometheusHandler func PrometheusHandler() gin.HandlerFunc { h := promhttp.Handler() return func(c *gin.Context) { @@ -42,16 +44,19 @@ func PrometheusHandler() gin.HandlerFunc { } } +// responseBodyWriter type responseBodyWriter struct { gin.ResponseWriter body *bytes.Buffer } +// Write func (r responseBodyWriter) Write(b []byte) (int, error) { r.body.Write(b) return r.ResponseWriter.Write(b) } +// PrometheusMiddleware func PrometheusMiddleware(c *gin.Context) { Inc(ApiRequestCounter) w := &responseBodyWriter{body: &bytes.Buffer{}, ResponseWriter: c.Writer} @@ -64,6 +69,7 @@ func PrometheusMiddleware(c *gin.Context) { } } +// Inc func Inc(counter prometheus.Counter) { if config.Config.Prometheus.Enable { if counter != nil { @@ -72,6 +78,7 @@ func Inc(counter prometheus.Counter) { } } +// Add func Add(counter prometheus.Counter, add int) { if config.Config.Prometheus.Enable { if counter != nil { @@ -80,6 +87,7 @@ func Add(counter prometheus.Counter, add int) { } } +// GaugeInc func GaugeInc(gauges prometheus.Gauge) { if config.Config.Prometheus.Enable { if gauges != nil { @@ -88,6 +96,7 @@ func GaugeInc(gauges prometheus.Gauge) { } } +// GaugeDec func GaugeDec(gauges prometheus.Gauge) { if config.Config.Prometheus.Enable { if gauges != nil { diff --git a/pkg/common/tokenverify/jwt_token.go b/pkg/common/tokenverify/jwt_token.go index 317347b1d..798f3699a 100644 --- a/pkg/common/tokenverify/jwt_token.go +++ b/pkg/common/tokenverify/jwt_token.go @@ -27,15 +27,18 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/utils" ) +// Claims type Claims struct { UserID string PlatformID int // login platform jwt.RegisteredClaims } +// BuildClaims func BuildClaims(uid string, platformID int, ttl int64) Claims { now := time.Now() before := now.Add(-time.Minute * 5) + return Claims{ UserID: uid, PlatformID: platformID, @@ -47,12 +50,14 @@ func BuildClaims(uid string, platformID int, ttl int64) Claims { } } +// secret func secret() jwt.Keyfunc { return func(token *jwt.Token) (interface{}, error) { return []byte(config.Config.Secret), nil } } +// GetClaimFromToken func GetClaimFromToken(tokensString string) (*Claims, error) { token, err := jwt.ParseWithClaims(tokensString, &Claims{}, secret()) if err != nil { @@ -73,10 +78,12 @@ func GetClaimFromToken(tokensString string) (*Claims, error) { if claims, ok := token.Claims.(*Claims); ok && token.Valid { return claims, nil } + return nil, utils.Wrap(errs.ErrTokenUnknown, "") } } +// CheckAccessV3 func CheckAccessV3(ctx context.Context, ownerUserID string) (err error) { opUserID := mcontext.GetOpUserID(ctx) if utils.IsContain(opUserID, config.Config.Manager.UserID) { @@ -85,28 +92,35 @@ func CheckAccessV3(ctx context.Context, ownerUserID string) (err error) { if opUserID == ownerUserID { return nil } + return errs.ErrNoPermission.Wrap(utils.GetSelfFuncName()) } +// IsAppManagerUid func IsAppManagerUid(ctx context.Context) bool { return utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.Manager.UserID) } +// CheckAdmin func CheckAdmin(ctx context.Context) error { if utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.Manager.UserID) { return nil } + return errs.ErrNoPermission.Wrap(fmt.Sprintf("user %s is not admin userID", mcontext.GetOpUserID(ctx))) } +// ParseRedisInterfaceToken func ParseRedisInterfaceToken(redisToken interface{}) (*Claims, error) { return GetClaimFromToken(string(redisToken.([]uint8))) } +// IsManagerUserID func IsManagerUserID(opUserID string) bool { return utils.IsContain(opUserID, config.Config.Manager.UserID) } +// WsVerifyToken func WsVerifyToken(token, userID string, platformID int) error { claim, err := GetClaimFromToken(token) if err != nil { @@ -118,5 +132,6 @@ func WsVerifyToken(token, userID string, platformID int) error { if claim.PlatformID != platformID { return errs.ErrTokenInvalid.Wrap(fmt.Sprintf("token platform %d != %d", claim.PlatformID, platformID)) } + return nil } diff --git a/pkg/discoveryregistry/discovery_register.go b/pkg/discoveryregistry/discovery_register.go index 4ebabe7a8..f81a91c7b 100644 --- a/pkg/discoveryregistry/discovery_register.go +++ b/pkg/discoveryregistry/discovery_register.go @@ -20,6 +20,7 @@ import ( "google.golang.org/grpc" ) +// Conn type Conn interface { GetConns(ctx context.Context, serviceName string, opts ...grpc.DialOption) ([]grpc.ClientConnInterface, error) GetConn(ctx context.Context, serviceName string, opts ...grpc.DialOption) (grpc.ClientConnInterface, error) @@ -29,6 +30,7 @@ type Conn interface { GetClientLocalConns() map[string][]grpc.ClientConnInterface } +// SvcDiscoveryRegistry type SvcDiscoveryRegistry interface { Conn Register(serviceName, host string, port int, opts ...grpc.DialOption) error diff --git a/pkg/discoveryregistry/zookeeper/conf.go b/pkg/discoveryregistry/zookeeper/conf.go index 034c525ba..8cfb504c1 100644 --- a/pkg/discoveryregistry/zookeeper/conf.go +++ b/pkg/discoveryregistry/zookeeper/conf.go @@ -18,6 +18,7 @@ import ( "github.com/go-zookeeper/zk" ) +// RegisterConf2Registry func (s *ZkClient) RegisterConf2Registry(key string, conf []byte) error { exists, _, err := s.conn.Exists(s.getPath(key)) if err != nil { @@ -32,10 +33,13 @@ func (s *ZkClient) RegisterConf2Registry(key string, conf []byte) error { if err != zk.ErrNodeExists { return err } + return nil } +// GetConfFromRegistry func (s *ZkClient) GetConfFromRegistry(key string) ([]byte, error) { bytes, _, err := s.conn.Get(s.getPath(key)) + return bytes, err } diff --git a/pkg/discoveryregistry/zookeeper/discover.go b/pkg/discoveryregistry/zookeeper/discover.go index 94cf1f84a..fc28dd388 100644 --- a/pkg/discoveryregistry/zookeeper/discover.go +++ b/pkg/discoveryregistry/zookeeper/discover.go @@ -35,6 +35,7 @@ var ( ErrConnIsNilButLocalNotNil = errors.New("conn is nil, but local is not nil") ) +// watch func (s *ZkClient) watch() { for { event := <-s.eventChan @@ -69,6 +70,7 @@ func (s *ZkClient) watch() { } } +// GetConnsRemote func (s *ZkClient) GetConnsRemote(serviceName string) (conns []resolver.Address, err error) { path := s.getPath(serviceName) _, _, _, err = s.conn.ChildrenW(path) @@ -86,15 +88,18 @@ func (s *ZkClient) GetConnsRemote(serviceName string) (conns []resolver.Address, if err == zk.ErrNoNode { return nil, errors.Wrap(err, "this is zk ErrNoNode") } + return nil, errors.Wrap(err, "get children error") } log.ZDebug(context.Background(), "get addrs from remote", "conn", string(data)) conns = append(conns, resolver.Address{Addr: string(data), ServerName: serviceName}) } } + return conns, nil } +// GetConns func (s *ZkClient) GetConns(ctx context.Context, serviceName string, opts ...grpc.DialOption) ([]grpc.ClientConnInterface, error) { s.logger.Printf("get conns from client, serviceName: %s", serviceName) s.lock.Lock() @@ -114,21 +119,26 @@ func (s *ZkClient) GetConns(ctx context.Context, serviceName string, opts ...grp cc, err := grpc.DialContext(ctx, addr.Addr, append(s.options, opts...)...) if err != nil { log.ZError(context.Background(), "dialContext failed", err, "addr", addr.Addr, "opts", append(s.options, opts...)) + return nil, errs.Wrap(err) } conns = append(conns, cc) } s.localConns[serviceName] = conns } + return conns, nil } +// GetConn func (s *ZkClient) GetConn(ctx context.Context, serviceName string, opts ...grpc.DialOption) (grpc.ClientConnInterface, error) { newOpts := append(s.options, grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, s.balancerName))) s.logger.Printf("get conn from client, serviceName: %s", serviceName) + return grpc.DialContext(ctx, fmt.Sprintf("%s:///%s", s.scheme, serviceName), append(newOpts, opts...)...) } +// CloseConn func (s *ZkClient) CloseConn(conn grpc.ClientConnInterface) { if closer, ok := conn.(io.Closer); ok { closer.Close() diff --git a/pkg/discoveryregistry/zookeeper/register.go b/pkg/discoveryregistry/zookeeper/register.go index 8fc5fa34e..dfdc567ee 100644 --- a/pkg/discoveryregistry/zookeeper/register.go +++ b/pkg/discoveryregistry/zookeeper/register.go @@ -21,16 +21,20 @@ import ( "google.golang.org/grpc" ) +// CreateRpcRootNodes func (s *ZkClient) CreateRpcRootNodes(serviceNames []string) error { for _, serviceName := range serviceNames { if err := s.ensureName(serviceName); err != nil && err != zk.ErrNodeExists { return err } } + return nil } +// CreateTempNode func (s *ZkClient) CreateTempNode(rpcRegisterName, addr string) (node string, err error) { + return s.conn.CreateProtectedEphemeralSequential( s.getPath(rpcRegisterName)+"/"+addr+"_", []byte(addr), @@ -38,6 +42,7 @@ func (s *ZkClient) CreateTempNode(rpcRegisterName, addr string) (node string, er ) } +// Register func (s *ZkClient) Register(rpcRegisterName, host string, port int, opts ...grpc.DialOption) error { if err := s.ensureName(rpcRegisterName); err != nil { return err @@ -55,9 +60,11 @@ func (s *ZkClient) Register(rpcRegisterName, host string, port int, opts ...grpc s.rpcRegisterAddr = addr s.node = node s.isRegistered = true + return nil } +// UnRegister func (s *ZkClient) UnRegister() error { s.lock.Lock() defer s.lock.Unlock() @@ -72,5 +79,6 @@ func (s *ZkClient) UnRegister() error { s.isRegistered = false s.localConns = make(map[string][]grpc.ClientConnInterface) s.resolvers = make(map[string]*Resolver) + return nil } diff --git a/pkg/discoveryregistry/zookeeper/resolver.go b/pkg/discoveryregistry/zookeeper/resolver.go index 7e9c8c125..792d904ba 100644 --- a/pkg/discoveryregistry/zookeeper/resolver.go +++ b/pkg/discoveryregistry/zookeeper/resolver.go @@ -23,6 +23,7 @@ import ( "google.golang.org/grpc/resolver" ) +// Resolver type Resolver struct { target resolver.Target cc resolver.ClientConn @@ -31,6 +32,7 @@ type Resolver struct { getConnsRemote func(serviceName string) (conns []resolver.Address, err error) } +// ResolveNowZK func (r *Resolver) ResolveNowZK(o resolver.ResolveNowOptions) { log.ZDebug( context.Background(), @@ -45,6 +47,7 @@ func (r *Resolver) ResolveNowZK(o resolver.ResolveNowOptions) { newConns, err := r.getConnsRemote(strings.TrimLeft(r.target.URL.Path, "/")) if err != nil { log.ZError(context.Background(), "resolve now error", err, "target", r.target) + return } r.addrs = newConns @@ -58,15 +61,19 @@ func (r *Resolver) ResolveNowZK(o resolver.ResolveNowOptions) { "zk path", r.target.URL.Path, ) + return } log.ZDebug(context.Background(), "resolve now finished", "target", r.target, "conns", r.addrs) } +// ResolveNow func (r *Resolver) ResolveNow(o resolver.ResolveNowOptions) {} +// Close func (s *Resolver) Close() {} +// Build func (s *ZkClient) Build( target resolver.Target, cc resolver.ClientConn, @@ -76,6 +83,7 @@ func (s *ZkClient) Build( serviceName := strings.TrimLeft(target.URL.Path, "/") if oldResolver, ok := s.resolvers[serviceName]; ok { s.logger.Printf("rpc resolver exist: %+v, cc: %+v, key: %s", target, cc.UpdateState, serviceName) + return oldResolver, nil } r := &Resolver{} @@ -87,7 +95,9 @@ func (s *ZkClient) Build( defer s.lock.Unlock() s.resolvers[serviceName] = r s.logger.Printf("build resolver finished: %+v, cc: %+v, key: %s", target, cc.UpdateState, serviceName) + return r, nil } +// Scheme func (s *ZkClient) Scheme() string { return s.scheme } diff --git a/pkg/discoveryregistry/zookeeper/zk.go b/pkg/discoveryregistry/zookeeper/zk.go index cc333c4b6..6237c0b02 100644 --- a/pkg/discoveryregistry/zookeeper/zk.go +++ b/pkg/discoveryregistry/zookeeper/zk.go @@ -30,10 +30,12 @@ const ( timeout = 5 ) +// Logger type Logger interface { Printf(string, ...interface{}) } +// ZkClient type ZkClient struct { zkServers []string zkRoot string @@ -62,14 +64,17 @@ type ZkClient struct { logger Logger } +// ZkOption type ZkOption func(*ZkClient) +// WithRoundRobin func WithRoundRobin() ZkOption { return func(client *ZkClient) { client.balancerName = "round_robin" } } +// WithUserNameAndPassword func WithUserNameAndPassword(userName, password string) ZkOption { return func(client *ZkClient) { client.userName = userName @@ -83,24 +88,28 @@ func WithOptions(opts ...grpc.DialOption) ZkOption { } } +// WithFreq func WithFreq(freq time.Duration) ZkOption { return func(client *ZkClient) { client.ticker = time.NewTicker(freq) } } +// WithTimeout func WithTimeout(timeout int) ZkOption { return func(client *ZkClient) { client.timeout = timeout } } +// WithLogger func WithLogger(logger Logger) ZkOption { return func(client *ZkClient) { client.logger = logger } } +// NewClient func NewClient(zkServers []string, zkRoot string, options ...ZkOption) (*ZkClient, error) { client := &ZkClient{ zkServers: zkServers, @@ -134,15 +143,18 @@ func NewClient(zkServers []string, zkRoot string, options ...ZkOption) (*ZkClien client.conn = conn if err := client.ensureRoot(); err != nil { client.CloseZK() + return nil, err } resolver.Register(client) go client.refresh() go client.watch() time.Sleep(time.Millisecond * 50) + return client, nil } +// CloseZK func (s *ZkClient) CloseZK() { s.conn.Close() } @@ -158,6 +170,7 @@ func (s *ZkClient) ensureAndCreate(node string) error { return err } } + return nil } @@ -189,14 +202,17 @@ func (s *ZkClient) flushResolver(serviceName string) { } } +// GetZkConn func (s *ZkClient) GetZkConn() *zk.Conn { return s.conn } +// GetRootPath func (s *ZkClient) GetRootPath() string { return s.zkRoot } +// GetNode func (s *ZkClient) GetNode() string { return s.node } @@ -217,10 +233,12 @@ func (s *ZkClient) getAddr(host string, port int) string { return net.JoinHostPort(host, strconv.Itoa(port)) } +// AddOption func (s *ZkClient) AddOption(opts ...grpc.DialOption) { s.options = append(s.options, opts...) } +// GetClientLocalConns func (s *ZkClient) GetClientLocalConns() map[string][]grpc.ClientConnInterface { return s.localConns } diff --git a/pkg/errs/coderr.go b/pkg/errs/coderr.go index af88a6353..5bd878922 100644 --- a/pkg/errs/coderr.go +++ b/pkg/errs/coderr.go @@ -15,12 +15,12 @@ package errs import ( - "fmt" "strings" "github.com/pkg/errors" ) +// CodeError type CodeError interface { Code() int Msg() string @@ -32,6 +32,7 @@ type CodeError interface { error } +// NewCodeError func NewCodeError(code int, msg string) CodeError { return &codeError{ code: code, @@ -64,6 +65,7 @@ func (e *codeError) WithDetail(detail string) CodeError { } else { d = e.detail + ", " + detail } + return &codeError{ code: e.code, msg: e.msg, @@ -93,13 +95,15 @@ func (e *codeError) Is(err error, loose ...bool) bool { return codeErr.Code() == e.code } } + return false } func (e *codeError) Error() string { - return fmt.Sprintf("%s", e.msg) + return e.msg } +// Unwrap func Unwrap(err error) error { for err != nil { unwrap, ok := err.(interface { @@ -110,9 +114,11 @@ func Unwrap(err error) error { } err = unwrap.Unwrap() } + return err } +// Wrap func Wrap(err error, msg ...string) error { if err == nil { return nil @@ -120,5 +126,6 @@ func Wrap(err error, msg ...string) error { if len(msg) == 0 { return errors.WithStack(err) } + return errors.Wrap(err, strings.Join(msg, ", ")) } diff --git a/pkg/errs/relation.go b/pkg/errs/relation.go index 0a7ad4997..d5e9c6345 100644 --- a/pkg/errs/relation.go +++ b/pkg/errs/relation.go @@ -14,6 +14,7 @@ package errs +// Relation var Relation = &relation{m: make(map[int]map[int]struct{})} func init() { @@ -52,5 +53,6 @@ func (r *relation) Is(parent, child int) bool { return false } _, ok = s[child] + return ok } diff --git a/pkg/proto/auth/auth.go b/pkg/proto/auth/auth.go index 9b8fdd988..db2019a67 100644 --- a/pkg/proto/auth/auth.go +++ b/pkg/proto/auth/auth.go @@ -19,6 +19,7 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" ) +// Check func (x *UserTokenReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") @@ -26,9 +27,11 @@ func (x *UserTokenReq) Check() error { if x.PlatformID > constant.AdminPlatformID || x.PlatformID < constant.IOSPlatformID { return errs.ErrArgs.Wrap("platform is invalidate") } + return nil } +// Check func (x *ForceLogoutReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") @@ -36,12 +39,15 @@ func (x *ForceLogoutReq) Check() error { if x.PlatformID > constant.AdminPlatformID || x.PlatformID < constant.IOSPlatformID { return errs.ErrArgs.Wrap("platformID is invalidate") } + return nil } +// Check func (x *ParseTokenReq) Check() error { if x.Token == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } diff --git a/pkg/proto/conversation/conversation.go b/pkg/proto/conversation/conversation.go index 7e8f62bbc..ad6c6a623 100644 --- a/pkg/proto/conversation/conversation.go +++ b/pkg/proto/conversation/conversation.go @@ -16,13 +16,16 @@ package conversation import "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" +// Check func (x *ConversationReq) Check() error { if x.ConversationID == "" { return errs.ErrArgs.Wrap("conversation is empty") } + return nil } +// Check func (x *Conversation) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("OwnerUserID is empty") @@ -36,19 +39,23 @@ func (x *Conversation) Check() error { if x.RecvMsgOpt < 0 || x.RecvMsgOpt > 2 { return errs.ErrArgs.Wrap("RecvMsgOpt is invalid") } + return nil } -//func (x *ModifyConversationFieldReq) Check() error { +// // Check +// func (x *ModifyConversationFieldReq) Check() error { // if x.UserIDList == nil { // return errs.ErrArgs.Wrap("userIDList is empty") // } // if x.Conversation == nil { // return errs.ErrArgs.Wrap("conversation is empty") // } -// return nil -//} +// +// return nil +// } +// Check func (x *SetConversationReq) Check() error { if x.Conversation == nil { return errs.ErrArgs.Wrap("Conversation is empty") @@ -56,10 +63,12 @@ func (x *SetConversationReq) Check() error { if x.Conversation.ConversationID == "" { return errs.ErrArgs.Wrap("conversationID is empty") } + return nil } -//func (x *SetRecvMsgOptReq) Check() error { +// // Check +// func (x *SetRecvMsgOptReq) Check() error { // if x.OwnerUserID == "" { // return errs.ErrArgs.Wrap("ownerUserID is empty") // } @@ -69,9 +78,11 @@ func (x *SetConversationReq) Check() error { // if x.RecvMsgOpt > 2 || x.RecvMsgOpt < 0 { // return errs.ErrArgs.Wrap("MsgReceiveOpt is invalid") // } -// return nil -//} +// +// return nil +// } +// Check func (x *GetConversationReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("ownerUserID is empty") @@ -79,9 +90,11 @@ func (x *GetConversationReq) Check() error { if x.ConversationID == "" { return errs.ErrArgs.Wrap("conversationID is empty") } + return nil } +// Check func (x *GetConversationsReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("ownerUserID is empty") @@ -89,41 +102,51 @@ func (x *GetConversationsReq) Check() error { if x.ConversationIDs == nil { return errs.ErrArgs.Wrap("conversationIDs is empty") } + return nil } +// Check func (x *GetAllConversationsReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("ownerUserID is empty") } + return nil } // -//func (x *BatchSetConversationsReq) Check() error { +// // Check +// func (x *BatchSetConversationsReq) Check() error { // if x.Conversations == nil { // return errs.ErrArgs.Wrap("conversations is empty") // } // if x.OwnerUserID == "" { // return errs.ErrArgs.Wrap("conversation is empty") // } -// return nil -//} +// +// return nil +// } +// Check func (x *GetRecvMsgNotNotifyUserIDsReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") } + return nil } +// Check func (x *CreateGroupChatConversationsReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") } + return nil } +// Check func (x *SetConversationMaxSeqReq) Check() error { if x.ConversationID == "" { return errs.ErrArgs.Wrap("conversationID is empty") @@ -134,9 +157,11 @@ func (x *SetConversationMaxSeqReq) Check() error { if x.MaxSeq <= 0 { return errs.ErrArgs.Wrap("maxSeq is invalid") } + return nil } +// Check func (x *SetConversationsReq) Check() error { if x.UserIDs == nil { return errs.ErrArgs.Wrap("userID is empty") @@ -144,19 +169,24 @@ func (x *SetConversationsReq) Check() error { if x.Conversation == nil { return errs.ErrArgs.Wrap("conversation is empty") } + return nil } +// Check func (x *GetUserConversationIDsHashReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("ownerUserID is empty") } + return nil } +// Check func (x *GetConversationsByConversationIDReq) Check() error { if x.ConversationIDs == nil { return errs.ErrArgs.Wrap("conversationIDs is empty") } + return nil } diff --git a/pkg/proto/friend/friend.go b/pkg/proto/friend/friend.go index 197fc753c..59d99ba38 100644 --- a/pkg/proto/friend/friend.go +++ b/pkg/proto/friend/friend.go @@ -16,6 +16,7 @@ package friend import "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" +// Check func (x *GetPaginationFriendsReq) Check() error { if x.Pagination == nil { return errs.ErrArgs.Wrap("pagination is empty") @@ -26,9 +27,11 @@ func (x *GetPaginationFriendsReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } +// Check func (x *ApplyToAddFriendReq) Check() error { if x.ToUserID == "" { return errs.ErrArgs.Wrap("toUserID is empty") @@ -36,9 +39,11 @@ func (x *ApplyToAddFriendReq) Check() error { if x.FromUserID == "" { return errs.ErrArgs.Wrap("fromUserID is empty") } + return nil } +// Check func (x *ImportFriendReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("ownerUserID is empty") @@ -46,9 +51,11 @@ func (x *ImportFriendReq) Check() error { if x.FriendUserIDs == nil { return errs.ErrArgs.Wrap("friendUserIDS is empty") } + return nil } +// Check func (x *GetPaginationFriendsApplyToReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") @@ -59,9 +66,11 @@ func (x *GetPaginationFriendsApplyToReq) Check() error { if x.Pagination.PageNumber < 1 { return errs.ErrArgs.Wrap("pageNumber is invalid") } + return nil } +// Check func (x *GetDesignatedFriendsReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("ownerUserID is empty") @@ -69,9 +78,11 @@ func (x *GetDesignatedFriendsReq) Check() error { if x.FriendUserIDs == nil { return errs.ErrArgs.Wrap("friendUserIDS is empty") } + return nil } +// Check func (x *AddBlackReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("ownerUserID is empty") @@ -79,9 +90,11 @@ func (x *AddBlackReq) Check() error { if x.BlackUserID == "" { return errs.ErrArgs.Wrap("BlackUserID is empty") } + return nil } +// Check func (x *RemoveBlackReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("ownerUserID is empty") @@ -89,9 +102,11 @@ func (x *RemoveBlackReq) Check() error { if x.BlackUserID == "" { return errs.ErrArgs.Wrap("BlackUserID is empty") } + return nil } +// Check func (x *GetPaginationBlacksReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") @@ -102,9 +117,11 @@ func (x *GetPaginationBlacksReq) Check() error { if x.Pagination.PageNumber < 1 { return errs.ErrArgs.Wrap("pageNumber is invalid") } + return nil } +// Check func (x *IsFriendReq) Check() error { if x.UserID1 == "" { return errs.ErrArgs.Wrap("userID1 is empty") @@ -112,9 +129,11 @@ func (x *IsFriendReq) Check() error { if x.UserID2 == "" { return errs.ErrArgs.Wrap("userID2 is empty") } + return nil } +// Check func (x *IsBlackReq) Check() error { if x.UserID1 == "" { return errs.ErrArgs.Wrap("userID1 is empty") @@ -122,9 +141,11 @@ func (x *IsBlackReq) Check() error { if x.UserID2 == "" { return errs.ErrArgs.Wrap("userID2 is empty") } + return nil } +// Check func (x *DeleteFriendReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("userID1 is empty") @@ -132,9 +153,11 @@ func (x *DeleteFriendReq) Check() error { if x.FriendUserID == "" { return errs.ErrArgs.Wrap("userID2 is empty") } + return nil } +// Check func (x *RespondFriendApplyReq) Check() error { if x.ToUserID == "" { return errs.ErrArgs.Wrap("toUserID is empty") @@ -142,9 +165,11 @@ func (x *RespondFriendApplyReq) Check() error { if x.FromUserID == "" { return errs.ErrArgs.Wrap("fromUserID is empty") } + return nil } +// Check func (x *SetFriendRemarkReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("ownerUserID is empty") @@ -152,9 +177,11 @@ func (x *SetFriendRemarkReq) Check() error { if x.FriendUserID == "" { return errs.ErrArgs.Wrap("fromUserID is empty") } + return nil } +// Check func (x *GetPaginationFriendsApplyFromReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") @@ -165,12 +192,15 @@ func (x *GetPaginationFriendsApplyFromReq) Check() error { if x.Pagination.PageNumber < 1 { return errs.ErrArgs.Wrap("pageNumber is invalid") } + return nil } +// Check func (x *GetFriendIDsReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } diff --git a/pkg/proto/group/group.go b/pkg/proto/group/group.go index 2cebc0df0..78641df72 100644 --- a/pkg/proto/group/group.go +++ b/pkg/proto/group/group.go @@ -16,6 +16,7 @@ package group import "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" +// Check func (x *CreateGroupReq) Check() error { if x.MemberUserIDs == nil { return errs.ErrArgs.Wrap("memberUserIDS is empty") @@ -29,16 +30,20 @@ func (x *CreateGroupReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("ownerUserID") } + return nil } +// Check func (x *GetGroupsInfoReq) Check() error { if x.GroupIDs == nil { return errs.ErrArgs.Wrap("GroupIDs") } + return nil } +// Check func (x *SetGroupInfoReq) Check() error { if x.GroupInfoForSet == nil { return errs.ErrArgs.Wrap("GroupInfoForSets is empty") @@ -46,9 +51,11 @@ func (x *SetGroupInfoReq) Check() error { if x.GroupInfoForSet.GroupID == "" { return errs.ErrArgs.Wrap("GroupID is empty") } + return nil } +// Check func (x *GetGroupApplicationListReq) Check() error { if x.Pagination == nil { return errs.ErrArgs.Wrap("pagination is empty") @@ -59,9 +66,11 @@ func (x *GetGroupApplicationListReq) Check() error { if x.FromUserID == "" { return errs.ErrArgs.Wrap("fromUserID is empty") } + return nil } +// Check func (x *GetUserReqApplicationListReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("UserID is empty") @@ -72,9 +81,11 @@ func (x *GetUserReqApplicationListReq) Check() error { if x.Pagination.PageNumber < 1 { return errs.ErrArgs.Wrap("pageNumber is invalid") } + return nil } +// Check func (x *TransferGroupOwnerReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") @@ -85,9 +96,11 @@ func (x *TransferGroupOwnerReq) Check() error { if x.NewOwnerUserID == "" { return errs.ErrArgs.Wrap("newOwnerUserID is empty") } + return nil } +// Check func (x *JoinGroupReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") @@ -100,9 +113,11 @@ func (x *JoinGroupReq) Check() error { return errs.ErrArgs.Wrap("inviterUserID is empty") } } + return nil } +// Check func (x *GroupApplicationResponseReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") @@ -113,16 +128,20 @@ func (x *GroupApplicationResponseReq) Check() error { if x.HandleResult > 1 || x.HandleResult < -1 { return errs.ErrArgs.Wrap("handleResult is invalid") } + return nil } +// Check func (x *QuitGroupReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") } + return nil } +// Check func (x *GetGroupMemberListReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") @@ -136,9 +155,11 @@ func (x *GetGroupMemberListReq) Check() error { if x.Filter < 0 || x.Filter > 5 { return errs.ErrArgs.Wrap("filter is invalid") } + return nil } +// Check func (x *GetGroupMembersInfoReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") @@ -146,9 +167,11 @@ func (x *GetGroupMembersInfoReq) Check() error { if x.UserIDs == nil { return errs.ErrArgs.Wrap("userIDs is empty") } + return nil } +// Check func (x *KickGroupMemberReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") @@ -156,9 +179,11 @@ func (x *KickGroupMemberReq) Check() error { if x.KickedUserIDs == nil { return errs.ErrArgs.Wrap("kickUserIDs is empty") } + return nil } +// Check func (x *GetJoinedGroupListReq) Check() error { if x.Pagination == nil { return errs.ErrArgs.Wrap("pagination is empty") @@ -169,9 +194,11 @@ func (x *GetJoinedGroupListReq) Check() error { if x.FromUserID == "" { return errs.ErrArgs.Wrap("fromUserID is empty") } + return nil } +// Check func (x *InviteUserToGroupReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") @@ -179,9 +206,11 @@ func (x *InviteUserToGroupReq) Check() error { if x.InvitedUserIDs == nil { return errs.ErrArgs.Wrap("invitedUserIDs is empty") } + return nil } +// Check func (x *GetGroupAllMemberReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") @@ -192,9 +221,11 @@ func (x *GetGroupAllMemberReq) Check() error { if x.Pagination.PageNumber < 1 { return errs.ErrArgs.Wrap("pageNumber is invalid") } + return nil } +// Check func (x *GetGroupsReq) Check() error { if x.Pagination == nil { return errs.ErrArgs.Wrap("pagination is empty") @@ -202,16 +233,20 @@ func (x *GetGroupsReq) Check() error { if x.Pagination.PageNumber < 1 { return errs.ErrArgs.Wrap("pageNumber is invalid") } + return nil } +// Check func (x *GetGroupMemberReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") } + return nil } +// Check func (x *GetGroupMembersCMSReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") @@ -222,16 +257,20 @@ func (x *GetGroupMembersCMSReq) Check() error { if x.Pagination.PageNumber < 1 { return errs.ErrArgs.Wrap("pageNumber is invalid") } + return nil } +// Check func (x *DismissGroupReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") } + return nil } +// Check func (x *MuteGroupMemberReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") @@ -242,9 +281,11 @@ func (x *MuteGroupMemberReq) Check() error { if x.MutedSeconds <= 0 { return errs.ErrArgs.Wrap("mutedSeconds is empty") } + return nil } +// Check func (x *CancelMuteGroupMemberReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") @@ -252,37 +293,47 @@ func (x *CancelMuteGroupMemberReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } +// Check func (x *MuteGroupReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") } + return nil } +// Check func (x *CancelMuteGroupReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("groupID is empty") } + return nil } +// Check func (x *GetJoinedSuperGroupListReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } +// Check func (x *GetSuperGroupsInfoReq) Check() error { if x.GroupIDs == nil { return errs.ErrArgs.Wrap("GroupIDs is empty") } + return nil } +// Check func (x *SetGroupMemberInfo) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("GroupID is empty") @@ -290,23 +341,29 @@ func (x *SetGroupMemberInfo) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } +// Check func (x *SetGroupMemberInfoReq) Check() error { if x.Members == nil { return errs.ErrArgs.Wrap("Members is empty") } + return nil } +// Check func (x *GetGroupAbstractInfoReq) Check() error { if x.GroupIDs == nil { return errs.ErrArgs.Wrap("GroupID is empty") } + return nil } +// Check func (x *GetUserInGroupMembersReq) Check() error { if x.GroupIDs == nil { return errs.ErrArgs.Wrap("GroupID is empty") @@ -314,16 +371,20 @@ func (x *GetUserInGroupMembersReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } +// Check func (x *GetGroupMemberUserIDsReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("GroupID is empty") } + return nil } +// Check func (x *GetGroupMemberRoleLevelReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("GroupID is empty") @@ -331,16 +392,20 @@ func (x *GetGroupMemberRoleLevelReq) Check() error { if x.RoleLevels == nil { return errs.ErrArgs.Wrap("rolesLevel is empty") } + return nil } +// Check func (x *GetGroupInfoCacheReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("GroupID is empty") } + return nil } +// Check func (x *GetGroupMemberCacheReq) Check() error { if x.GroupID == "" { return errs.ErrArgs.Wrap("GroupID is empty") @@ -348,5 +413,6 @@ func (x *GetGroupMemberCacheReq) Check() error { if x.GroupMemberID == "" { return errs.ErrArgs.Wrap("GroupMemberID is empty") } + return nil } diff --git a/pkg/proto/msg/msg.go b/pkg/proto/msg/msg.go index 03c9da915..48904e82b 100644 --- a/pkg/proto/msg/msg.go +++ b/pkg/proto/msg/msg.go @@ -16,13 +16,16 @@ package msg import "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" +// Check func (x *GetMaxAndMinSeqReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } +// Check func (x *SendMsgReq) Check() error { if x.MsgData == nil { return errs.ErrArgs.Wrap("MsgData is empty") @@ -30,21 +33,25 @@ func (x *SendMsgReq) Check() error { if err := x.MsgData.Check(); err != nil { return err } + return nil } +// Check func (x *SetSendMsgStatusReq) Check() error { if x.Status < 0 || x.Status > 3 { return errs.ErrArgs.Wrap("status is invalid") } + return nil } +// Check func (x *GetSendMsgStatusReq) Check() error { return nil } -//func (x *ModifyMessageReactionExtensionsReq) Check() error { +// func (x *ModifyMessageReactionExtensionsReq) Check() error { // if x.ConversationID == "" { // return errs.ErrArgs.Wrap("conversationID is empty") // } @@ -55,9 +62,9 @@ func (x *GetSendMsgStatusReq) Check() error { // return errs.ErrArgs.Wrap("reactionExtensions is empty") // } // return nil -//} +// } // -//func (x *SetMessageReactionExtensionsReq) Check() error { +// func (x *SetMessageReactionExtensionsReq) Check() error { // if x.ConversationID == "" { // return errs.ErrArgs.Wrap("conversationID is empty") // } @@ -68,9 +75,9 @@ func (x *GetSendMsgStatusReq) Check() error { // return errs.ErrArgs.Wrap("reactionExtensions is empty") // } // return nil -//} +// } // -//func (x *GetMessagesReactionExtensionsReq) Check() error { +// func (x *GetMessagesReactionExtensionsReq) Check() error { // if x.ConversationID == "" { // return errs.ErrArgs.Wrap("conversationID is empty") // } @@ -84,9 +91,9 @@ func (x *GetSendMsgStatusReq) Check() error { // return errs.ErrArgs.Wrap("TypeKeys is empty") // } // return nil -//} +// } // -//func (x *DeleteMessagesReactionExtensionsReq) Check() error { +// func (x *DeleteMessagesReactionExtensionsReq) Check() error { // if x.ConversationID == "" { // return errs.ErrArgs.Wrap("conversationID is empty") // } @@ -97,12 +104,14 @@ func (x *GetSendMsgStatusReq) Check() error { // return errs.ErrArgs.Wrap("ReactionExtensions is empty") // } // return nil -//} +// } +// Check func (x *DelMsgsReq) Check() error { return nil } +// Check func (x *RevokeMsgReq) Check() error { if x.ConversationID == "" { return errs.ErrArgs.Wrap("conversationID is empty") @@ -113,9 +122,11 @@ func (x *RevokeMsgReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } +// Check func (x *MarkMsgsAsReadReq) Check() error { if x.ConversationID == "" { return errs.ErrArgs.Wrap("conversationID is empty") @@ -131,9 +142,11 @@ func (x *MarkMsgsAsReadReq) Check() error { return errs.ErrArgs.Wrap("seqs has 0 value is invalid") } } + return nil } +// Check func (x *MarkConversationAsReadReq) Check() error { if x.ConversationID == "" { return errs.ErrArgs.Wrap("conversationID is empty") @@ -149,9 +162,11 @@ func (x *MarkConversationAsReadReq) Check() error { return errs.ErrArgs.Wrap("seqs has 0 value is invalid") } } + return nil } +// Check func (x *SetConversationHasReadSeqReq) Check() error { if x.ConversationID == "" { return errs.ErrArgs.Wrap("conversationID is empty") @@ -162,9 +177,11 @@ func (x *SetConversationHasReadSeqReq) Check() error { if x.HasReadSeq < 1 { return errs.ErrArgs.Wrap("hasReadSeq is invalid") } + return nil } +// Check func (x *ClearConversationsMsgReq) Check() error { if x.ConversationIDs == nil { return errs.ErrArgs.Wrap("conversationIDs is empty") @@ -172,16 +189,20 @@ func (x *ClearConversationsMsgReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } +// Check func (x *UserClearAllMsgReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } +// Check func (x *DeleteMsgsReq) Check() error { if x.ConversationID == "" { return errs.ErrArgs.Wrap("conversationID is empty") @@ -192,26 +213,33 @@ func (x *DeleteMsgsReq) Check() error { if x.Seqs == nil { return errs.ErrArgs.Wrap("seqs is empty") } + return nil } +// Check func (x *DeleteMsgPhysicalReq) Check() error { if x.ConversationIDs == nil { return errs.ErrArgs.Wrap("conversationIDs is empty") } + return nil } +// Check func (x *GetConversationMaxSeqReq) Check() error { if x.ConversationID == "" { return errs.ErrArgs.Wrap("conversationID is empty") } + return nil } +// Check func (x *GetConversationsHasReadAndMaxSeqReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("userID is empty") } + return nil } diff --git a/pkg/proto/msggateway/msggateway.go b/pkg/proto/msggateway/msggateway.go index 5e0c85b45..45f20c7cb 100644 --- a/pkg/proto/msggateway/msggateway.go +++ b/pkg/proto/msggateway/msggateway.go @@ -16,6 +16,7 @@ package msggateway import "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" +// Check func (x *OnlinePushMsgReq) Check() error { if x.MsgData == nil { return errs.ErrArgs.Wrap("MsgData is empty") @@ -26,9 +27,11 @@ func (x *OnlinePushMsgReq) Check() error { if x.PushToUserID == "" { return errs.ErrArgs.Wrap("PushToUserID is empty") } + return nil } +// Check func (x *OnlineBatchPushOneMsgReq) Check() error { if x.MsgData == nil { return errs.ErrArgs.Wrap("MsgData is empty") @@ -39,16 +42,20 @@ func (x *OnlineBatchPushOneMsgReq) Check() error { if x.PushToUserIDs == nil { return errs.ErrArgs.Wrap("PushToUserIDs is empty") } + return nil } +// Check func (x *GetUsersOnlineStatusReq) Check() error { if x.UserIDs == nil { return errs.ErrArgs.Wrap("UserIDs is empty") } + return nil } +// Check func (x *KickUserOfflineReq) Check() error { if x.PlatformID < 1 || x.PlatformID > 9 { return errs.ErrArgs.Wrap("PlatformID is invalid") @@ -56,9 +63,11 @@ func (x *KickUserOfflineReq) Check() error { if x.KickUserIDList == nil { return errs.ErrArgs.Wrap("KickUserIDList is empty") } + return nil } +// Check func (x *MultiTerminalLoginCheckReq) Check() error { if x.PlatformID < 1 || x.PlatformID > 9 { return errs.ErrArgs.Wrap("PlatformID is invalid") @@ -69,5 +78,6 @@ func (x *MultiTerminalLoginCheckReq) Check() error { if x.Token == "" { return errs.ErrArgs.Wrap("Token is empty") } + return nil } diff --git a/pkg/proto/push/push.go b/pkg/proto/push/push.go index 2f117acda..83c6e9a9f 100644 --- a/pkg/proto/push/push.go +++ b/pkg/proto/push/push.go @@ -16,6 +16,7 @@ package push import "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" +// Check func (x *PushMsgReq) Check() error { if x.MsgData == nil { return errs.ErrArgs.Wrap("MsgData is empty") @@ -26,9 +27,11 @@ func (x *PushMsgReq) Check() error { if x.ConversationID == "" { return errs.ErrArgs.Wrap("ConversationID is empty") } + return nil } +// Check func (x *DelUserPushTokenReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("UserID is empty") @@ -36,5 +39,6 @@ func (x *DelUserPushTokenReq) Check() error { if x.PlatformID < 1 || x.PlatformID > 9 { return errs.ErrArgs.Wrap("PlatformID is invalid") } + return nil } diff --git a/pkg/proto/sdkws/sdkws.go b/pkg/proto/sdkws/sdkws.go index d0b0ae8aa..ff4630629 100644 --- a/pkg/proto/sdkws/sdkws.go +++ b/pkg/proto/sdkws/sdkws.go @@ -19,6 +19,7 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" ) +// Check func (x *MsgData) Check() error { if x.SendID == "" { return errs.ErrArgs.Wrap("sendID is empty") @@ -42,5 +43,6 @@ func (x *MsgData) Check() error { return errs.ErrArgs.Wrap("GroupID is empty") } } + return nil } diff --git a/pkg/proto/third/third.go b/pkg/proto/third/third.go index 0e2072727..454191342 100644 --- a/pkg/proto/third/third.go +++ b/pkg/proto/third/third.go @@ -16,7 +16,7 @@ package third import "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" -//func (x *ApplyPutReq) Check() error { +// func (x *ApplyPutReq) Check() error { // if x.PutID == "" { // return errs.ErrArgs.Wrap("PutID is empty") // } @@ -24,36 +24,37 @@ import "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" // return errs.ErrArgs.Wrap("ContentType is empty") // } // return nil -//} +// } // -//func (x *ConfirmPutReq) Check() error { +// func (x *ConfirmPutReq) Check() error { // if x.PutID == "" { // return errs.ErrArgs.Wrap("PutID is empty") // } // return nil -//} +// } // -//func (x *GetUrlReq) Check() error { +// func (x *GetUrlReq) Check() error { // if x.Name == "" { // return errs.ErrArgs.Wrap("Name is empty") // } // return nil -//} +// } // -//func (x *GetPutReq) Check() error { +// func (x *GetPutReq) Check() error { // if x.PutID == "" { // return errs.ErrArgs.Wrap("PutID is empty") // } // return nil -//} +// } // -//func (x *GetHashInfoReq) Check() error { +// func (x *GetHashInfoReq) Check() error { // if x.Hash == "" { // return errs.ErrArgs.Wrap("Hash is empty") // } // return nil -//} +// } +// Check func (x *FcmUpdateTokenReq) Check() error { if x.PlatformID < 1 || x.PlatformID > 9 { return errs.ErrArgs.Wrap("PlatformID is invalid") @@ -64,12 +65,15 @@ func (x *FcmUpdateTokenReq) Check() error { if x.Account == "" { return errs.ErrArgs.Wrap("Account is empty") } + return nil } +// Check func (x *SetAppBadgeReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("UserID is empty") } + return nil } diff --git a/pkg/proto/user/user.go b/pkg/proto/user/user.go index 06f07cb6e..f92ea9b9d 100644 --- a/pkg/proto/user/user.go +++ b/pkg/proto/user/user.go @@ -16,6 +16,7 @@ package user import "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" +// Check func (x *GetAllUserIDReq) Check() error { if x.Pagination == nil { return errs.ErrArgs.Wrap("pagination is empty") @@ -23,23 +24,29 @@ func (x *GetAllUserIDReq) Check() error { if x.Pagination.PageNumber < 1 { return errs.ErrArgs.Wrap("pageNumber is invalid") } + return nil } +// Check func (x *AccountCheckReq) Check() error { if x.CheckUserIDs == nil { return errs.ErrArgs.Wrap("CheckUserIDs is empty") } + return nil } +// Check func (x *GetDesignateUsersReq) Check() error { if x.UserIDs == nil { return errs.ErrArgs.Wrap("UserIDs is empty") } + return nil } +// Check func (x *UpdateUserInfoReq) Check() error { if x.UserInfo == nil { return errs.ErrArgs.Wrap("UserInfo is empty") @@ -47,9 +54,11 @@ func (x *UpdateUserInfoReq) Check() error { if x.UserInfo.UserID == "" { return errs.ErrArgs.Wrap("UserID is empty") } + return nil } +// Check func (x *SetGlobalRecvMessageOptReq) Check() error { if x.GlobalRecvMsgOpt > 2 || x.GlobalRecvMsgOpt < 0 { return errs.ErrArgs.Wrap("GlobalRecvMsgOpt is invalid") @@ -57,9 +66,11 @@ func (x *SetGlobalRecvMessageOptReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("UserID is empty") } + return nil } +// Check func (x *SetConversationReq) Check() error { if err := x.Conversation.Check(); err != nil { return err @@ -67,9 +78,11 @@ func (x *SetConversationReq) Check() error { if x.NotificationType < 1 || x.NotificationType > 3 { return errs.ErrArgs.Wrap("NotificationType is invalid") } + return nil } +// Check func (x *SetRecvMsgOptReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("OwnerUserID is empty") @@ -83,9 +96,11 @@ func (x *SetRecvMsgOptReq) Check() error { if x.NotificationType < 1 || x.NotificationType > 3 { return errs.ErrArgs.Wrap("NotificationType is invalid") } + return nil } +// Check func (x *GetConversationReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("OwnerUserID is empty") @@ -93,9 +108,11 @@ func (x *GetConversationReq) Check() error { if x.ConversationID == "" { return errs.ErrArgs.Wrap("ConversationID is empty") } + return nil } +// Check func (x *GetConversationsReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("OwnerUserID is empty") @@ -103,16 +120,20 @@ func (x *GetConversationsReq) Check() error { if x.ConversationIDs == nil { return errs.ErrArgs.Wrap("ConversationIDs is empty") } + return nil } +// Check func (x *GetAllConversationsReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("OwnerUserID is empty") } + return nil } +// Check func (x *BatchSetConversationsReq) Check() error { if x.OwnerUserID == "" { return errs.ErrArgs.Wrap("OwnerUserID is empty") @@ -123,9 +144,11 @@ func (x *BatchSetConversationsReq) Check() error { if x.NotificationType < 1 || x.NotificationType > 3 { return errs.ErrArgs.Wrap("NotificationType is invalid") } + return nil } +// Check func (x *GetPaginationUsersReq) Check() error { if x.Pagination == nil { return errs.ErrArgs.Wrap("pagination is empty") @@ -133,23 +156,29 @@ func (x *GetPaginationUsersReq) Check() error { if x.Pagination.PageNumber < 1 { return errs.ErrArgs.Wrap("pageNumber is invalid") } + return nil } +// Check func (x *UserRegisterReq) Check() error { if x.Users == nil { return errs.ErrArgs.Wrap("Users is empty") } + return nil } +// Check func (x *GetGlobalRecvMessageOptReq) Check() error { if x.UserID == "" { return errs.ErrArgs.Wrap("UserID is empty") } + return nil } +// Check func (x *UserRegisterCountReq) Check() error { if x.Start <= 0 { return errs.ErrArgs.Wrap("start is invalid") @@ -157,5 +186,6 @@ func (x *UserRegisterCountReq) Check() error { if x.End <= 0 { return errs.ErrArgs.Wrap("end is invalid") } + return nil } diff --git a/pkg/rpcclient/auth.go b/pkg/rpcclient/auth.go index aa13ed898..abde73548 100644 --- a/pkg/rpcclient/auth.go +++ b/pkg/rpcclient/auth.go @@ -24,15 +24,18 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/auth" ) +// NewAuth func NewAuth(discov discoveryregistry.SvcDiscoveryRegistry) *Auth { conn, err := discov.GetConn(context.Background(), config.Config.RpcRegisterName.OpenImAuthName) if err != nil { panic(err) } client := auth.NewAuthClient(conn) + return &Auth{discov: discov, conn: conn, Client: client} } +// Auth type Auth struct { conn grpc.ClientConnInterface Client auth.AuthClient diff --git a/pkg/rpcclient/conversation.go b/pkg/rpcclient/conversation.go index 71867620d..30fb1c8c7 100644 --- a/pkg/rpcclient/conversation.go +++ b/pkg/rpcclient/conversation.go @@ -26,27 +26,33 @@ import ( pbConversation "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/conversation" ) +// Conversation type Conversation struct { Client pbConversation.ConversationClient conn grpc.ClientConnInterface discov discoveryregistry.SvcDiscoveryRegistry } +// NewConversation func NewConversation(discov discoveryregistry.SvcDiscoveryRegistry) *Conversation { conn, err := discov.GetConn(context.Background(), config.Config.RpcRegisterName.OpenImConversationName) if err != nil { panic(err) } client := pbConversation.NewConversationClient(conn) + return &Conversation{discov: discov, conn: conn, Client: client} } +// ConversationRpcClient type ConversationRpcClient Conversation +// NewConversationRpcClient func NewConversationRpcClient(discov discoveryregistry.SvcDiscoveryRegistry) ConversationRpcClient { return ConversationRpcClient(*NewConversation(discov)) } +// GetSingleConversationRecvMsgOpt func (c *ConversationRpcClient) GetSingleConversationRecvMsgOpt(ctx context.Context, userID, conversationID string) (int32, error) { var req pbConversation.GetConversationReq req.OwnerUserID = userID @@ -55,45 +61,59 @@ func (c *ConversationRpcClient) GetSingleConversationRecvMsgOpt(ctx context.Cont if err != nil { return 0, err } + return conversation.GetConversation().RecvMsgOpt, err } +// SingleChatFirstCreateConversation func (c *ConversationRpcClient) SingleChatFirstCreateConversation(ctx context.Context, recvID, sendID string) error { _, err := c.Client.CreateSingleChatConversations(ctx, &pbConversation.CreateSingleChatConversationsReq{RecvID: recvID, SendID: sendID}) + return err } +// GroupChatFirstCreateConversation func (c *ConversationRpcClient) GroupChatFirstCreateConversation(ctx context.Context, groupID string, userIDs []string) error { _, err := c.Client.CreateGroupChatConversations(ctx, &pbConversation.CreateGroupChatConversationsReq{UserIDs: userIDs, GroupID: groupID}) + return err } +// SetConversationMaxSeq func (c *ConversationRpcClient) SetConversationMaxSeq(ctx context.Context, ownerUserIDs []string, conversationID string, maxSeq int64) error { _, err := c.Client.SetConversationMaxSeq(ctx, &pbConversation.SetConversationMaxSeqReq{OwnerUserID: ownerUserIDs, ConversationID: conversationID, MaxSeq: maxSeq}) + return err } +// SetConversations func (c *ConversationRpcClient) SetConversations(ctx context.Context, userIDs []string, conversation *pbConversation.ConversationReq) error { _, err := c.Client.SetConversations(ctx, &pbConversation.SetConversationsReq{UserIDs: userIDs, Conversation: conversation}) + return err } +// GetConversationIDs func (c *ConversationRpcClient) GetConversationIDs(ctx context.Context, ownerUserID string) ([]string, error) { resp, err := c.Client.GetConversationIDs(ctx, &pbConversation.GetConversationIDsReq{UserID: ownerUserID}) if err != nil { return nil, err } + return resp.ConversationIDs, nil } +// GetConversation func (c *ConversationRpcClient) GetConversation(ctx context.Context, ownerUserID, conversationID string) (*pbConversation.Conversation, error) { resp, err := c.Client.GetConversation(ctx, &pbConversation.GetConversationReq{OwnerUserID: ownerUserID, ConversationID: conversationID}) if err != nil { return nil, err } + return resp.Conversation, nil } +// GetConversationsByConversationID func (c *ConversationRpcClient) GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*pbConversation.Conversation, error) { if len(conversationIDs) == 0 { return nil, nil @@ -105,9 +125,11 @@ func (c *ConversationRpcClient) GetConversationsByConversationID(ctx context.Con if len(resp.Conversations) == 0 { return nil, errs.ErrRecordNotFound.Wrap(fmt.Sprintf("conversationIDs: %v not found", conversationIDs)) } + return resp.Conversations, nil } +// GetConversations func (c *ConversationRpcClient) GetConversations( ctx context.Context, ownerUserID string, @@ -123,5 +145,6 @@ func (c *ConversationRpcClient) GetConversations( if err != nil { return nil, err } + return resp.Conversations, nil } diff --git a/pkg/rpcclient/friend.go b/pkg/rpcclient/friend.go index 5a8ac0633..edb75cc21 100644 --- a/pkg/rpcclient/friend.go +++ b/pkg/rpcclient/friend.go @@ -25,27 +25,33 @@ import ( sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" ) +// Friend type Friend struct { conn grpc.ClientConnInterface Client friend.FriendClient discov discoveryregistry.SvcDiscoveryRegistry } +// NewFriend func NewFriend(discov discoveryregistry.SvcDiscoveryRegistry) *Friend { conn, err := discov.GetConn(context.Background(), config.Config.RpcRegisterName.OpenImFriendName) if err != nil { panic(err) } client := friend.NewFriendClient(conn) + return &Friend{discov: discov, conn: conn, Client: client} } +// FriendRpcClient type FriendRpcClient Friend +// NewFriendRpcClient func NewFriendRpcClient(discov discoveryregistry.SvcDiscoveryRegistry) FriendRpcClient { return FriendRpcClient(*NewFriend(discov)) } +// GetFriendsInfo func (f *FriendRpcClient) GetFriendsInfo( ctx context.Context, ownerUserID, friendUserID string, @@ -58,31 +64,37 @@ func (f *FriendRpcClient) GetFriendsInfo( return nil, err } resp = r.FriendsInfo[0] + return } -// possibleFriendUserID是否在userID的好友中. +// IsFriend possibleFriendUserID是否在userID的好友中. func (f *FriendRpcClient) IsFriend(ctx context.Context, possibleFriendUserID, userID string) (bool, error) { resp, err := f.Client.IsFriend(ctx, &friend.IsFriendReq{UserID1: userID, UserID2: possibleFriendUserID}) if err != nil { return false, err } + return resp.InUser1Friends, nil } +// GetFriendIDs func (f *FriendRpcClient) GetFriendIDs(ctx context.Context, ownerUserID string) (friendIDs []string, err error) { req := friend.GetFriendIDsReq{UserID: ownerUserID} resp, err := f.Client.GetFriendIDs(ctx, &req) if err != nil { return nil, err } + return resp.FriendIDs, nil } +// IsBlocked func (b *FriendRpcClient) IsBlocked(ctx context.Context, possibleBlackUserID, userID string) (bool, error) { r, err := b.Client.IsBlack(ctx, &friend.IsBlackReq{UserID1: possibleBlackUserID, UserID2: userID}) if err != nil { return false, err } + return r.InUser2Blacks, nil } diff --git a/pkg/rpcclient/group.go b/pkg/rpcclient/group.go index 06333234f..65ef0ab0f 100644 --- a/pkg/rpcclient/group.go +++ b/pkg/rpcclient/group.go @@ -29,27 +29,33 @@ import ( "github.com/OpenIMSDK/Open-IM-Server/pkg/utils" ) +// Group type Group struct { conn grpc.ClientConnInterface Client group.GroupClient discov discoveryregistry.SvcDiscoveryRegistry } +// NewGroup func NewGroup(discov discoveryregistry.SvcDiscoveryRegistry) *Group { conn, err := discov.GetConn(context.Background(), config.Config.RpcRegisterName.OpenImGroupName) if err != nil { panic(err) } client := group.NewGroupClient(conn) + return &Group{discov: discov, conn: conn, Client: client} } +// GroupRpcClient type GroupRpcClient Group +// NewGroupRpcClient func NewGroupRpcClient(discov discoveryregistry.SvcDiscoveryRegistry) GroupRpcClient { return GroupRpcClient(*NewGroup(discov)) } +// GetGroupInfos func (g *GroupRpcClient) GetGroupInfos( ctx context.Context, groupIDs []string, @@ -71,14 +77,17 @@ func (g *GroupRpcClient) GetGroupInfos( return resp.GroupInfos, nil } +// GetGroupInfo func (g *GroupRpcClient) 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 } +// GetGroupInfoMap func (g *GroupRpcClient) GetGroupInfoMap( ctx context.Context, groupIDs []string, @@ -88,11 +97,13 @@ func (g *GroupRpcClient) GetGroupInfoMap( if err != nil { return nil, err } + return utils.SliceToMap(groups, func(e *sdkws.GroupInfo) string { return e.GroupID }), nil } +// GetGroupMemberInfos func (g *GroupRpcClient) GetGroupMemberInfos( ctx context.Context, groupID string, @@ -113,9 +124,11 @@ func (g *GroupRpcClient) GetGroupMemberInfos( return nil, errs.ErrNotInGroupYet.Wrap(strings.Join(ids, ",")) } } + return resp.Members, nil } +// GetGroupMemberInfo func (g *GroupRpcClient) GetGroupMemberInfo( ctx context.Context, groupID string, @@ -125,9 +138,11 @@ func (g *GroupRpcClient) GetGroupMemberInfo( if err != nil { return nil, err } + return members[0], nil } +// GetGroupMemberInfoMap func (g *GroupRpcClient) GetGroupMemberInfoMap( ctx context.Context, groupID string, @@ -138,11 +153,13 @@ func (g *GroupRpcClient) GetGroupMemberInfoMap( if err != nil { return nil, err } + return utils.SliceToMap(members, func(e *sdkws.GroupMemberFullInfo) string { return e.UserID }), nil } +// GetOwnerAndAdminInfos func (g *GroupRpcClient) GetOwnerAndAdminInfos( ctx context.Context, groupID string, @@ -154,17 +171,21 @@ func (g *GroupRpcClient) GetOwnerAndAdminInfos( if err != nil { return nil, err } + return resp.Members, nil } +// GetOwnerInfo func (g *GroupRpcClient) GetOwnerInfo(ctx context.Context, groupID string) (*sdkws.GroupMemberFullInfo, error) { resp, err := g.Client.GetGroupMemberRoleLevel(ctx, &group.GetGroupMemberRoleLevelReq{ GroupID: groupID, RoleLevels: []int32{constant.GroupOwner}, }) + return resp.Members[0], err } +// GetGroupMemberIDs func (g *GroupRpcClient) GetGroupMemberIDs(ctx context.Context, groupID string) ([]string, error) { resp, err := g.Client.GetGroupMemberUserIDs(ctx, &group.GetGroupMemberUserIDsReq{ GroupID: groupID, @@ -172,9 +193,11 @@ func (g *GroupRpcClient) GetGroupMemberIDs(ctx context.Context, groupID string) if err != nil { return nil, err } + return resp.UserIDs, nil } +// GetGroupInfoCache func (g *GroupRpcClient) GetGroupInfoCache(ctx context.Context, groupID string) (*sdkws.GroupInfo, error) { resp, err := g.Client.GetGroupInfoCache(ctx, &group.GetGroupInfoCacheReq{ GroupID: groupID, @@ -182,9 +205,11 @@ func (g *GroupRpcClient) GetGroupInfoCache(ctx context.Context, groupID string) if err != nil { return nil, err } + return resp.GroupInfo, nil } +// GetGroupMemberCache func (g *GroupRpcClient) GetGroupMemberCache( ctx context.Context, groupID string, @@ -197,13 +222,16 @@ func (g *GroupRpcClient) GetGroupMemberCache( if err != nil { return nil, err } + return resp.Member, nil } +// DismissGroup func (g *GroupRpcClient) DismissGroup(ctx context.Context, groupID string) error { _, err := g.Client.DismissGroup(ctx, &group.DismissGroupReq{ GroupID: groupID, DeleteMember: true, }) + return err } diff --git a/pkg/rpcclient/msg.go b/pkg/rpcclient/msg.go index be776138b..5555aba23 100644 --- a/pkg/rpcclient/msg.go +++ b/pkg/rpcclient/msg.go @@ -121,29 +121,36 @@ func newSessionTypeConf() map[int32]int32 { } } +// Message type Message struct { conn grpc.ClientConnInterface Client msg.MsgClient discov discoveryregistry.SvcDiscoveryRegistry } +// NewMessage func NewMessage(discov discoveryregistry.SvcDiscoveryRegistry) *Message { conn, err := discov.GetConn(context.Background(), config.Config.RpcRegisterName.OpenImMsgName) if err != nil { panic(err) } client := msg.NewMsgClient(conn) + return &Message{discov: discov, conn: conn, Client: client} } +// MessageRpcClient type MessageRpcClient Message +// NewMessageRpcClient func NewMessageRpcClient(discov discoveryregistry.SvcDiscoveryRegistry) MessageRpcClient { return MessageRpcClient(*NewMessage(discov)) } +// SendMsg func (m *MessageRpcClient) SendMsg(ctx context.Context, req *msg.SendMsgReq) (*msg.SendMsgResp, error) { resp, err := m.Client.SendMsg(ctx, req) + return resp, err } diff --git a/pkg/rpcclient/notification/group.go b/pkg/rpcclient/notification/group.go index abdc4d76e..5b8d87226 100644 --- a/pkg/rpcclient/notification/group.go +++ b/pkg/rpcclient/notification/group.go @@ -597,6 +597,7 @@ func (g *GroupNotificationSender) GroupMemberSetToOrdinaryUserNotification(ctx c if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil { return err } + return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberSetToOrdinaryUserNotification, tips) } diff --git a/pkg/statistics/statistics.go b/pkg/statistics/statistics.go index 8c1828380..223e2c322 100644 --- a/pkg/statistics/statistics.go +++ b/pkg/statistics/statistics.go @@ -35,12 +35,10 @@ func (s *Statistics) output() { defer t.Stop() var sum uint64 var timeIntervalNum uint64 - outputCh := make(chan struct{}) for { sum = *s.AllCount select { case <-t.C: - outputCh <- struct{}{} } if *s.AllCount-sum <= 0 { intervalCount = 0 From 2ba5c8b8077f2c7d5ff61381d7f3a549a9f097a9 Mon Sep 17 00:00:00 2001 From: BanTanger Date: Sun, 23 Jul 2023 02:51:16 +0000 Subject: [PATCH 59/62] cicd: robot automated Change Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- go.mod | 1 - go.sum | 2 - internal/api/msg.go | 1 - internal/msggateway/hub_server.go | 1 + internal/rpc/msg/send.go | 1 + pkg/apistruct/manage.go | 2 +- pkg/proto/auth/auth.pb.go | 17 +- pkg/proto/conversation/conversation.pb.go | 78 ++--- pkg/proto/errinfo/errinfo.pb.go | 11 +- pkg/proto/friend/friend.pb.go | 44 +-- pkg/proto/group/group.pb.go | 100 +++--- pkg/proto/msg/msg.pb.go | 146 ++++---- pkg/proto/msggateway/msggateway.pb.go | 48 +-- pkg/proto/push/push.pb.go | 12 +- pkg/proto/sdkws/sdkws.pb.go | 396 +++++++++++----------- pkg/proto/statistics/statistics.pb.go | 3 +- pkg/proto/third/third.pb.go | 65 ++-- pkg/proto/user/user.pb.go | 54 +-- pkg/proto/wrapperspb/wrapperspb.pb.go | 5 +- 19 files changed, 503 insertions(+), 484 deletions(-) diff --git a/go.mod b/go.mod index 21e6e2241..9fcf500a5 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,6 @@ require ( github.com/robfig/cron/v3 v3.0.1 github.com/sirupsen/logrus v1.9.2 // indirect github.com/stretchr/testify v1.8.3 - github.com/tencentyun/qcloud-cos-sts-sdk v0.0.0-20210325043845-84a0811633ca go.mongodb.org/mongo-driver v1.8.3 golang.org/x/image v0.3.0 google.golang.org/api v0.114.0 diff --git a/go.sum b/go.sum index e95d2e81e..9acc8ff8f 100644 --- a/go.sum +++ b/go.sum @@ -426,8 +426,6 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.194/go.mod github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.194/go.mod h1:yrBKWhChnDqNz1xuXdSbWXG56XawEq0G5j1lg4VwBD4= github.com/tencentyun/cos-go-sdk-v5 v0.7.41 h1:iU0Li/Np78H4SBna0ECQoF3mpgi6ImLXU+doGzPFXGc= github.com/tencentyun/cos-go-sdk-v5 v0.7.41/go.mod h1:4dCEtLHGh8QPxHEkgq+nFaky7yZxQuYwgSJM87icDaw= -github.com/tencentyun/qcloud-cos-sts-sdk v0.0.0-20210325043845-84a0811633ca h1:G/aIr3WiUesWHL2YGYgEqjM5tCAJ43Ml+0C18wDkWWs= -github.com/tencentyun/qcloud-cos-sts-sdk v0.0.0-20210325043845-84a0811633ca/go.mod h1:b18KQa4IxHbxeseW1GcZox53d7J0z39VNONTxvvlkXw= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= diff --git a/internal/api/msg.go b/internal/api/msg.go index 8ad7943e9..41ab4dc48 100644 --- a/internal/api/msg.go +++ b/internal/api/msg.go @@ -250,7 +250,6 @@ func (m *MessageApi) BatchSendMsg(c *gin.Context) { return } - var recvIDs []string var err error if req.IsSendAll { diff --git a/internal/msggateway/hub_server.go b/internal/msggateway/hub_server.go index deb8c3d77..4e1586969 100644 --- a/internal/msggateway/hub_server.go +++ b/internal/msggateway/hub_server.go @@ -16,6 +16,7 @@ package msggateway import ( "context" + "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify" "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" diff --git a/internal/rpc/msg/send.go b/internal/rpc/msg/send.go index dd02083fa..a568154c7 100644 --- a/internal/rpc/msg/send.go +++ b/internal/rpc/msg/send.go @@ -16,6 +16,7 @@ package msg import ( "context" + "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/log" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext" diff --git a/pkg/apistruct/manage.go b/pkg/apistruct/manage.go index 6a92f40aa..d3c24d544 100644 --- a/pkg/apistruct/manage.go +++ b/pkg/apistruct/manage.go @@ -33,7 +33,7 @@ type SendMsg struct { } type SendMsgReq struct { - RecvID string `json:"recvID" binding:"required_if" message:"recvID is required if sessionType is SingleChatType or NotificationChatType"` + RecvID string `json:"recvID" binding:"required_if" message:"recvID is required if sessionType is SingleChatType or NotificationChatType"` SendMsg } diff --git a/pkg/proto/auth/auth.pb.go b/pkg/proto/auth/auth.pb.go index 2d1e0493c..238d12975 100644 --- a/pkg/proto/auth/auth.pb.go +++ b/pkg/proto/auth/auth.pb.go @@ -22,13 +22,14 @@ package auth import ( context "context" + reflect "reflect" + sync "sync" + grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" ) const ( @@ -43,9 +44,9 @@ type UserTokenReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Secret string `protobuf:"bytes,1,opt,name=secret,proto3" json:"secret"` + Secret string `protobuf:"bytes,1,opt,name=secret,proto3" json:"secret"` PlatformID int32 `protobuf:"varint,2,opt,name=platformID,proto3" json:"platformID"` - UserID string `protobuf:"bytes,3,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,3,opt,name=userID,proto3" json:"userID"` } func (x *UserTokenReq) Reset() { @@ -106,7 +107,7 @@ type UserTokenResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token"` + Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token"` ExpireTimeSeconds int64 `protobuf:"varint,3,opt,name=expireTimeSeconds,proto3" json:"expireTimeSeconds"` } @@ -162,7 +163,7 @@ type ForceLogoutReq struct { unknownFields protoimpl.UnknownFields PlatformID int32 `protobuf:"varint,1,opt,name=platformID,proto3" json:"platformID"` - UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` } func (x *ForceLogoutReq) Reset() { @@ -301,8 +302,8 @@ type ParseTokenResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` - Platform string `protobuf:"bytes,2,opt,name=platform,proto3" json:"platform"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + Platform string `protobuf:"bytes,2,opt,name=platform,proto3" json:"platform"` ExpireTimeSeconds int64 `protobuf:"varint,4,opt,name=expireTimeSeconds,proto3" json:"expireTimeSeconds"` } diff --git a/pkg/proto/conversation/conversation.pb.go b/pkg/proto/conversation/conversation.pb.go index cf5de48a7..568948379 100644 --- a/pkg/proto/conversation/conversation.pb.go +++ b/pkg/proto/conversation/conversation.pb.go @@ -22,14 +22,16 @@ package conversation import ( context "context" - wrapperspb "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb" + reflect "reflect" + sync "sync" + grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" + + wrapperspb "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb" ) const ( @@ -44,23 +46,23 @@ type Conversation struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` - ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` - RecvMsgOpt int32 `protobuf:"varint,3,opt,name=recvMsgOpt,proto3" json:"recvMsgOpt"` - ConversationType int32 `protobuf:"varint,4,opt,name=conversationType,proto3" json:"conversationType"` - UserID string `protobuf:"bytes,5,opt,name=userID,proto3" json:"userID"` - GroupID string `protobuf:"bytes,6,opt,name=groupID,proto3" json:"groupID"` - IsPinned bool `protobuf:"varint,7,opt,name=isPinned,proto3" json:"isPinned"` - AttachedInfo string `protobuf:"bytes,8,opt,name=attachedInfo,proto3" json:"attachedInfo"` - IsPrivateChat bool `protobuf:"varint,9,opt,name=isPrivateChat,proto3" json:"isPrivateChat"` - GroupAtType int32 `protobuf:"varint,10,opt,name=groupAtType,proto3" json:"groupAtType"` - Ex string `protobuf:"bytes,11,opt,name=ex,proto3" json:"ex"` - BurnDuration int32 `protobuf:"varint,12,opt,name=burnDuration,proto3" json:"burnDuration"` - MinSeq int64 `protobuf:"varint,13,opt,name=minSeq,proto3" json:"minSeq"` - MaxSeq int64 `protobuf:"varint,14,opt,name=maxSeq,proto3" json:"maxSeq"` - MsgDestructTime int64 `protobuf:"varint,15,opt,name=msgDestructTime,proto3" json:"msgDestructTime"` + OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` + ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` + RecvMsgOpt int32 `protobuf:"varint,3,opt,name=recvMsgOpt,proto3" json:"recvMsgOpt"` + ConversationType int32 `protobuf:"varint,4,opt,name=conversationType,proto3" json:"conversationType"` + UserID string `protobuf:"bytes,5,opt,name=userID,proto3" json:"userID"` + GroupID string `protobuf:"bytes,6,opt,name=groupID,proto3" json:"groupID"` + IsPinned bool `protobuf:"varint,7,opt,name=isPinned,proto3" json:"isPinned"` + AttachedInfo string `protobuf:"bytes,8,opt,name=attachedInfo,proto3" json:"attachedInfo"` + IsPrivateChat bool `protobuf:"varint,9,opt,name=isPrivateChat,proto3" json:"isPrivateChat"` + GroupAtType int32 `protobuf:"varint,10,opt,name=groupAtType,proto3" json:"groupAtType"` + Ex string `protobuf:"bytes,11,opt,name=ex,proto3" json:"ex"` + BurnDuration int32 `protobuf:"varint,12,opt,name=burnDuration,proto3" json:"burnDuration"` + MinSeq int64 `protobuf:"varint,13,opt,name=minSeq,proto3" json:"minSeq"` + MaxSeq int64 `protobuf:"varint,14,opt,name=maxSeq,proto3" json:"maxSeq"` + MsgDestructTime int64 `protobuf:"varint,15,opt,name=msgDestructTime,proto3" json:"msgDestructTime"` LatestMsgDestructTime int64 `protobuf:"varint,16,opt,name=latestMsgDestructTime,proto3" json:"latestMsgDestructTime"` - IsMsgDestruct bool `protobuf:"varint,17,opt,name=isMsgDestruct,proto3" json:"isMsgDestruct"` + IsMsgDestruct bool `protobuf:"varint,17,opt,name=isMsgDestruct,proto3" json:"isMsgDestruct"` } func (x *Conversation) Reset() { @@ -219,21 +221,21 @@ type ConversationReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` + ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` ConversationType int32 `protobuf:"varint,2,opt,name=conversationType,proto3" json:"conversationType"` - UserID string `protobuf:"bytes,3,opt,name=userID,proto3" json:"userID"` - GroupID string `protobuf:"bytes,4,opt,name=groupID,proto3" json:"groupID"` - RecvMsgOpt *wrapperspb.Int32Value `protobuf:"bytes,5,opt,name=recvMsgOpt,proto3" json:"recvMsgOpt"` - IsPinned *wrapperspb.BoolValue `protobuf:"bytes,6,opt,name=isPinned,proto3" json:"isPinned"` - AttachedInfo *wrapperspb.StringValue `protobuf:"bytes,7,opt,name=attachedInfo,proto3" json:"attachedInfo"` - IsPrivateChat *wrapperspb.BoolValue `protobuf:"bytes,8,opt,name=isPrivateChat,proto3" json:"isPrivateChat"` - Ex *wrapperspb.StringValue `protobuf:"bytes,9,opt,name=ex,proto3" json:"ex"` - BurnDuration *wrapperspb.Int32Value `protobuf:"bytes,10,opt,name=burnDuration,proto3" json:"burnDuration"` - MinSeq *wrapperspb.Int64Value `protobuf:"bytes,11,opt,name=minSeq,proto3" json:"minSeq"` - MaxSeq *wrapperspb.Int64Value `protobuf:"bytes,12,opt,name=maxSeq,proto3" json:"maxSeq"` - GroupAtType *wrapperspb.Int32Value `protobuf:"bytes,13,opt,name=groupAtType,proto3" json:"groupAtType"` - MsgDestructTime *wrapperspb.Int64Value `protobuf:"bytes,14,opt,name=msgDestructTime,proto3" json:"msgDestructTime"` - IsMsgDestruct *wrapperspb.BoolValue `protobuf:"bytes,15,opt,name=isMsgDestruct,proto3" json:"isMsgDestruct"` + UserID string `protobuf:"bytes,3,opt,name=userID,proto3" json:"userID"` + GroupID string `protobuf:"bytes,4,opt,name=groupID,proto3" json:"groupID"` + RecvMsgOpt *wrapperspb.Int32Value `protobuf:"bytes,5,opt,name=recvMsgOpt,proto3" json:"recvMsgOpt"` + IsPinned *wrapperspb.BoolValue `protobuf:"bytes,6,opt,name=isPinned,proto3" json:"isPinned"` + AttachedInfo *wrapperspb.StringValue `protobuf:"bytes,7,opt,name=attachedInfo,proto3" json:"attachedInfo"` + IsPrivateChat *wrapperspb.BoolValue `protobuf:"bytes,8,opt,name=isPrivateChat,proto3" json:"isPrivateChat"` + Ex *wrapperspb.StringValue `protobuf:"bytes,9,opt,name=ex,proto3" json:"ex"` + BurnDuration *wrapperspb.Int32Value `protobuf:"bytes,10,opt,name=burnDuration,proto3" json:"burnDuration"` + MinSeq *wrapperspb.Int64Value `protobuf:"bytes,11,opt,name=minSeq,proto3" json:"minSeq"` + MaxSeq *wrapperspb.Int64Value `protobuf:"bytes,12,opt,name=maxSeq,proto3" json:"maxSeq"` + GroupAtType *wrapperspb.Int32Value `protobuf:"bytes,13,opt,name=groupAtType,proto3" json:"groupAtType"` + MsgDestructTime *wrapperspb.Int64Value `protobuf:"bytes,14,opt,name=msgDestructTime,proto3" json:"msgDestructTime"` + IsMsgDestruct *wrapperspb.BoolValue `protobuf:"bytes,15,opt,name=isMsgDestruct,proto3" json:"isMsgDestruct"` } func (x *ConversationReq) Reset() { @@ -464,7 +466,7 @@ type GetConversationReq struct { unknownFields protoimpl.UnknownFields ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` - OwnerUserID string `protobuf:"bytes,2,opt,name=ownerUserID,proto3" json:"ownerUserID"` + OwnerUserID string `protobuf:"bytes,2,opt,name=ownerUserID,proto3" json:"ownerUserID"` } func (x *GetConversationReq) Reset() { @@ -565,7 +567,7 @@ type GetConversationsReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` + OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` ConversationIDs []string `protobuf:"bytes,2,rep,name=conversationIDs,proto3" json:"conversationIDs"` } @@ -1042,8 +1044,8 @@ type SetConversationMaxSeqReq struct { unknownFields protoimpl.UnknownFields ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` - OwnerUserID []string `protobuf:"bytes,2,rep,name=ownerUserID,proto3" json:"ownerUserID"` - MaxSeq int64 `protobuf:"varint,3,opt,name=maxSeq,proto3" json:"maxSeq"` + OwnerUserID []string `protobuf:"bytes,2,rep,name=ownerUserID,proto3" json:"ownerUserID"` + MaxSeq int64 `protobuf:"varint,3,opt,name=maxSeq,proto3" json:"maxSeq"` } func (x *SetConversationMaxSeqReq) Reset() { @@ -1236,7 +1238,7 @@ type SetConversationsReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserIDs []string `protobuf:"bytes,1,rep,name=userIDs,proto3" json:"userIDs"` + UserIDs []string `protobuf:"bytes,1,rep,name=userIDs,proto3" json:"userIDs"` Conversation *ConversationReq `protobuf:"bytes,2,opt,name=conversation,proto3" json:"conversation"` } diff --git a/pkg/proto/errinfo/errinfo.pb.go b/pkg/proto/errinfo/errinfo.pb.go index 44f906d86..1beca5842 100644 --- a/pkg/proto/errinfo/errinfo.pb.go +++ b/pkg/proto/errinfo/errinfo.pb.go @@ -21,10 +21,11 @@ package errinfo import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( @@ -39,11 +40,11 @@ type ErrorInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path"` + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path"` Line uint32 `protobuf:"varint,2,opt,name=line,proto3" json:"line"` - Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name"` Cause string `protobuf:"bytes,4,opt,name=cause,proto3" json:"cause"` - Warp []string `protobuf:"bytes,5,rep,name=warp,proto3" json:"warp"` + Warp []string `protobuf:"bytes,5,rep,name=warp,proto3" json:"warp"` } func (x *ErrorInfo) Reset() { diff --git a/pkg/proto/friend/friend.pb.go b/pkg/proto/friend/friend.pb.go index 5745fcd3c..7439a475a 100644 --- a/pkg/proto/friend/friend.pb.go +++ b/pkg/proto/friend/friend.pb.go @@ -22,14 +22,16 @@ package friend import ( context "context" - sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" + reflect "reflect" + sync "sync" + grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" + + sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" ) const ( @@ -45,7 +47,7 @@ type GetPaginationFriendsReq struct { unknownFields protoimpl.UnknownFields Pagination *sdkws.RequestPagination `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination"` - UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` } func (x *GetPaginationFriendsReq) Reset() { @@ -100,7 +102,7 @@ type GetPaginationFriendsResp struct { unknownFields protoimpl.UnknownFields FriendsInfo []*sdkws.FriendInfo `protobuf:"bytes,1,rep,name=friendsInfo,proto3" json:"friendsInfo"` - Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total"` + Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total"` } func (x *GetPaginationFriendsResp) Reset() { @@ -155,9 +157,9 @@ type ApplyToAddFriendReq struct { unknownFields protoimpl.UnknownFields FromUserID string `protobuf:"bytes,1,opt,name=fromUserID,proto3" json:"fromUserID"` - ToUserID string `protobuf:"bytes,2,opt,name=toUserID,proto3" json:"toUserID"` - ReqMsg string `protobuf:"bytes,3,opt,name=reqMsg,proto3" json:"reqMsg"` - Ex string `protobuf:"bytes,4,opt,name=ex,proto3" json:"ex"` + ToUserID string `protobuf:"bytes,2,opt,name=toUserID,proto3" json:"toUserID"` + ReqMsg string `protobuf:"bytes,3,opt,name=reqMsg,proto3" json:"reqMsg"` + Ex string `protobuf:"bytes,4,opt,name=ex,proto3" json:"ex"` } func (x *ApplyToAddFriendReq) Reset() { @@ -263,7 +265,7 @@ type ImportFriendReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` + OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` FriendUserIDs []string `protobuf:"bytes,2,rep,name=friendUserIDs,proto3" json:"friendUserIDs"` } @@ -356,7 +358,7 @@ type GetPaginationFriendsApplyToReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` Pagination *sdkws.RequestPagination `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination"` } @@ -412,7 +414,7 @@ type GetPaginationFriendsApplyToResp struct { unknownFields protoimpl.UnknownFields FriendRequests []*sdkws.FriendRequest `protobuf:"bytes,1,rep,name=FriendRequests,proto3" json:"FriendRequests"` - Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total"` + Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total"` } func (x *GetPaginationFriendsApplyToResp) Reset() { @@ -466,7 +468,7 @@ type GetDesignatedFriendsReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` + OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` FriendUserIDs []string `protobuf:"bytes,2,rep,name=friendUserIDs,proto3" json:"friendUserIDs"` } @@ -754,7 +756,7 @@ type GetPaginationBlacksReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` Pagination *sdkws.RequestPagination `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination"` } @@ -1084,7 +1086,7 @@ type DeleteFriendReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` + OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` FriendUserID string `protobuf:"bytes,2,opt,name=friendUserID,proto3" json:"friendUserID"` } @@ -1178,10 +1180,10 @@ type RespondFriendApplyReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - FromUserID string `protobuf:"bytes,1,opt,name=fromUserID,proto3" json:"fromUserID"` //主动发起的申请者 - ToUserID string `protobuf:"bytes,2,opt,name=toUserID,proto3" json:"toUserID"` //被动添加者 + FromUserID string `protobuf:"bytes,1,opt,name=fromUserID,proto3" json:"fromUserID"` //主动发起的申请者 + ToUserID string `protobuf:"bytes,2,opt,name=toUserID,proto3" json:"toUserID"` //被动添加者 HandleResult int32 `protobuf:"varint,3,opt,name=handleResult,proto3" json:"handleResult"` - HandleMsg string `protobuf:"bytes,4,opt,name=handleMsg,proto3" json:"handleMsg"` + HandleMsg string `protobuf:"bytes,4,opt,name=handleMsg,proto3" json:"handleMsg"` } func (x *RespondFriendApplyReq) Reset() { @@ -1287,9 +1289,9 @@ type SetFriendRemarkReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` + OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` FriendUserID string `protobuf:"bytes,2,opt,name=friendUserID,proto3" json:"friendUserID"` - Remark string `protobuf:"bytes,3,opt,name=remark,proto3" json:"remark"` + Remark string `protobuf:"bytes,3,opt,name=remark,proto3" json:"remark"` } func (x *SetFriendRemarkReq) Reset() { @@ -1388,7 +1390,7 @@ type GetPaginationFriendsApplyFromReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` Pagination *sdkws.RequestPagination `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination"` } @@ -1444,7 +1446,7 @@ type GetPaginationFriendsApplyFromResp struct { unknownFields protoimpl.UnknownFields FriendRequests []*sdkws.FriendRequest `protobuf:"bytes,1,rep,name=friendRequests,proto3" json:"friendRequests"` - Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total"` + Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total"` } func (x *GetPaginationFriendsApplyFromResp) Reset() { diff --git a/pkg/proto/group/group.pb.go b/pkg/proto/group/group.pb.go index f4230c794..32261fc7c 100644 --- a/pkg/proto/group/group.pb.go +++ b/pkg/proto/group/group.pb.go @@ -22,15 +22,17 @@ package group import ( context "context" - sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" - wrapperspb "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb" + reflect "reflect" + sync "sync" + grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" + + sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" + wrapperspb "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb" ) const ( @@ -46,9 +48,9 @@ type CreateGroupReq struct { unknownFields protoimpl.UnknownFields MemberUserIDs []string `protobuf:"bytes,1,rep,name=memberUserIDs,proto3" json:"memberUserIDs"` - GroupInfo *sdkws.GroupInfo `protobuf:"bytes,2,opt,name=groupInfo,proto3" json:"groupInfo"` - AdminUserIDs []string `protobuf:"bytes,3,rep,name=adminUserIDs,proto3" json:"adminUserIDs"` - OwnerUserID string `protobuf:"bytes,4,opt,name=ownerUserID,proto3" json:"ownerUserID"` //owner + GroupInfo *sdkws.GroupInfo `protobuf:"bytes,2,opt,name=groupInfo,proto3" json:"groupInfo"` + AdminUserIDs []string `protobuf:"bytes,3,rep,name=adminUserIDs,proto3" json:"adminUserIDs"` + OwnerUserID string `protobuf:"bytes,4,opt,name=ownerUserID,proto3" json:"ownerUserID"` //owner } func (x *CreateGroupReq) Reset() { @@ -397,7 +399,7 @@ type GetGroupApplicationListResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` + Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` GroupRequests []*sdkws.GroupRequest `protobuf:"bytes,2,rep,name=groupRequests,proto3" json:"groupRequests"` } @@ -453,7 +455,7 @@ type GetUserReqApplicationListReq struct { unknownFields protoimpl.UnknownFields Pagination *sdkws.RequestPagination `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination"` - UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` } func (x *GetUserReqApplicationListReq) Reset() { @@ -507,7 +509,7 @@ type GetUserReqApplicationListResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` + Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` GroupRequests []*sdkws.GroupRequest `protobuf:"bytes,2,rep,name=groupRequests,proto3" json:"groupRequests"` } @@ -562,7 +564,7 @@ type TransferGroupOwnerReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` OldOwnerUserID string `protobuf:"bytes,2,opt,name=oldOwnerUserID,proto3" json:"oldOwnerUserID"` NewOwnerUserID string `protobuf:"bytes,3,opt,name=newOwnerUserID,proto3" json:"newOwnerUserID"` } @@ -663,9 +665,9 @@ type JoinGroupReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` - ReqMessage string `protobuf:"bytes,2,opt,name=reqMessage,proto3" json:"reqMessage"` - JoinSource int32 `protobuf:"varint,3,opt,name=joinSource,proto3" json:"joinSource"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + ReqMessage string `protobuf:"bytes,2,opt,name=reqMessage,proto3" json:"reqMessage"` + JoinSource int32 `protobuf:"varint,3,opt,name=joinSource,proto3" json:"joinSource"` InviterUserID string `protobuf:"bytes,4,opt,name=inviterUserID,proto3" json:"inviterUserID"` } @@ -772,9 +774,9 @@ type GroupApplicationResponseReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` - FromUserID string `protobuf:"bytes,2,opt,name=fromUserID,proto3" json:"fromUserID"` // - HandledMsg string `protobuf:"bytes,3,opt,name=handledMsg,proto3" json:"handledMsg"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + FromUserID string `protobuf:"bytes,2,opt,name=fromUserID,proto3" json:"fromUserID"` // + HandledMsg string `protobuf:"bytes,3,opt,name=handledMsg,proto3" json:"handledMsg"` HandleResult int32 `protobuf:"varint,4,opt,name=handleResult,proto3" json:"handleResult"` } @@ -967,8 +969,8 @@ type GetGroupMemberListReq struct { unknownFields protoimpl.UnknownFields Pagination *sdkws.RequestPagination `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination"` - GroupID string `protobuf:"bytes,2,opt,name=groupID,proto3" json:"groupID"` - Filter int32 `protobuf:"varint,3,opt,name=filter,proto3" json:"filter"` + GroupID string `protobuf:"bytes,2,opt,name=groupID,proto3" json:"groupID"` + Filter int32 `protobuf:"varint,3,opt,name=filter,proto3" json:"filter"` } func (x *GetGroupMemberListReq) Reset() { @@ -1029,7 +1031,7 @@ type GetGroupMemberListResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` + Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` Members []*sdkws.GroupMemberFullInfo `protobuf:"bytes,2,rep,name=members,proto3" json:"members"` } @@ -1186,9 +1188,9 @@ type KickGroupMemberReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` KickedUserIDs []string `protobuf:"bytes,2,rep,name=kickedUserIDs,proto3" json:"kickedUserIDs"` - Reason string `protobuf:"bytes,3,opt,name=reason,proto3" json:"reason"` + Reason string `protobuf:"bytes,3,opt,name=reason,proto3" json:"reason"` } func (x *KickGroupMemberReq) Reset() { @@ -1397,8 +1399,8 @@ type InviteUserToGroupReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` - Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason"` InvitedUserIDs []string `protobuf:"bytes,3,rep,name=invitedUserIDs,proto3" json:"invitedUserIDs"` } @@ -1499,7 +1501,7 @@ type GetGroupAllMemberReq struct { unknownFields protoimpl.UnknownFields Pagination *sdkws.RequestPagination `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination"` - GroupID string `protobuf:"bytes,2,opt,name=groupID,proto3" json:"groupID"` + GroupID string `protobuf:"bytes,2,opt,name=groupID,proto3" json:"groupID"` } func (x *GetGroupAllMemberReq) Reset() { @@ -1600,9 +1602,9 @@ type CMSGroup struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupInfo *sdkws.GroupInfo `protobuf:"bytes,1,opt,name=groupInfo,proto3" json:"groupInfo"` + GroupInfo *sdkws.GroupInfo `protobuf:"bytes,1,opt,name=groupInfo,proto3" json:"groupInfo"` GroupOwnerUserName string `protobuf:"bytes,2,opt,name=groupOwnerUserName,proto3" json:"groupOwnerUserName"` - GroupOwnerUserID string `protobuf:"bytes,3,opt,name=groupOwnerUserID,proto3" json:"groupOwnerUserID"` + GroupOwnerUserID string `protobuf:"bytes,3,opt,name=groupOwnerUserID,proto3" json:"groupOwnerUserID"` } func (x *CMSGroup) Reset() { @@ -1664,8 +1666,8 @@ type GetGroupsReq struct { unknownFields protoimpl.UnknownFields Pagination *sdkws.RequestPagination `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination"` - GroupName string `protobuf:"bytes,2,opt,name=groupName,proto3" json:"groupName"` - GroupID string `protobuf:"bytes,3,opt,name=groupID,proto3" json:"groupID"` + GroupName string `protobuf:"bytes,2,opt,name=groupName,proto3" json:"groupName"` + GroupID string `protobuf:"bytes,3,opt,name=groupID,proto3" json:"groupID"` } func (x *GetGroupsReq) Reset() { @@ -1829,8 +1831,8 @@ type GetGroupMembersCMSReq struct { unknownFields protoimpl.UnknownFields Pagination *sdkws.RequestPagination `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination"` - GroupID string `protobuf:"bytes,2,opt,name=groupID,proto3" json:"groupID"` - UserName string `protobuf:"bytes,3,opt,name=userName,proto3" json:"userName"` + GroupID string `protobuf:"bytes,2,opt,name=groupID,proto3" json:"groupID"` + UserName string `protobuf:"bytes,3,opt,name=userName,proto3" json:"userName"` } func (x *GetGroupMembersCMSReq) Reset() { @@ -1891,7 +1893,7 @@ type GetGroupMembersCMSResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` + Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` Members []*sdkws.GroupMemberFullInfo `protobuf:"bytes,2,rep,name=members,proto3" json:"members"` } @@ -1946,7 +1948,7 @@ type DismissGroupReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` DeleteMember bool `protobuf:"varint,2,opt,name=deleteMember,proto3" json:"deleteMember"` } @@ -2039,8 +2041,8 @@ type MuteGroupMemberReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` - UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` MutedSeconds uint32 `protobuf:"varint,3,opt,name=mutedSeconds,proto3" json:"mutedSeconds"` } @@ -2141,7 +2143,7 @@ type CancelMuteGroupMemberReq struct { unknownFields protoimpl.UnknownFields GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` - UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` } func (x *CancelMuteGroupMemberReq) Reset() { @@ -2591,12 +2593,12 @@ type SetGroupMemberInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` - UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` - Nickname *wrapperspb.StringValue `protobuf:"bytes,3,opt,name=nickname,proto3" json:"nickname"` - FaceURL *wrapperspb.StringValue `protobuf:"bytes,4,opt,name=faceURL,proto3" json:"faceURL"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` + Nickname *wrapperspb.StringValue `protobuf:"bytes,3,opt,name=nickname,proto3" json:"nickname"` + FaceURL *wrapperspb.StringValue `protobuf:"bytes,4,opt,name=faceURL,proto3" json:"faceURL"` RoleLevel *wrapperspb.Int32Value `protobuf:"bytes,5,opt,name=roleLevel,proto3" json:"roleLevel"` - Ex *wrapperspb.StringValue `protobuf:"bytes,6,opt,name=ex,proto3" json:"ex"` + Ex *wrapperspb.StringValue `protobuf:"bytes,6,opt,name=ex,proto3" json:"ex"` } func (x *SetGroupMemberInfo) Reset() { @@ -2810,8 +2812,8 @@ type GroupAbstractInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` - GroupMemberNumber uint32 `protobuf:"varint,2,opt,name=groupMemberNumber,proto3" json:"groupMemberNumber"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + GroupMemberNumber uint32 `protobuf:"varint,2,opt,name=groupMemberNumber,proto3" json:"groupMemberNumber"` GroupMemberListHash uint64 `protobuf:"varint,3,opt,name=groupMemberListHash,proto3" json:"groupMemberListHash"` } @@ -2920,7 +2922,7 @@ type GetUserInGroupMembersReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` GroupIDs []string `protobuf:"bytes,2,rep,name=groupIDs,proto3" json:"groupIDs"` } @@ -3116,7 +3118,7 @@ type GetGroupMemberRoleLevelReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` RoleLevels []int32 `protobuf:"varint,2,rep,packed,name=roleLevels,proto3" json:"roleLevels"` } @@ -3312,7 +3314,7 @@ type GetGroupMemberCacheReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` GroupMemberID string `protobuf:"bytes,2,opt,name=groupMemberID,proto3" json:"groupMemberID"` } @@ -3415,7 +3417,7 @@ type GroupCreateCountReq struct { unknownFields protoimpl.UnknownFields Start int64 `protobuf:"varint,1,opt,name=start,proto3" json:"start"` - End int64 `protobuf:"varint,2,opt,name=end,proto3" json:"end"` + End int64 `protobuf:"varint,2,opt,name=end,proto3" json:"end"` } func (x *GroupCreateCountReq) Reset() { @@ -3469,9 +3471,9 @@ type GroupCreateCountResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Total int64 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` + Total int64 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` Before int64 `protobuf:"varint,2,opt,name=before,proto3" json:"before"` - Count map[string]int64 `protobuf:"bytes,3,rep,name=count,proto3" json:"count" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + Count map[string]int64 `protobuf:"bytes,3,rep,name=count,proto3" json:"count" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` } func (x *GroupCreateCountResp) Reset() { diff --git a/pkg/proto/msg/msg.pb.go b/pkg/proto/msg/msg.pb.go index db1f019c2..01e8463bf 100644 --- a/pkg/proto/msg/msg.pb.go +++ b/pkg/proto/msg/msg.pb.go @@ -22,14 +22,16 @@ package msg import ( context "context" - sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" + reflect "reflect" + sync "sync" + grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" + + sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" ) const ( @@ -44,7 +46,7 @@ type MsgDataToMQ struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token"` + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token"` MsgData *sdkws.MsgData `protobuf:"bytes,2,opt,name=msgData,proto3" json:"msgData"` } @@ -146,7 +148,7 @@ type PushMsgDataToMQ struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - MsgData *sdkws.MsgData `protobuf:"bytes,1,opt,name=msgData,proto3" json:"msgData"` + MsgData *sdkws.MsgData `protobuf:"bytes,1,opt,name=msgData,proto3" json:"msgData"` ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` } @@ -201,9 +203,9 @@ type MsgDataToMongoByMQ struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - LastSeq int64 `protobuf:"varint,1,opt,name=lastSeq,proto3" json:"lastSeq"` + LastSeq int64 `protobuf:"varint,1,opt,name=lastSeq,proto3" json:"lastSeq"` ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` - MsgData []*sdkws.MsgData `protobuf:"bytes,3,rep,name=msgData,proto3" json:"msgData"` + MsgData []*sdkws.MsgData `protobuf:"bytes,3,rep,name=msgData,proto3" json:"msgData"` } func (x *MsgDataToMongoByMQ) Reset() { @@ -415,7 +417,7 @@ type SendMsgResp struct { ServerMsgID string `protobuf:"bytes,1,opt,name=serverMsgID,proto3" json:"serverMsgID"` ClientMsgID string `protobuf:"bytes,2,opt,name=clientMsgID,proto3" json:"clientMsgID"` - SendTime int64 `protobuf:"varint,3,opt,name=sendTime,proto3" json:"sendTime"` + SendTime int64 `protobuf:"varint,3,opt,name=sendTime,proto3" json:"sendTime"` } func (x *SendMsgResp) Reset() { @@ -646,7 +648,7 @@ type MsgDataToModifyByMQ struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Messages []*sdkws.MsgData `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages"` + Messages []*sdkws.MsgData `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages"` ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` } @@ -778,8 +780,8 @@ type RevokeMsgReq struct { unknownFields protoimpl.UnknownFields ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` - Seq int64 `protobuf:"varint,2,opt,name=seq,proto3" json:"seq"` - UserID string `protobuf:"bytes,3,opt,name=userID,proto3" json:"userID"` + Seq int64 `protobuf:"varint,2,opt,name=seq,proto3" json:"seq"` + UserID string `protobuf:"bytes,3,opt,name=userID,proto3" json:"userID"` } func (x *RevokeMsgReq) Reset() { @@ -879,8 +881,8 @@ type MarkMsgsAsReadReq struct { unknownFields protoimpl.UnknownFields ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` - Seqs []int64 `protobuf:"varint,2,rep,packed,name=seqs,proto3" json:"seqs"` - UserID string `protobuf:"bytes,3,opt,name=userID,proto3" json:"userID"` + Seqs []int64 `protobuf:"varint,2,rep,packed,name=seqs,proto3" json:"seqs"` + UserID string `protobuf:"bytes,3,opt,name=userID,proto3" json:"userID"` } func (x *MarkMsgsAsReadReq) Reset() { @@ -980,9 +982,9 @@ type MarkConversationAsReadReq struct { unknownFields protoimpl.UnknownFields ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` - UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` - HasReadSeq int64 `protobuf:"varint,3,opt,name=hasReadSeq,proto3" json:"hasReadSeq"` - Seqs []int64 `protobuf:"varint,4,rep,packed,name=seqs,proto3" json:"seqs"` + UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` + HasReadSeq int64 `protobuf:"varint,3,opt,name=hasReadSeq,proto3" json:"hasReadSeq"` + Seqs []int64 `protobuf:"varint,4,rep,packed,name=seqs,proto3" json:"seqs"` } func (x *MarkConversationAsReadReq) Reset() { @@ -1089,8 +1091,8 @@ type SetConversationHasReadSeqReq struct { unknownFields protoimpl.UnknownFields ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` - UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` - HasReadSeq int64 `protobuf:"varint,3,opt,name=hasReadSeq,proto3" json:"hasReadSeq"` + UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` + HasReadSeq int64 `protobuf:"varint,3,opt,name=hasReadSeq,proto3" json:"hasReadSeq"` } func (x *SetConversationHasReadSeqReq) Reset() { @@ -1189,7 +1191,7 @@ type DeleteSyncOpt struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - IsSyncSelf bool `protobuf:"varint,3,opt,name=IsSyncSelf,proto3" json:"IsSyncSelf"` + IsSyncSelf bool `protobuf:"varint,3,opt,name=IsSyncSelf,proto3" json:"IsSyncSelf"` IsSyncOther bool `protobuf:"varint,4,opt,name=IsSyncOther,proto3" json:"IsSyncOther"` } @@ -1245,8 +1247,8 @@ type ClearConversationsMsgReq struct { unknownFields protoimpl.UnknownFields ConversationIDs []string `protobuf:"bytes,1,rep,name=conversationIDs,proto3" json:"conversationIDs"` - UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` - DeleteSyncOpt *DeleteSyncOpt `protobuf:"bytes,3,opt,name=deleteSyncOpt,proto3" json:"deleteSyncOpt"` + UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` + DeleteSyncOpt *DeleteSyncOpt `protobuf:"bytes,3,opt,name=deleteSyncOpt,proto3" json:"deleteSyncOpt"` } func (x *ClearConversationsMsgReq) Reset() { @@ -1345,7 +1347,7 @@ type UserClearAllMsgReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` DeleteSyncOpt *DeleteSyncOpt `protobuf:"bytes,3,opt,name=deleteSyncOpt,proto3" json:"deleteSyncOpt"` } @@ -1439,9 +1441,9 @@ type DeleteMsgsReq struct { unknownFields protoimpl.UnknownFields ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` - Seqs []int64 `protobuf:"varint,2,rep,packed,name=seqs,proto3" json:"seqs"` - UserID string `protobuf:"bytes,3,opt,name=userID,proto3" json:"userID"` - DeleteSyncOpt *DeleteSyncOpt `protobuf:"bytes,4,opt,name=deleteSyncOpt,proto3" json:"deleteSyncOpt"` + Seqs []int64 `protobuf:"varint,2,rep,packed,name=seqs,proto3" json:"seqs"` + UserID string `protobuf:"bytes,3,opt,name=userID,proto3" json:"userID"` + DeleteSyncOpt *DeleteSyncOpt `protobuf:"bytes,4,opt,name=deleteSyncOpt,proto3" json:"deleteSyncOpt"` } func (x *DeleteMsgsReq) Reset() { @@ -1548,7 +1550,7 @@ type DeleteMsgPhysicalReq struct { unknownFields protoimpl.UnknownFields ConversationIDs []string `protobuf:"bytes,1,rep,name=conversationIDs,proto3" json:"conversationIDs"` - Timestamp int64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp"` + Timestamp int64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp"` } func (x *DeleteMsgPhysicalReq) Reset() { @@ -1641,7 +1643,7 @@ type DeleteMsgPhysicalBySeqReq struct { unknownFields protoimpl.UnknownFields ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` - Seqs []int64 `protobuf:"varint,2,rep,packed,name=seqs,proto3" json:"seqs"` + Seqs []int64 `protobuf:"varint,2,rep,packed,name=seqs,proto3" json:"seqs"` } func (x *DeleteMsgPhysicalBySeqReq) Reset() { @@ -1874,7 +1876,7 @@ type Seqs struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - MaxSeq int64 `protobuf:"varint,1,opt,name=maxSeq,proto3" json:"maxSeq"` + MaxSeq int64 `protobuf:"varint,1,opt,name=maxSeq,proto3" json:"maxSeq"` HasReadSeq int64 `protobuf:"varint,2,opt,name=hasReadSeq,proto3" json:"hasReadSeq"` } @@ -1976,10 +1978,10 @@ type GetActiveUserReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Start int64 `protobuf:"varint,1,opt,name=start,proto3" json:"start"` - End int64 `protobuf:"varint,2,opt,name=end,proto3" json:"end"` - Ase bool `protobuf:"varint,3,opt,name=ase,proto3" json:"ase"` - Group bool `protobuf:"varint,4,opt,name=group,proto3" json:"group"` + Start int64 `protobuf:"varint,1,opt,name=start,proto3" json:"start"` + End int64 `protobuf:"varint,2,opt,name=end,proto3" json:"end"` + Ase bool `protobuf:"varint,3,opt,name=ase,proto3" json:"ase"` + Group bool `protobuf:"varint,4,opt,name=group,proto3" json:"group"` Pagination *sdkws.RequestPagination `protobuf:"bytes,5,opt,name=pagination,proto3" json:"pagination"` } @@ -2055,7 +2057,7 @@ type ActiveUser struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - User *sdkws.UserInfo `protobuf:"bytes,1,opt,name=user,proto3" json:"user"` + User *sdkws.UserInfo `protobuf:"bytes,1,opt,name=user,proto3" json:"user"` Count int64 `protobuf:"varint,2,opt,name=count,proto3" json:"count"` } @@ -2110,10 +2112,10 @@ type GetActiveUserResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - MsgCount int64 `protobuf:"varint,1,opt,name=msgCount,proto3" json:"msgCount"` + MsgCount int64 `protobuf:"varint,1,opt,name=msgCount,proto3" json:"msgCount"` UserCount int64 `protobuf:"varint,2,opt,name=userCount,proto3" json:"userCount"` - DateCount map[string]int64 `protobuf:"bytes,3,rep,name=dateCount,proto3" json:"dateCount" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` - Users []*ActiveUser `protobuf:"bytes,4,rep,name=users,proto3" json:"users"` + DateCount map[string]int64 `protobuf:"bytes,3,rep,name=dateCount,proto3" json:"dateCount" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + Users []*ActiveUser `protobuf:"bytes,4,rep,name=users,proto3" json:"users"` } func (x *GetActiveUserResp) Reset() { @@ -2181,9 +2183,9 @@ type GetActiveGroupReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Start int64 `protobuf:"varint,1,opt,name=start,proto3" json:"start"` - End int64 `protobuf:"varint,2,opt,name=end,proto3" json:"end"` - Ase bool `protobuf:"varint,3,opt,name=ase,proto3" json:"ase"` + Start int64 `protobuf:"varint,1,opt,name=start,proto3" json:"start"` + End int64 `protobuf:"varint,2,opt,name=end,proto3" json:"end"` + Ase bool `protobuf:"varint,3,opt,name=ase,proto3" json:"ase"` Pagination *sdkws.RequestPagination `protobuf:"bytes,4,opt,name=pagination,proto3" json:"pagination"` } @@ -2252,7 +2254,7 @@ type ActiveGroup struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *sdkws.GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + Group *sdkws.GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` Count int64 `protobuf:"varint,2,opt,name=count,proto3" json:"count"` } @@ -2307,10 +2309,10 @@ type GetActiveGroupResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - MsgCount int64 `protobuf:"varint,1,opt,name=msgCount,proto3" json:"msgCount"` + MsgCount int64 `protobuf:"varint,1,opt,name=msgCount,proto3" json:"msgCount"` GroupCount int64 `protobuf:"varint,2,opt,name=groupCount,proto3" json:"groupCount"` - DateCount map[string]int64 `protobuf:"bytes,3,rep,name=dateCount,proto3" json:"dateCount" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` - Groups []*ActiveGroup `protobuf:"bytes,4,rep,name=groups,proto3" json:"groups"` + DateCount map[string]int64 `protobuf:"bytes,3,rep,name=dateCount,proto3" json:"dateCount" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + Groups []*ActiveGroup `protobuf:"bytes,4,rep,name=groups,proto3" json:"groups"` } func (x *GetActiveGroupResp) Reset() { @@ -2378,12 +2380,12 @@ type SearchMessageReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - SendID string `protobuf:"bytes,1,opt,name=sendID,proto3" json:"sendID"` //发送者ID - RecvID string `protobuf:"bytes,2,opt,name=recvID,proto3" json:"recvID"` //接收者ID - MsgType int32 `protobuf:"varint,3,opt,name=msgType,proto3" json:"msgType"` - SendTime string `protobuf:"bytes,4,opt,name=sendTime,proto3" json:"sendTime"` + SendID string `protobuf:"bytes,1,opt,name=sendID,proto3" json:"sendID"` //发送者ID + RecvID string `protobuf:"bytes,2,opt,name=recvID,proto3" json:"recvID"` //接收者ID + MsgType int32 `protobuf:"varint,3,opt,name=msgType,proto3" json:"msgType"` + SendTime string `protobuf:"bytes,4,opt,name=sendTime,proto3" json:"sendTime"` SessionType int32 `protobuf:"varint,5,opt,name=sessionType,proto3" json:"sessionType"` - Pagination *sdkws.RequestPagination `protobuf:"bytes,6,opt,name=pagination,proto3" json:"pagination"` + Pagination *sdkws.RequestPagination `protobuf:"bytes,6,opt,name=pagination,proto3" json:"pagination"` } func (x *SearchMessageReq) Reset() { @@ -2465,7 +2467,7 @@ type SearchMessageResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ChatLogs []*ChatLog `protobuf:"bytes,1,rep,name=chatLogs,proto3" json:"chatLogs"` + ChatLogs []*ChatLog `protobuf:"bytes,1,rep,name=chatLogs,proto3" json:"chatLogs"` ChatLogsNum int32 `protobuf:"varint,2,opt,name=chatLogsNum,proto3" json:"chatLogsNum"` } @@ -2520,29 +2522,29 @@ type ChatLog struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ServerMsgID string `protobuf:"bytes,1,opt,name=serverMsgID,proto3" json:"serverMsgID"` - ClientMsgID string `protobuf:"bytes,2,opt,name=clientMsgID,proto3" json:"clientMsgID"` - SendID string `protobuf:"bytes,3,opt,name=sendID,proto3" json:"sendID"` - RecvID string `protobuf:"bytes,4,opt,name=recvID,proto3" json:"recvID"` - GroupID string `protobuf:"bytes,5,opt,name=groupID,proto3" json:"groupID"` - RecvNickname string `protobuf:"bytes,6,opt,name=recvNickname,proto3" json:"recvNickname"` - SenderPlatformID int32 `protobuf:"varint,7,opt,name=senderPlatformID,proto3" json:"senderPlatformID"` - SenderNickname string `protobuf:"bytes,8,opt,name=senderNickname,proto3" json:"senderNickname"` - SenderFaceURL string `protobuf:"bytes,9,opt,name=senderFaceURL,proto3" json:"senderFaceURL"` - GroupName string `protobuf:"bytes,10,opt,name=groupName,proto3" json:"groupName"` - SessionType int32 `protobuf:"varint,11,opt,name=sessionType,proto3" json:"sessionType"` - MsgFrom int32 `protobuf:"varint,12,opt,name=msgFrom,proto3" json:"msgFrom"` - ContentType int32 `protobuf:"varint,13,opt,name=contentType,proto3" json:"contentType"` - Content string `protobuf:"bytes,14,opt,name=content,proto3" json:"content"` - Status int32 `protobuf:"varint,15,opt,name=status,proto3" json:"status"` - SendTime int64 `protobuf:"varint,16,opt,name=sendTime,proto3" json:"sendTime"` - CreateTime int64 `protobuf:"varint,17,opt,name=createTime,proto3" json:"createTime"` - Ex string `protobuf:"bytes,18,opt,name=ex,proto3" json:"ex"` - GroupFaceURL string `protobuf:"bytes,19,opt,name=groupFaceURL,proto3" json:"groupFaceURL"` + ServerMsgID string `protobuf:"bytes,1,opt,name=serverMsgID,proto3" json:"serverMsgID"` + ClientMsgID string `protobuf:"bytes,2,opt,name=clientMsgID,proto3" json:"clientMsgID"` + SendID string `protobuf:"bytes,3,opt,name=sendID,proto3" json:"sendID"` + RecvID string `protobuf:"bytes,4,opt,name=recvID,proto3" json:"recvID"` + GroupID string `protobuf:"bytes,5,opt,name=groupID,proto3" json:"groupID"` + RecvNickname string `protobuf:"bytes,6,opt,name=recvNickname,proto3" json:"recvNickname"` + SenderPlatformID int32 `protobuf:"varint,7,opt,name=senderPlatformID,proto3" json:"senderPlatformID"` + SenderNickname string `protobuf:"bytes,8,opt,name=senderNickname,proto3" json:"senderNickname"` + SenderFaceURL string `protobuf:"bytes,9,opt,name=senderFaceURL,proto3" json:"senderFaceURL"` + GroupName string `protobuf:"bytes,10,opt,name=groupName,proto3" json:"groupName"` + SessionType int32 `protobuf:"varint,11,opt,name=sessionType,proto3" json:"sessionType"` + MsgFrom int32 `protobuf:"varint,12,opt,name=msgFrom,proto3" json:"msgFrom"` + ContentType int32 `protobuf:"varint,13,opt,name=contentType,proto3" json:"contentType"` + Content string `protobuf:"bytes,14,opt,name=content,proto3" json:"content"` + Status int32 `protobuf:"varint,15,opt,name=status,proto3" json:"status"` + SendTime int64 `protobuf:"varint,16,opt,name=sendTime,proto3" json:"sendTime"` + CreateTime int64 `protobuf:"varint,17,opt,name=createTime,proto3" json:"createTime"` + Ex string `protobuf:"bytes,18,opt,name=ex,proto3" json:"ex"` + GroupFaceURL string `protobuf:"bytes,19,opt,name=groupFaceURL,proto3" json:"groupFaceURL"` GroupMemberCount uint32 `protobuf:"varint,20,opt,name=groupMemberCount,proto3" json:"groupMemberCount"` - Seq int64 `protobuf:"varint,21,opt,name=seq,proto3" json:"seq"` - GroupOwner string `protobuf:"bytes,22,opt,name=groupOwner,proto3" json:"groupOwner"` - GroupType int32 `protobuf:"varint,23,opt,name=groupType,proto3" json:"groupType"` + Seq int64 `protobuf:"varint,21,opt,name=seq,proto3" json:"seq"` + GroupOwner string `protobuf:"bytes,22,opt,name=groupOwner,proto3" json:"groupOwner"` + GroupType int32 `protobuf:"varint,23,opt,name=groupType,proto3" json:"groupType"` } func (x *ChatLog) Reset() { @@ -2744,7 +2746,7 @@ type BatchSendMessageReq struct { unknownFields protoimpl.UnknownFields RecvIDList []string `protobuf:"bytes,1,rep,name=recvIDList,proto3" json:"recvIDList"` - MsgData *sdkws.MsgData `protobuf:"bytes,2,opt,name=msgData,proto3" json:"msgData"` + MsgData *sdkws.MsgData `protobuf:"bytes,2,opt,name=msgData,proto3" json:"msgData"` } func (x *BatchSendMessageReq) Reset() { diff --git a/pkg/proto/msggateway/msggateway.pb.go b/pkg/proto/msggateway/msggateway.pb.go index d922d98b4..353524897 100644 --- a/pkg/proto/msggateway/msggateway.pb.go +++ b/pkg/proto/msggateway/msggateway.pb.go @@ -22,14 +22,16 @@ package msggateway import ( context "context" - sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" + reflect "reflect" + sync "sync" + grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" + + sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" ) const ( @@ -44,7 +46,7 @@ type OnlinePushMsgReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - MsgData *sdkws.MsgData `protobuf:"bytes,1,opt,name=msgData,proto3" json:"msgData"` + MsgData *sdkws.MsgData `protobuf:"bytes,1,opt,name=msgData,proto3" json:"msgData"` PushToUserID string `protobuf:"bytes,2,opt,name=pushToUserID,proto3" json:"pushToUserID"` } @@ -146,8 +148,8 @@ type SingleMsgToUserResults struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` - Resp []*SingleMsgToUserPlatform `protobuf:"bytes,2,rep,name=resp,proto3" json:"resp"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + Resp []*SingleMsgToUserPlatform `protobuf:"bytes,2,rep,name=resp,proto3" json:"resp"` OnlinePush bool `protobuf:"varint,3,opt,name=onlinePush,proto3" json:"onlinePush"` } @@ -209,7 +211,7 @@ type OnlineBatchPushOneMsgReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - MsgData *sdkws.MsgData `protobuf:"bytes,1,opt,name=msgData,proto3" json:"msgData"` + MsgData *sdkws.MsgData `protobuf:"bytes,1,opt,name=msgData,proto3" json:"msgData"` PushToUserIDs []string `protobuf:"bytes,2,rep,name=pushToUserIDs,proto3" json:"pushToUserIDs"` } @@ -311,8 +313,8 @@ type SingleMsgToUserPlatform struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ResultCode int64 `protobuf:"varint,1,opt,name=ResultCode,proto3" json:"ResultCode"` - RecvID string `protobuf:"bytes,2,opt,name=RecvID,proto3" json:"RecvID"` + ResultCode int64 `protobuf:"varint,1,opt,name=ResultCode,proto3" json:"ResultCode"` + RecvID string `protobuf:"bytes,2,opt,name=RecvID,proto3" json:"RecvID"` RecvPlatFormID int32 `protobuf:"varint,3,opt,name=RecvPlatFormID,proto3" json:"RecvPlatFormID"` } @@ -422,7 +424,7 @@ type GetUsersOnlineStatusResp struct { unknownFields protoimpl.UnknownFields SuccessResult []*GetUsersOnlineStatusResp_SuccessResult `protobuf:"bytes,1,rep,name=successResult,proto3" json:"successResult"` - FailedResult []*GetUsersOnlineStatusResp_FailedDetail `protobuf:"bytes,2,rep,name=failedResult,proto3" json:"failedResult"` + FailedResult []*GetUsersOnlineStatusResp_FailedDetail `protobuf:"bytes,2,rep,name=failedResult,proto3" json:"failedResult"` } func (x *GetUsersOnlineStatusResp) Reset() { @@ -476,8 +478,8 @@ type SingleDetail struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` - Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status"` SinglePlatformToken []*SinglePlatformToken `protobuf:"bytes,3,rep,name=singlePlatformToken,proto3" json:"singlePlatformToken"` } @@ -540,8 +542,8 @@ type SinglePlatformToken struct { unknownFields protoimpl.UnknownFields Platform string `protobuf:"bytes,1,opt,name=platform,proto3" json:"platform"` - Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total"` - Token []string `protobuf:"bytes,3,rep,name=token,proto3" json:"token"` + Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total"` + Token []string `protobuf:"bytes,3,rep,name=token,proto3" json:"token"` } func (x *SinglePlatformToken) Reset() { @@ -602,7 +604,7 @@ type KickUserOfflineReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - PlatformID int32 `protobuf:"varint,1,opt,name=platformID,proto3" json:"platformID"` + PlatformID int32 `protobuf:"varint,1,opt,name=platformID,proto3" json:"platformID"` KickUserIDList []string `protobuf:"bytes,2,rep,name=kickUserIDList,proto3" json:"kickUserIDList"` } @@ -695,9 +697,9 @@ type MultiTerminalLoginCheckReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` PlatformID int32 `protobuf:"varint,2,opt,name=platformID,proto3" json:"platformID"` - Token string `protobuf:"bytes,3,opt,name=token,proto3" json:"token"` + Token string `protobuf:"bytes,3,opt,name=token,proto3" json:"token"` OperationID string `protobuf:"bytes,4,opt,name=operationID,proto3" json:"operationID"` } @@ -804,11 +806,11 @@ type GetUsersOnlineStatusResp_SuccessDetail struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Platform string `protobuf:"bytes,1,opt,name=platform,proto3" json:"platform"` - Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status"` - ConnID string `protobuf:"bytes,3,opt,name=connID,proto3" json:"connID"` + Platform string `protobuf:"bytes,1,opt,name=platform,proto3" json:"platform"` + Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status"` + ConnID string `protobuf:"bytes,3,opt,name=connID,proto3" json:"connID"` IsBackground bool `protobuf:"varint,4,opt,name=isBackground,proto3" json:"isBackground"` - Token string `protobuf:"bytes,5,opt,name=token,proto3" json:"token"` + Token string `protobuf:"bytes,5,opt,name=token,proto3" json:"token"` } func (x *GetUsersOnlineStatusResp_SuccessDetail) Reset() { @@ -930,8 +932,8 @@ type GetUsersOnlineStatusResp_SuccessResult struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` - Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status"` DetailPlatformStatus []*GetUsersOnlineStatusResp_SuccessDetail `protobuf:"bytes,3,rep,name=detailPlatformStatus,proto3" json:"detailPlatformStatus"` } diff --git a/pkg/proto/push/push.pb.go b/pkg/proto/push/push.pb.go index 1dc9d2ab9..7ef946b60 100644 --- a/pkg/proto/push/push.pb.go +++ b/pkg/proto/push/push.pb.go @@ -22,14 +22,16 @@ package push import ( context "context" - sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" + reflect "reflect" + sync "sync" + grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" + + sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" ) const ( @@ -44,7 +46,7 @@ type PushMsgReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - MsgData *sdkws.MsgData `protobuf:"bytes,1,opt,name=msgData,proto3" json:"msgData"` + MsgData *sdkws.MsgData `protobuf:"bytes,1,opt,name=msgData,proto3" json:"msgData"` ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` } @@ -137,7 +139,7 @@ type DelUserPushTokenReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` PlatformID int32 `protobuf:"varint,2,opt,name=platformID,proto3" json:"platformID"` } diff --git a/pkg/proto/sdkws/sdkws.pb.go b/pkg/proto/sdkws/sdkws.pb.go index b45d46d4c..ca6e6135a 100644 --- a/pkg/proto/sdkws/sdkws.pb.go +++ b/pkg/proto/sdkws/sdkws.pb.go @@ -21,11 +21,13 @@ package sdkws import ( - wrapperspb "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + + wrapperspb "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb" ) const ( @@ -87,23 +89,23 @@ type GroupInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` - GroupName string `protobuf:"bytes,2,opt,name=groupName,proto3" json:"groupName"` - Notification string `protobuf:"bytes,3,opt,name=notification,proto3" json:"notification"` - Introduction string `protobuf:"bytes,4,opt,name=introduction,proto3" json:"introduction"` - FaceURL string `protobuf:"bytes,5,opt,name=faceURL,proto3" json:"faceURL"` - OwnerUserID string `protobuf:"bytes,6,opt,name=ownerUserID,proto3" json:"ownerUserID"` - CreateTime int64 `protobuf:"varint,7,opt,name=createTime,proto3" json:"createTime"` - MemberCount uint32 `protobuf:"varint,8,opt,name=memberCount,proto3" json:"memberCount"` - Ex string `protobuf:"bytes,9,opt,name=ex,proto3" json:"ex"` - Status int32 `protobuf:"varint,10,opt,name=status,proto3" json:"status"` - CreatorUserID string `protobuf:"bytes,11,opt,name=creatorUserID,proto3" json:"creatorUserID"` - GroupType int32 `protobuf:"varint,12,opt,name=groupType,proto3" json:"groupType"` - NeedVerification int32 `protobuf:"varint,13,opt,name=needVerification,proto3" json:"needVerification"` - LookMemberInfo int32 `protobuf:"varint,14,opt,name=lookMemberInfo,proto3" json:"lookMemberInfo"` - ApplyMemberFriend int32 `protobuf:"varint,15,opt,name=applyMemberFriend,proto3" json:"applyMemberFriend"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + GroupName string `protobuf:"bytes,2,opt,name=groupName,proto3" json:"groupName"` + Notification string `protobuf:"bytes,3,opt,name=notification,proto3" json:"notification"` + Introduction string `protobuf:"bytes,4,opt,name=introduction,proto3" json:"introduction"` + FaceURL string `protobuf:"bytes,5,opt,name=faceURL,proto3" json:"faceURL"` + OwnerUserID string `protobuf:"bytes,6,opt,name=ownerUserID,proto3" json:"ownerUserID"` + CreateTime int64 `protobuf:"varint,7,opt,name=createTime,proto3" json:"createTime"` + MemberCount uint32 `protobuf:"varint,8,opt,name=memberCount,proto3" json:"memberCount"` + Ex string `protobuf:"bytes,9,opt,name=ex,proto3" json:"ex"` + Status int32 `protobuf:"varint,10,opt,name=status,proto3" json:"status"` + CreatorUserID string `protobuf:"bytes,11,opt,name=creatorUserID,proto3" json:"creatorUserID"` + GroupType int32 `protobuf:"varint,12,opt,name=groupType,proto3" json:"groupType"` + NeedVerification int32 `protobuf:"varint,13,opt,name=needVerification,proto3" json:"needVerification"` + LookMemberInfo int32 `protobuf:"varint,14,opt,name=lookMemberInfo,proto3" json:"lookMemberInfo"` + ApplyMemberFriend int32 `protobuf:"varint,15,opt,name=applyMemberFriend,proto3" json:"applyMemberFriend"` NotificationUpdateTime int64 `protobuf:"varint,16,opt,name=notificationUpdateTime,proto3" json:"notificationUpdateTime"` - NotificationUserID string `protobuf:"bytes,17,opt,name=notificationUserID,proto3" json:"notificationUserID"` + NotificationUserID string `protobuf:"bytes,17,opt,name=notificationUserID,proto3" json:"notificationUserID"` } func (x *GroupInfo) Reset() { @@ -262,14 +264,14 @@ type GroupInfoForSet struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` - GroupName string `protobuf:"bytes,2,opt,name=groupName,proto3" json:"groupName"` - Notification string `protobuf:"bytes,3,opt,name=notification,proto3" json:"notification"` - Introduction string `protobuf:"bytes,4,opt,name=introduction,proto3" json:"introduction"` - FaceURL string `protobuf:"bytes,5,opt,name=faceURL,proto3" json:"faceURL"` - Ex string `protobuf:"bytes,6,opt,name=ex,proto3" json:"ex"` - NeedVerification *wrapperspb.Int32Value `protobuf:"bytes,7,opt,name=needVerification,proto3" json:"needVerification"` - LookMemberInfo *wrapperspb.Int32Value `protobuf:"bytes,8,opt,name=lookMemberInfo,proto3" json:"lookMemberInfo"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + GroupName string `protobuf:"bytes,2,opt,name=groupName,proto3" json:"groupName"` + Notification string `protobuf:"bytes,3,opt,name=notification,proto3" json:"notification"` + Introduction string `protobuf:"bytes,4,opt,name=introduction,proto3" json:"introduction"` + FaceURL string `protobuf:"bytes,5,opt,name=faceURL,proto3" json:"faceURL"` + Ex string `protobuf:"bytes,6,opt,name=ex,proto3" json:"ex"` + NeedVerification *wrapperspb.Int32Value `protobuf:"bytes,7,opt,name=needVerification,proto3" json:"needVerification"` + LookMemberInfo *wrapperspb.Int32Value `protobuf:"bytes,8,opt,name=lookMemberInfo,proto3" json:"lookMemberInfo"` ApplyMemberFriend *wrapperspb.Int32Value `protobuf:"bytes,9,opt,name=applyMemberFriend,proto3" json:"applyMemberFriend"` } @@ -373,18 +375,18 @@ type GroupMemberFullInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` - UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` - RoleLevel int32 `protobuf:"varint,3,opt,name=roleLevel,proto3" json:"roleLevel"` - JoinTime int64 `protobuf:"varint,4,opt,name=joinTime,proto3" json:"joinTime"` - Nickname string `protobuf:"bytes,5,opt,name=nickname,proto3" json:"nickname"` - FaceURL string `protobuf:"bytes,6,opt,name=faceURL,proto3" json:"faceURL"` + GroupID string `protobuf:"bytes,1,opt,name=groupID,proto3" json:"groupID"` + UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` + RoleLevel int32 `protobuf:"varint,3,opt,name=roleLevel,proto3" json:"roleLevel"` + JoinTime int64 `protobuf:"varint,4,opt,name=joinTime,proto3" json:"joinTime"` + Nickname string `protobuf:"bytes,5,opt,name=nickname,proto3" json:"nickname"` + FaceURL string `protobuf:"bytes,6,opt,name=faceURL,proto3" json:"faceURL"` AppMangerLevel int32 `protobuf:"varint,7,opt,name=appMangerLevel,proto3" json:"appMangerLevel"` //if >0 - JoinSource int32 `protobuf:"varint,8,opt,name=joinSource,proto3" json:"joinSource"` - OperatorUserID string `protobuf:"bytes,9,opt,name=operatorUserID,proto3" json:"operatorUserID"` - Ex string `protobuf:"bytes,10,opt,name=ex,proto3" json:"ex"` - MuteEndTime int64 `protobuf:"varint,11,opt,name=muteEndTime,proto3" json:"muteEndTime"` - InviterUserID string `protobuf:"bytes,12,opt,name=inviterUserID,proto3" json:"inviterUserID"` + JoinSource int32 `protobuf:"varint,8,opt,name=joinSource,proto3" json:"joinSource"` + OperatorUserID string `protobuf:"bytes,9,opt,name=operatorUserID,proto3" json:"operatorUserID"` + Ex string `protobuf:"bytes,10,opt,name=ex,proto3" json:"ex"` + MuteEndTime int64 `protobuf:"varint,11,opt,name=muteEndTime,proto3" json:"muteEndTime"` + InviterUserID string `protobuf:"bytes,12,opt,name=inviterUserID,proto3" json:"inviterUserID"` } func (x *GroupMemberFullInfo) Reset() { @@ -508,10 +510,10 @@ type PublicUserInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` Nickname string `protobuf:"bytes,2,opt,name=nickname,proto3" json:"nickname"` - FaceURL string `protobuf:"bytes,3,opt,name=faceURL,proto3" json:"faceURL"` - Ex string `protobuf:"bytes,4,opt,name=ex,proto3" json:"ex"` + FaceURL string `protobuf:"bytes,3,opt,name=faceURL,proto3" json:"faceURL"` + Ex string `protobuf:"bytes,4,opt,name=ex,proto3" json:"ex"` } func (x *PublicUserInfo) Reset() { @@ -579,12 +581,12 @@ type UserInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` - Nickname string `protobuf:"bytes,2,opt,name=nickname,proto3" json:"nickname"` - FaceURL string `protobuf:"bytes,3,opt,name=faceURL,proto3" json:"faceURL"` - Ex string `protobuf:"bytes,4,opt,name=ex,proto3" json:"ex"` - CreateTime int64 `protobuf:"varint,5,opt,name=createTime,proto3" json:"createTime"` - AppMangerLevel int32 `protobuf:"varint,6,opt,name=appMangerLevel,proto3" json:"appMangerLevel"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + Nickname string `protobuf:"bytes,2,opt,name=nickname,proto3" json:"nickname"` + FaceURL string `protobuf:"bytes,3,opt,name=faceURL,proto3" json:"faceURL"` + Ex string `protobuf:"bytes,4,opt,name=ex,proto3" json:"ex"` + CreateTime int64 `protobuf:"varint,5,opt,name=createTime,proto3" json:"createTime"` + AppMangerLevel int32 `protobuf:"varint,6,opt,name=appMangerLevel,proto3" json:"appMangerLevel"` GlobalRecvMsgOpt int32 `protobuf:"varint,7,opt,name=globalRecvMsgOpt,proto3" json:"globalRecvMsgOpt"` } @@ -674,13 +676,13 @@ type FriendInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` - Remark string `protobuf:"bytes,2,opt,name=remark,proto3" json:"remark"` - CreateTime int64 `protobuf:"varint,3,opt,name=createTime,proto3" json:"createTime"` - FriendUser *UserInfo `protobuf:"bytes,4,opt,name=friendUser,proto3" json:"friendUser"` - AddSource int32 `protobuf:"varint,5,opt,name=addSource,proto3" json:"addSource"` + OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` + Remark string `protobuf:"bytes,2,opt,name=remark,proto3" json:"remark"` + CreateTime int64 `protobuf:"varint,3,opt,name=createTime,proto3" json:"createTime"` + FriendUser *UserInfo `protobuf:"bytes,4,opt,name=friendUser,proto3" json:"friendUser"` + AddSource int32 `protobuf:"varint,5,opt,name=addSource,proto3" json:"addSource"` OperatorUserID string `protobuf:"bytes,6,opt,name=operatorUserID,proto3" json:"operatorUserID"` - Ex string `protobuf:"bytes,7,opt,name=ex,proto3" json:"ex"` + Ex string `protobuf:"bytes,7,opt,name=ex,proto3" json:"ex"` } func (x *FriendInfo) Reset() { @@ -769,12 +771,12 @@ type BlackInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` - CreateTime int64 `protobuf:"varint,2,opt,name=createTime,proto3" json:"createTime"` - BlackUserInfo *PublicUserInfo `protobuf:"bytes,3,opt,name=blackUserInfo,proto3" json:"blackUserInfo"` - AddSource int32 `protobuf:"varint,4,opt,name=addSource,proto3" json:"addSource"` + OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` + CreateTime int64 `protobuf:"varint,2,opt,name=createTime,proto3" json:"createTime"` + BlackUserInfo *PublicUserInfo `protobuf:"bytes,3,opt,name=blackUserInfo,proto3" json:"blackUserInfo"` + AddSource int32 `protobuf:"varint,4,opt,name=addSource,proto3" json:"addSource"` OperatorUserID string `protobuf:"bytes,5,opt,name=operatorUserID,proto3" json:"operatorUserID"` - Ex string `protobuf:"bytes,6,opt,name=ex,proto3" json:"ex"` + Ex string `protobuf:"bytes,6,opt,name=ex,proto3" json:"ex"` } func (x *BlackInfo) Reset() { @@ -856,16 +858,16 @@ type GroupRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserInfo *PublicUserInfo `protobuf:"bytes,1,opt,name=userInfo,proto3" json:"userInfo"` - GroupInfo *GroupInfo `protobuf:"bytes,2,opt,name=groupInfo,proto3" json:"groupInfo"` - HandleResult int32 `protobuf:"varint,3,opt,name=handleResult,proto3" json:"handleResult"` - ReqMsg string `protobuf:"bytes,4,opt,name=reqMsg,proto3" json:"reqMsg"` - HandleMsg string `protobuf:"bytes,5,opt,name=handleMsg,proto3" json:"handleMsg"` - ReqTime int64 `protobuf:"varint,6,opt,name=reqTime,proto3" json:"reqTime"` - HandleUserID string `protobuf:"bytes,7,opt,name=handleUserID,proto3" json:"handleUserID"` - HandleTime int64 `protobuf:"varint,8,opt,name=handleTime,proto3" json:"handleTime"` - Ex string `protobuf:"bytes,9,opt,name=ex,proto3" json:"ex"` - JoinSource int32 `protobuf:"varint,10,opt,name=joinSource,proto3" json:"joinSource"` + UserInfo *PublicUserInfo `protobuf:"bytes,1,opt,name=userInfo,proto3" json:"userInfo"` + GroupInfo *GroupInfo `protobuf:"bytes,2,opt,name=groupInfo,proto3" json:"groupInfo"` + HandleResult int32 `protobuf:"varint,3,opt,name=handleResult,proto3" json:"handleResult"` + ReqMsg string `protobuf:"bytes,4,opt,name=reqMsg,proto3" json:"reqMsg"` + HandleMsg string `protobuf:"bytes,5,opt,name=handleMsg,proto3" json:"handleMsg"` + ReqTime int64 `protobuf:"varint,6,opt,name=reqTime,proto3" json:"reqTime"` + HandleUserID string `protobuf:"bytes,7,opt,name=handleUserID,proto3" json:"handleUserID"` + HandleTime int64 `protobuf:"varint,8,opt,name=handleTime,proto3" json:"handleTime"` + Ex string `protobuf:"bytes,9,opt,name=ex,proto3" json:"ex"` + JoinSource int32 `protobuf:"varint,10,opt,name=joinSource,proto3" json:"joinSource"` InviterUserID string `protobuf:"bytes,11,opt,name=inviterUserID,proto3" json:"inviterUserID"` } @@ -983,19 +985,19 @@ type FriendRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - FromUserID string `protobuf:"bytes,1,opt,name=fromUserID,proto3" json:"fromUserID"` - FromNickname string `protobuf:"bytes,2,opt,name=fromNickname,proto3" json:"fromNickname"` - FromFaceURL string `protobuf:"bytes,3,opt,name=fromFaceURL,proto3" json:"fromFaceURL"` - ToUserID string `protobuf:"bytes,4,opt,name=toUserID,proto3" json:"toUserID"` - ToNickname string `protobuf:"bytes,5,opt,name=toNickname,proto3" json:"toNickname"` - ToFaceURL string `protobuf:"bytes,6,opt,name=toFaceURL,proto3" json:"toFaceURL"` - HandleResult int32 `protobuf:"varint,7,opt,name=handleResult,proto3" json:"handleResult"` - ReqMsg string `protobuf:"bytes,8,opt,name=reqMsg,proto3" json:"reqMsg"` - CreateTime int64 `protobuf:"varint,9,opt,name=createTime,proto3" json:"createTime"` + FromUserID string `protobuf:"bytes,1,opt,name=fromUserID,proto3" json:"fromUserID"` + FromNickname string `protobuf:"bytes,2,opt,name=fromNickname,proto3" json:"fromNickname"` + FromFaceURL string `protobuf:"bytes,3,opt,name=fromFaceURL,proto3" json:"fromFaceURL"` + ToUserID string `protobuf:"bytes,4,opt,name=toUserID,proto3" json:"toUserID"` + ToNickname string `protobuf:"bytes,5,opt,name=toNickname,proto3" json:"toNickname"` + ToFaceURL string `protobuf:"bytes,6,opt,name=toFaceURL,proto3" json:"toFaceURL"` + HandleResult int32 `protobuf:"varint,7,opt,name=handleResult,proto3" json:"handleResult"` + ReqMsg string `protobuf:"bytes,8,opt,name=reqMsg,proto3" json:"reqMsg"` + CreateTime int64 `protobuf:"varint,9,opt,name=createTime,proto3" json:"createTime"` HandlerUserID string `protobuf:"bytes,10,opt,name=handlerUserID,proto3" json:"handlerUserID"` - HandleMsg string `protobuf:"bytes,11,opt,name=handleMsg,proto3" json:"handleMsg"` - HandleTime int64 `protobuf:"varint,12,opt,name=handleTime,proto3" json:"handleTime"` - Ex string `protobuf:"bytes,13,opt,name=ex,proto3" json:"ex"` + HandleMsg string `protobuf:"bytes,11,opt,name=handleMsg,proto3" json:"handleMsg"` + HandleTime int64 `protobuf:"varint,12,opt,name=handleTime,proto3" json:"handleTime"` + Ex string `protobuf:"bytes,13,opt,name=ex,proto3" json:"ex"` } func (x *FriendRequest) Reset() { @@ -1126,8 +1128,8 @@ type PullMessageBySeqsReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` - SeqRanges []*SeqRange `protobuf:"bytes,2,rep,name=seqRanges,proto3" json:"seqRanges"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + SeqRanges []*SeqRange `protobuf:"bytes,2,rep,name=seqRanges,proto3" json:"seqRanges"` Order PullOrder `protobuf:"varint,3,opt,name=order,proto3,enum=OpenIMServer.sdkws.PullOrder" json:"order"` } @@ -1190,9 +1192,9 @@ type SeqRange struct { unknownFields protoimpl.UnknownFields ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` - Begin int64 `protobuf:"varint,2,opt,name=begin,proto3" json:"begin"` - End int64 `protobuf:"varint,3,opt,name=end,proto3" json:"end"` - Num int64 `protobuf:"varint,4,opt,name=num,proto3" json:"num"` + Begin int64 `protobuf:"varint,2,opt,name=begin,proto3" json:"begin"` + End int64 `protobuf:"varint,3,opt,name=end,proto3" json:"end"` + Num int64 `protobuf:"varint,4,opt,name=num,proto3" json:"num"` } func (x *SeqRange) Reset() { @@ -1260,7 +1262,7 @@ type PullMsgs struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Msgs []*MsgData `protobuf:"bytes,1,rep,name=Msgs,proto3" json:"Msgs"` + Msgs []*MsgData `protobuf:"bytes,1,rep,name=Msgs,proto3" json:"Msgs"` IsEnd bool `protobuf:"varint,2,opt,name=isEnd,proto3" json:"isEnd"` } @@ -1315,7 +1317,7 @@ type PullMessageBySeqsResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Msgs map[string]*PullMsgs `protobuf:"bytes,1,rep,name=msgs,proto3" json:"msgs" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Msgs map[string]*PullMsgs `protobuf:"bytes,1,rep,name=msgs,proto3" json:"msgs" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` NotificationMsgs map[string]*PullMsgs `protobuf:"bytes,2,rep,name=notificationMsgs,proto3" json:"notificationMsgs" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } @@ -1474,7 +1476,7 @@ type UserSendMsgResp struct { ServerMsgID string `protobuf:"bytes,1,opt,name=serverMsgID,proto3" json:"serverMsgID"` ClientMsgID string `protobuf:"bytes,2,opt,name=clientMsgID,proto3" json:"clientMsgID"` - SendTime int64 `protobuf:"varint,3,opt,name=sendTime,proto3" json:"sendTime"` + SendTime int64 `protobuf:"varint,3,opt,name=sendTime,proto3" json:"sendTime"` } func (x *UserSendMsgResp) Reset() { @@ -1535,28 +1537,28 @@ type MsgData struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - SendID string `protobuf:"bytes,1,opt,name=sendID,proto3" json:"sendID"` - RecvID string `protobuf:"bytes,2,opt,name=recvID,proto3" json:"recvID"` - GroupID string `protobuf:"bytes,3,opt,name=groupID,proto3" json:"groupID"` - ClientMsgID string `protobuf:"bytes,4,opt,name=clientMsgID,proto3" json:"clientMsgID"` - ServerMsgID string `protobuf:"bytes,5,opt,name=serverMsgID,proto3" json:"serverMsgID"` + SendID string `protobuf:"bytes,1,opt,name=sendID,proto3" json:"sendID"` + RecvID string `protobuf:"bytes,2,opt,name=recvID,proto3" json:"recvID"` + GroupID string `protobuf:"bytes,3,opt,name=groupID,proto3" json:"groupID"` + ClientMsgID string `protobuf:"bytes,4,opt,name=clientMsgID,proto3" json:"clientMsgID"` + ServerMsgID string `protobuf:"bytes,5,opt,name=serverMsgID,proto3" json:"serverMsgID"` SenderPlatformID int32 `protobuf:"varint,6,opt,name=senderPlatformID,proto3" json:"senderPlatformID"` - SenderNickname string `protobuf:"bytes,7,opt,name=senderNickname,proto3" json:"senderNickname"` - SenderFaceURL string `protobuf:"bytes,8,opt,name=senderFaceURL,proto3" json:"senderFaceURL"` - SessionType int32 `protobuf:"varint,9,opt,name=sessionType,proto3" json:"sessionType"` - MsgFrom int32 `protobuf:"varint,10,opt,name=msgFrom,proto3" json:"msgFrom"` - ContentType int32 `protobuf:"varint,11,opt,name=contentType,proto3" json:"contentType"` - Content []byte `protobuf:"bytes,12,opt,name=content,proto3" json:"content"` - Seq int64 `protobuf:"varint,14,opt,name=seq,proto3" json:"seq"` - SendTime int64 `protobuf:"varint,15,opt,name=sendTime,proto3" json:"sendTime"` - CreateTime int64 `protobuf:"varint,16,opt,name=createTime,proto3" json:"createTime"` - Status int32 `protobuf:"varint,17,opt,name=status,proto3" json:"status"` - IsRead bool `protobuf:"varint,18,opt,name=isRead,proto3" json:"isRead"` - Options map[string]bool `protobuf:"bytes,19,rep,name=options,proto3" json:"options" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` - OfflinePushInfo *OfflinePushInfo `protobuf:"bytes,20,opt,name=offlinePushInfo,proto3" json:"offlinePushInfo"` - AtUserIDList []string `protobuf:"bytes,21,rep,name=atUserIDList,proto3" json:"atUserIDList"` - AttachedInfo string `protobuf:"bytes,22,opt,name=attachedInfo,proto3" json:"attachedInfo"` - Ex string `protobuf:"bytes,23,opt,name=ex,proto3" json:"ex"` + SenderNickname string `protobuf:"bytes,7,opt,name=senderNickname,proto3" json:"senderNickname"` + SenderFaceURL string `protobuf:"bytes,8,opt,name=senderFaceURL,proto3" json:"senderFaceURL"` + SessionType int32 `protobuf:"varint,9,opt,name=sessionType,proto3" json:"sessionType"` + MsgFrom int32 `protobuf:"varint,10,opt,name=msgFrom,proto3" json:"msgFrom"` + ContentType int32 `protobuf:"varint,11,opt,name=contentType,proto3" json:"contentType"` + Content []byte `protobuf:"bytes,12,opt,name=content,proto3" json:"content"` + Seq int64 `protobuf:"varint,14,opt,name=seq,proto3" json:"seq"` + SendTime int64 `protobuf:"varint,15,opt,name=sendTime,proto3" json:"sendTime"` + CreateTime int64 `protobuf:"varint,16,opt,name=createTime,proto3" json:"createTime"` + Status int32 `protobuf:"varint,17,opt,name=status,proto3" json:"status"` + IsRead bool `protobuf:"varint,18,opt,name=isRead,proto3" json:"isRead"` + Options map[string]bool `protobuf:"bytes,19,rep,name=options,proto3" json:"options" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + OfflinePushInfo *OfflinePushInfo `protobuf:"bytes,20,opt,name=offlinePushInfo,proto3" json:"offlinePushInfo"` + AtUserIDList []string `protobuf:"bytes,21,rep,name=atUserIDList,proto3" json:"atUserIDList"` + AttachedInfo string `protobuf:"bytes,22,opt,name=attachedInfo,proto3" json:"attachedInfo"` + Ex string `protobuf:"bytes,23,opt,name=ex,proto3" json:"ex"` } func (x *MsgData) Reset() { @@ -1750,7 +1752,7 @@ type PushMessages struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Msgs map[string]*PullMsgs `protobuf:"bytes,1,rep,name=msgs,proto3" json:"msgs" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Msgs map[string]*PullMsgs `protobuf:"bytes,1,rep,name=msgs,proto3" json:"msgs" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` NotificationMsgs map[string]*PullMsgs `protobuf:"bytes,2,rep,name=notificationMsgs,proto3" json:"notificationMsgs" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } @@ -1805,12 +1807,12 @@ type OfflinePushInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title"` - Desc string `protobuf:"bytes,2,opt,name=desc,proto3" json:"desc"` - Ex string `protobuf:"bytes,3,opt,name=ex,proto3" json:"ex"` - IOSPushSound string `protobuf:"bytes,4,opt,name=iOSPushSound,proto3" json:"iOSPushSound"` + Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title"` + Desc string `protobuf:"bytes,2,opt,name=desc,proto3" json:"desc"` + Ex string `protobuf:"bytes,3,opt,name=ex,proto3" json:"ex"` + IOSPushSound string `protobuf:"bytes,4,opt,name=iOSPushSound,proto3" json:"iOSPushSound"` IOSBadgeCount bool `protobuf:"varint,5,opt,name=iOSBadgeCount,proto3" json:"iOSBadgeCount"` - SignalInfo string `protobuf:"bytes,6,opt,name=signalInfo,proto3" json:"signalInfo"` + SignalInfo string `protobuf:"bytes,6,opt,name=signalInfo,proto3" json:"signalInfo"` } func (x *OfflinePushInfo) Reset() { @@ -1892,9 +1894,9 @@ type TipsComm struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Detail []byte `protobuf:"bytes,1,opt,name=detail,proto3" json:"detail"` + Detail []byte `protobuf:"bytes,1,opt,name=detail,proto3" json:"detail"` DefaultTips string `protobuf:"bytes,2,opt,name=defaultTips,proto3" json:"defaultTips"` - JsonDetail string `protobuf:"bytes,3,opt,name=jsonDetail,proto3" json:"jsonDetail"` + JsonDetail string `protobuf:"bytes,3,opt,name=jsonDetail,proto3" json:"jsonDetail"` } func (x *TipsComm) Reset() { @@ -1956,9 +1958,9 @@ type GroupCreatedTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` - MemberList []*GroupMemberFullInfo `protobuf:"bytes,3,rep,name=memberList,proto3" json:"memberList"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + MemberList []*GroupMemberFullInfo `protobuf:"bytes,3,rep,name=memberList,proto3" json:"memberList"` OperationTime int64 `protobuf:"varint,4,opt,name=operationTime,proto3" json:"operationTime"` GroupOwnerUser *GroupMemberFullInfo `protobuf:"bytes,5,opt,name=groupOwnerUser,proto3" json:"groupOwnerUser"` } @@ -2036,9 +2038,9 @@ type GroupInfoSetTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OpUser *GroupMemberFullInfo `protobuf:"bytes,1,opt,name=opUser,proto3" json:"opUser"` //who do this + OpUser *GroupMemberFullInfo `protobuf:"bytes,1,opt,name=opUser,proto3" json:"opUser"` //who do this MuteTime int64 `protobuf:"varint,2,opt,name=muteTime,proto3" json:"muteTime"` - Group *GroupInfo `protobuf:"bytes,3,opt,name=group,proto3" json:"group"` + Group *GroupInfo `protobuf:"bytes,3,opt,name=group,proto3" json:"group"` } func (x *GroupInfoSetTips) Reset() { @@ -2100,7 +2102,7 @@ type GroupInfoSetNameTips struct { unknownFields protoimpl.UnknownFields OpUser *GroupMemberFullInfo `protobuf:"bytes,1,opt,name=opUser,proto3" json:"opUser"` //who do this - Group *GroupInfo `protobuf:"bytes,2,opt,name=group,proto3" json:"group"` + Group *GroupInfo `protobuf:"bytes,2,opt,name=group,proto3" json:"group"` } func (x *GroupInfoSetNameTips) Reset() { @@ -2155,7 +2157,7 @@ type GroupInfoSetAnnouncementTips struct { unknownFields protoimpl.UnknownFields OpUser *GroupMemberFullInfo `protobuf:"bytes,1,opt,name=opUser,proto3" json:"opUser"` //who do this - Group *GroupInfo `protobuf:"bytes,2,opt,name=group,proto3" json:"group"` + Group *GroupInfo `protobuf:"bytes,2,opt,name=group,proto3" json:"group"` } func (x *GroupInfoSetAnnouncementTips) Reset() { @@ -2210,9 +2212,9 @@ type JoinGroupApplicationTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` Applicant *PublicUserInfo `protobuf:"bytes,2,opt,name=applicant,proto3" json:"applicant"` - ReqMsg string `protobuf:"bytes,3,opt,name=reqMsg,proto3" json:"reqMsg"` + ReqMsg string `protobuf:"bytes,3,opt,name=reqMsg,proto3" json:"reqMsg"` } func (x *JoinGroupApplicationTips) Reset() { @@ -2276,8 +2278,8 @@ type MemberQuitTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - QuitUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=quitUser,proto3" json:"quitUser"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + QuitUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=quitUser,proto3" json:"quitUser"` OperationTime int64 `protobuf:"varint,3,opt,name=operationTime,proto3" json:"operationTime"` } @@ -2340,9 +2342,9 @@ type GroupApplicationAcceptedTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` - HandleMsg string `protobuf:"bytes,4,opt,name=handleMsg,proto3" json:"handleMsg"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + HandleMsg string `protobuf:"bytes,4,opt,name=handleMsg,proto3" json:"handleMsg"` ReceiverAs int32 `protobuf:"varint,5,opt,name=receiverAs,proto3" json:"receiverAs"` // admin(==1) or applicant(==0) } @@ -2412,9 +2414,9 @@ type GroupApplicationRejectedTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` - HandleMsg string `protobuf:"bytes,4,opt,name=handleMsg,proto3" json:"handleMsg"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + HandleMsg string `protobuf:"bytes,4,opt,name=handleMsg,proto3" json:"handleMsg"` ReceiverAs int32 `protobuf:"varint,5,opt,name=receiverAs,proto3" json:"receiverAs"` // admin(==1) or applicant(==0) } @@ -2484,9 +2486,9 @@ type GroupOwnerTransferredTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` - NewGroupOwner *GroupMemberFullInfo `protobuf:"bytes,3,opt,name=newGroupOwner,proto3" json:"newGroupOwner"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + NewGroupOwner *GroupMemberFullInfo `protobuf:"bytes,3,opt,name=newGroupOwner,proto3" json:"newGroupOwner"` OperationTime int64 `protobuf:"varint,4,opt,name=operationTime,proto3" json:"operationTime"` } @@ -2556,8 +2558,8 @@ type MemberKickedTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` KickedUserList []*GroupMemberFullInfo `protobuf:"bytes,3,rep,name=kickedUserList,proto3" json:"kickedUserList"` OperationTime int64 `protobuf:"varint,4,opt,name=operationTime,proto3" json:"operationTime"` } @@ -2628,10 +2630,10 @@ type MemberInvitedTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` InvitedUserList []*GroupMemberFullInfo `protobuf:"bytes,3,rep,name=invitedUserList,proto3" json:"invitedUserList"` - OperationTime int64 `protobuf:"varint,4,opt,name=operationTime,proto3" json:"operationTime"` + OperationTime int64 `protobuf:"varint,4,opt,name=operationTime,proto3" json:"operationTime"` } func (x *MemberInvitedTips) Reset() { @@ -2700,8 +2702,8 @@ type MemberEnterTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - EntrantUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=entrantUser,proto3" json:"entrantUser"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + EntrantUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=entrantUser,proto3" json:"entrantUser"` OperationTime int64 `protobuf:"varint,3,opt,name=operationTime,proto3" json:"operationTime"` } @@ -2763,8 +2765,8 @@ type GroupDismissedTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` OperationTime int64 `protobuf:"varint,3,opt,name=operationTime,proto3" json:"operationTime"` } @@ -2826,11 +2828,11 @@ type GroupMemberMutedTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` OperationTime int64 `protobuf:"varint,3,opt,name=operationTime,proto3" json:"operationTime"` - MutedUser *GroupMemberFullInfo `protobuf:"bytes,4,opt,name=mutedUser,proto3" json:"mutedUser"` - MutedSeconds uint32 `protobuf:"varint,5,opt,name=mutedSeconds,proto3" json:"mutedSeconds"` + MutedUser *GroupMemberFullInfo `protobuf:"bytes,4,opt,name=mutedUser,proto3" json:"mutedUser"` + MutedSeconds uint32 `protobuf:"varint,5,opt,name=mutedSeconds,proto3" json:"mutedSeconds"` } func (x *GroupMemberMutedTips) Reset() { @@ -2905,10 +2907,10 @@ type GroupMemberCancelMutedTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` OperationTime int64 `protobuf:"varint,3,opt,name=operationTime,proto3" json:"operationTime"` - MutedUser *GroupMemberFullInfo `protobuf:"bytes,4,opt,name=mutedUser,proto3" json:"mutedUser"` + MutedUser *GroupMemberFullInfo `protobuf:"bytes,4,opt,name=mutedUser,proto3" json:"mutedUser"` } func (x *GroupMemberCancelMutedTips) Reset() { @@ -2976,8 +2978,8 @@ type GroupMutedTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` OperationTime int64 `protobuf:"varint,3,opt,name=operationTime,proto3" json:"operationTime"` } @@ -3039,8 +3041,8 @@ type GroupCancelMutedTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` OperationTime int64 `protobuf:"varint,3,opt,name=operationTime,proto3" json:"operationTime"` } @@ -3102,10 +3104,10 @@ type GroupMemberInfoSetTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` - OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` + Group *GroupInfo `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` + OpUser *GroupMemberFullInfo `protobuf:"bytes,2,opt,name=opUser,proto3" json:"opUser"` OperationTime int64 `protobuf:"varint,3,opt,name=operationTime,proto3" json:"operationTime"` - ChangedUser *GroupMemberFullInfo `protobuf:"bytes,4,opt,name=changedUser,proto3" json:"changedUser"` + ChangedUser *GroupMemberFullInfo `protobuf:"bytes,4,opt,name=changedUser,proto3" json:"changedUser"` } func (x *GroupMemberInfoSetTips) Reset() { @@ -3173,8 +3175,8 @@ type FriendApplication struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - AddTime int64 `protobuf:"varint,1,opt,name=addTime,proto3" json:"addTime"` - AddSource string `protobuf:"bytes,2,opt,name=addSource,proto3" json:"addSource"` + AddTime int64 `protobuf:"varint,1,opt,name=addTime,proto3" json:"addTime"` + AddSource string `protobuf:"bytes,2,opt,name=addSource,proto3" json:"addSource"` AddWording string `protobuf:"bytes,3,opt,name=addWording,proto3" json:"addWording"` } @@ -3237,7 +3239,7 @@ type FromToUserID struct { unknownFields protoimpl.UnknownFields FromUserID string `protobuf:"bytes,1,opt,name=fromUserID,proto3" json:"fromUserID"` - ToUserID string `protobuf:"bytes,2,opt,name=toUserID,proto3" json:"toUserID"` + ToUserID string `protobuf:"bytes,2,opt,name=toUserID,proto3" json:"toUserID"` } func (x *FromToUserID) Reset() { @@ -3341,7 +3343,7 @@ type FriendApplicationApprovedTips struct { unknownFields protoimpl.UnknownFields FromToUserID *FromToUserID `protobuf:"bytes,1,opt,name=fromToUserID,proto3" json:"fromToUserID"` //from:同意者;to:请求发起者 - HandleMsg string `protobuf:"bytes,2,opt,name=handleMsg,proto3" json:"handleMsg"` + HandleMsg string `protobuf:"bytes,2,opt,name=handleMsg,proto3" json:"handleMsg"` } func (x *FriendApplicationApprovedTips) Reset() { @@ -3397,7 +3399,7 @@ type FriendApplicationRejectedTips struct { unknownFields protoimpl.UnknownFields FromToUserID *FromToUserID `protobuf:"bytes,1,opt,name=fromToUserID,proto3" json:"fromToUserID"` //from:拒绝者;to:请求发起者 - HandleMsg string `protobuf:"bytes,2,opt,name=handleMsg,proto3" json:"handleMsg"` + HandleMsg string `protobuf:"bytes,2,opt,name=handleMsg,proto3" json:"handleMsg"` } func (x *FriendApplicationRejectedTips) Reset() { @@ -3452,9 +3454,9 @@ type FriendAddedTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Friend *FriendInfo `protobuf:"bytes,1,opt,name=friend,proto3" json:"friend"` + Friend *FriendInfo `protobuf:"bytes,1,opt,name=friend,proto3" json:"friend"` OperationTime int64 `protobuf:"varint,2,opt,name=operationTime,proto3" json:"operationTime"` - OpUser *PublicUserInfo `protobuf:"bytes,3,opt,name=opUser,proto3" json:"opUser"` //who do this + OpUser *PublicUserInfo `protobuf:"bytes,3,opt,name=opUser,proto3" json:"opUser"` //who do this } func (x *FriendAddedTips) Reset() { @@ -3753,7 +3755,7 @@ type ConversationUpdateTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` ConversationIDList []string `protobuf:"bytes,2,rep,name=conversationIDList,proto3" json:"conversationIDList"` } @@ -3808,8 +3810,8 @@ type ConversationSetPrivateTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - RecvID string `protobuf:"bytes,1,opt,name=recvID,proto3" json:"recvID"` - SendID string `protobuf:"bytes,2,opt,name=sendID,proto3" json:"sendID"` + RecvID string `protobuf:"bytes,1,opt,name=recvID,proto3" json:"recvID"` + SendID string `protobuf:"bytes,2,opt,name=sendID,proto3" json:"sendID"` IsPrivate bool `protobuf:"varint,3,opt,name=isPrivate,proto3" json:"isPrivate"` } @@ -3871,9 +3873,9 @@ type ConversationHasReadTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` - ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` - HasReadSeq int64 `protobuf:"varint,3,opt,name=hasReadSeq,proto3" json:"hasReadSeq"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` + HasReadSeq int64 `protobuf:"varint,3,opt,name=hasReadSeq,proto3" json:"hasReadSeq"` UnreadCountTime int64 `protobuf:"varint,4,opt,name=unreadCountTime,proto3" json:"unreadCountTime"` } @@ -4037,8 +4039,8 @@ type DeleteMessageTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OpUserID string `protobuf:"bytes,1,opt,name=opUserID,proto3" json:"opUserID"` - UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` + OpUserID string `protobuf:"bytes,1,opt,name=opUserID,proto3" json:"opUserID"` + UserID string `protobuf:"bytes,2,opt,name=userID,proto3" json:"userID"` Seqs []int64 `protobuf:"varint,3,rep,packed,name=seqs,proto3" json:"seqs"` } @@ -4100,11 +4102,11 @@ type RevokeMsgTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - RevokerUserID string `protobuf:"bytes,1,opt,name=revokerUserID,proto3" json:"revokerUserID"` - ClientMsgID string `protobuf:"bytes,2,opt,name=clientMsgID,proto3" json:"clientMsgID"` - RevokeTime int64 `protobuf:"varint,3,opt,name=revokeTime,proto3" json:"revokeTime"` - SesstionType int32 `protobuf:"varint,5,opt,name=sesstionType,proto3" json:"sesstionType"` - Seq int64 `protobuf:"varint,6,opt,name=seq,proto3" json:"seq"` + RevokerUserID string `protobuf:"bytes,1,opt,name=revokerUserID,proto3" json:"revokerUserID"` + ClientMsgID string `protobuf:"bytes,2,opt,name=clientMsgID,proto3" json:"clientMsgID"` + RevokeTime int64 `protobuf:"varint,3,opt,name=revokeTime,proto3" json:"revokeTime"` + SesstionType int32 `protobuf:"varint,5,opt,name=sesstionType,proto3" json:"sesstionType"` + Seq int64 `protobuf:"varint,6,opt,name=seq,proto3" json:"seq"` ConversationID string `protobuf:"bytes,7,opt,name=conversationID,proto3" json:"conversationID"` } @@ -4187,17 +4189,17 @@ type MessageRevokedContent struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - RevokerID string `protobuf:"bytes,1,opt,name=revokerID,proto3" json:"revokerID"` - RevokerRole int32 `protobuf:"varint,2,opt,name=revokerRole,proto3" json:"revokerRole"` - ClientMsgID string `protobuf:"bytes,3,opt,name=clientMsgID,proto3" json:"clientMsgID"` - RevokerNickname string `protobuf:"bytes,4,opt,name=revokerNickname,proto3" json:"revokerNickname"` - RevokeTime int64 `protobuf:"varint,5,opt,name=revokeTime,proto3" json:"revokeTime"` - SourceMessageSendTime int64 `protobuf:"varint,6,opt,name=sourceMessageSendTime,proto3" json:"sourceMessageSendTime"` - SourceMessageSendID string `protobuf:"bytes,7,opt,name=sourceMessageSendID,proto3" json:"sourceMessageSendID"` + RevokerID string `protobuf:"bytes,1,opt,name=revokerID,proto3" json:"revokerID"` + RevokerRole int32 `protobuf:"varint,2,opt,name=revokerRole,proto3" json:"revokerRole"` + ClientMsgID string `protobuf:"bytes,3,opt,name=clientMsgID,proto3" json:"clientMsgID"` + RevokerNickname string `protobuf:"bytes,4,opt,name=revokerNickname,proto3" json:"revokerNickname"` + RevokeTime int64 `protobuf:"varint,5,opt,name=revokeTime,proto3" json:"revokeTime"` + SourceMessageSendTime int64 `protobuf:"varint,6,opt,name=sourceMessageSendTime,proto3" json:"sourceMessageSendTime"` + SourceMessageSendID string `protobuf:"bytes,7,opt,name=sourceMessageSendID,proto3" json:"sourceMessageSendID"` SourceMessageSenderNickname string `protobuf:"bytes,8,opt,name=sourceMessageSenderNickname,proto3" json:"sourceMessageSenderNickname"` - SessionType int32 `protobuf:"varint,10,opt,name=sessionType,proto3" json:"sessionType"` - Seq int64 `protobuf:"varint,11,opt,name=seq,proto3" json:"seq"` - Ex string `protobuf:"bytes,12,opt,name=ex,proto3" json:"ex"` + SessionType int32 `protobuf:"varint,10,opt,name=sessionType,proto3" json:"sessionType"` + Seq int64 `protobuf:"varint,11,opt,name=seq,proto3" json:"seq"` + Ex string `protobuf:"bytes,12,opt,name=ex,proto3" json:"ex"` } func (x *MessageRevokedContent) Reset() { @@ -4314,7 +4316,7 @@ type ClearConversationTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` ConversationIDs []string `protobuf:"bytes,2,rep,name=conversationIDs,proto3" json:"conversationIDs"` } @@ -4369,9 +4371,9 @@ type DeleteMsgsTips struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` - Seqs []int64 `protobuf:"varint,3,rep,packed,name=seqs,proto3" json:"seqs"` + Seqs []int64 `protobuf:"varint,3,rep,packed,name=seqs,proto3" json:"seqs"` } func (x *DeleteMsgsTips) Reset() { @@ -4433,9 +4435,9 @@ type MarkAsReadTips struct { unknownFields protoimpl.UnknownFields MarkAsReadUserID string `protobuf:"bytes,1,opt,name=markAsReadUserID,proto3" json:"markAsReadUserID"` - ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` - Seqs []int64 `protobuf:"varint,3,rep,packed,name=seqs,proto3" json:"seqs"` - HasReadSeq int64 `protobuf:"varint,4,opt,name=hasReadSeq,proto3" json:"hasReadSeq"` + ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` + Seqs []int64 `protobuf:"varint,3,rep,packed,name=seqs,proto3" json:"seqs"` + HasReadSeq int64 `protobuf:"varint,4,opt,name=hasReadSeq,proto3" json:"hasReadSeq"` } func (x *MarkAsReadTips) Reset() { @@ -4503,7 +4505,7 @@ type SetAppBackgroundStatusReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` IsBackground bool `protobuf:"varint,2,opt,name=isBackground,proto3" json:"isBackground"` } diff --git a/pkg/proto/statistics/statistics.pb.go b/pkg/proto/statistics/statistics.pb.go index 5660758f9..5e03e9797 100644 --- a/pkg/proto/statistics/statistics.pb.go +++ b/pkg/proto/statistics/statistics.pb.go @@ -21,9 +21,10 @@ package statistics import ( + reflect "reflect" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" ) const ( diff --git a/pkg/proto/third/third.pb.go b/pkg/proto/third/third.pb.go index 155b5f7cc..a098b296f 100644 --- a/pkg/proto/third/third.pb.go +++ b/pkg/proto/third/third.pb.go @@ -22,13 +22,14 @@ package third import ( context "context" + reflect "reflect" + sync "sync" + grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" ) const ( @@ -43,7 +44,7 @@ type KeyValues struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key"` Values []string `protobuf:"bytes,2,rep,name=values,proto3" json:"values"` } @@ -99,9 +100,9 @@ type SignPart struct { unknownFields protoimpl.UnknownFields PartNumber int32 `protobuf:"varint,1,opt,name=partNumber,proto3" json:"partNumber"` - Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url"` - Query []*KeyValues `protobuf:"bytes,3,rep,name=query,proto3" json:"query"` - Header []*KeyValues `protobuf:"bytes,4,rep,name=header,proto3" json:"header"` + Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url"` + Query []*KeyValues `protobuf:"bytes,3,rep,name=query,proto3" json:"query"` + Header []*KeyValues `protobuf:"bytes,4,rep,name=header,proto3" json:"header"` } func (x *SignPart) Reset() { @@ -169,10 +170,10 @@ type AuthSignParts struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url"` - Query []*KeyValues `protobuf:"bytes,2,rep,name=query,proto3" json:"query"` + Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url"` + Query []*KeyValues `protobuf:"bytes,2,rep,name=query,proto3" json:"query"` Header []*KeyValues `protobuf:"bytes,3,rep,name=header,proto3" json:"header"` - Parts []*SignPart `protobuf:"bytes,4,rep,name=parts,proto3" json:"parts"` + Parts []*SignPart `protobuf:"bytes,4,rep,name=parts,proto3" json:"parts"` } func (x *AuthSignParts) Reset() { @@ -280,7 +281,7 @@ type PartLimitResp struct { MinPartSize int64 `protobuf:"varint,1,opt,name=minPartSize,proto3" json:"minPartSize"` MaxPartSize int64 `protobuf:"varint,2,opt,name=maxPartSize,proto3" json:"maxPartSize"` - MaxNumSize int32 `protobuf:"varint,3,opt,name=maxNumSize,proto3" json:"maxNumSize"` + MaxNumSize int32 `protobuf:"varint,3,opt,name=maxNumSize,proto3" json:"maxNumSize"` } func (x *PartLimitResp) Reset() { @@ -435,12 +436,12 @@ type InitiateMultipartUploadReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Hash string `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash"` - Size int64 `protobuf:"varint,2,opt,name=size,proto3" json:"size"` - PartSize int64 `protobuf:"varint,3,opt,name=partSize,proto3" json:"partSize"` - MaxParts int32 `protobuf:"varint,4,opt,name=maxParts,proto3" json:"maxParts"` - Cause string `protobuf:"bytes,5,opt,name=cause,proto3" json:"cause"` - Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name"` + Hash string `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash"` + Size int64 `protobuf:"varint,2,opt,name=size,proto3" json:"size"` + PartSize int64 `protobuf:"varint,3,opt,name=partSize,proto3" json:"partSize"` + MaxParts int32 `protobuf:"varint,4,opt,name=maxParts,proto3" json:"maxParts"` + Cause string `protobuf:"bytes,5,opt,name=cause,proto3" json:"cause"` + Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name"` ContentType string `protobuf:"bytes,7,opt,name=contentType,proto3" json:"contentType"` } @@ -530,9 +531,9 @@ type UploadInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UploadID string `protobuf:"bytes,1,opt,name=uploadID,proto3" json:"uploadID"` - PartSize int64 `protobuf:"varint,2,opt,name=partSize,proto3" json:"partSize"` - Sign *AuthSignParts `protobuf:"bytes,3,opt,name=sign,proto3" json:"sign"` + UploadID string `protobuf:"bytes,1,opt,name=uploadID,proto3" json:"uploadID"` + PartSize int64 `protobuf:"varint,2,opt,name=partSize,proto3" json:"partSize"` + Sign *AuthSignParts `protobuf:"bytes,3,opt,name=sign,proto3" json:"sign"` ExpireTime int64 `protobuf:"varint,4,opt,name=expireTime,proto3" json:"expireTime"` } @@ -601,7 +602,7 @@ type InitiateMultipartUploadResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url"` + Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url"` Upload *UploadInfo `protobuf:"bytes,2,opt,name=upload,proto3" json:"upload"` } @@ -656,7 +657,7 @@ type AuthSignReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UploadID string `protobuf:"bytes,1,opt,name=uploadID,proto3" json:"uploadID"` + UploadID string `protobuf:"bytes,1,opt,name=uploadID,proto3" json:"uploadID"` PartNumbers []int32 `protobuf:"varint,2,rep,packed,name=partNumbers,proto3" json:"partNumbers"` } @@ -711,10 +712,10 @@ type AuthSignResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url"` - Query []*KeyValues `protobuf:"bytes,2,rep,name=query,proto3" json:"query"` + Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url"` + Query []*KeyValues `protobuf:"bytes,2,rep,name=query,proto3" json:"query"` Header []*KeyValues `protobuf:"bytes,3,rep,name=header,proto3" json:"header"` - Parts []*SignPart `protobuf:"bytes,4,rep,name=parts,proto3" json:"parts"` + Parts []*SignPart `protobuf:"bytes,4,rep,name=parts,proto3" json:"parts"` } func (x *AuthSignResp) Reset() { @@ -782,11 +783,11 @@ type CompleteMultipartUploadReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UploadID string `protobuf:"bytes,1,opt,name=uploadID,proto3" json:"uploadID"` - Parts []string `protobuf:"bytes,2,rep,name=parts,proto3" json:"parts"` - Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name"` + UploadID string `protobuf:"bytes,1,opt,name=uploadID,proto3" json:"uploadID"` + Parts []string `protobuf:"bytes,2,rep,name=parts,proto3" json:"parts"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name"` ContentType string `protobuf:"bytes,4,opt,name=contentType,proto3" json:"contentType"` - Cause string `protobuf:"bytes,5,opt,name=cause,proto3" json:"cause"` + Cause string `protobuf:"bytes,5,opt,name=cause,proto3" json:"cause"` } func (x *CompleteMultipartUploadReq) Reset() { @@ -955,7 +956,7 @@ type AccessURLResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url"` + Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url"` ExpireTime int64 `protobuf:"varint,2,opt,name=expireTime,proto3" json:"expireTime"` } @@ -1011,8 +1012,8 @@ type FcmUpdateTokenReq struct { unknownFields protoimpl.UnknownFields PlatformID int32 `protobuf:"varint,1,opt,name=platformID,proto3" json:"platformID"` - FcmToken string `protobuf:"bytes,2,opt,name=fcmToken,proto3" json:"fcmToken"` - Account string `protobuf:"bytes,3,opt,name=account,proto3" json:"account"` + FcmToken string `protobuf:"bytes,2,opt,name=fcmToken,proto3" json:"fcmToken"` + Account string `protobuf:"bytes,3,opt,name=account,proto3" json:"account"` ExpireTime int64 `protobuf:"varint,4,opt,name=expireTime,proto3" json:"expireTime"` } @@ -1119,7 +1120,7 @@ type SetAppBadgeReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` AppUnreadCount int32 `protobuf:"varint,2,opt,name=appUnreadCount,proto3" json:"appUnreadCount"` } diff --git a/pkg/proto/user/user.pb.go b/pkg/proto/user/user.pb.go index 5046505db..12a1bd2c8 100644 --- a/pkg/proto/user/user.pb.go +++ b/pkg/proto/user/user.pb.go @@ -22,15 +22,17 @@ package user import ( context "context" - conversation "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/conversation" - sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" + reflect "reflect" + sync "sync" + grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" + + conversation "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/conversation" + sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws" ) const ( @@ -92,7 +94,7 @@ type GetAllUserIDResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Total int32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` + Total int32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` UserIDs []string `protobuf:"bytes,2,rep,name=userIDs,proto3" json:"userIDs"` } @@ -420,7 +422,7 @@ type SetGlobalRecvMessageOptReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` GlobalRecvMsgOpt int32 `protobuf:"varint,3,opt,name=globalRecvMsgOpt,proto3" json:"globalRecvMsgOpt"` } @@ -513,9 +515,9 @@ type SetConversationReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Conversation *conversation.Conversation `protobuf:"bytes,1,opt,name=conversation,proto3" json:"conversation"` + Conversation *conversation.Conversation `protobuf:"bytes,1,opt,name=conversation,proto3" json:"conversation"` NotificationType int32 `protobuf:"varint,2,opt,name=notificationType,proto3" json:"notificationType"` - OperationID string `protobuf:"bytes,3,opt,name=operationID,proto3" json:"operationID"` + OperationID string `protobuf:"bytes,3,opt,name=operationID,proto3" json:"operationID"` } func (x *SetConversationReq) Reset() { @@ -614,11 +616,11 @@ type SetRecvMsgOptReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` - ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` - RecvMsgOpt int32 `protobuf:"varint,3,opt,name=recvMsgOpt,proto3" json:"recvMsgOpt"` + OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` + ConversationID string `protobuf:"bytes,2,opt,name=conversationID,proto3" json:"conversationID"` + RecvMsgOpt int32 `protobuf:"varint,3,opt,name=recvMsgOpt,proto3" json:"recvMsgOpt"` NotificationType int32 `protobuf:"varint,4,opt,name=notificationType,proto3" json:"notificationType"` - OperationID string `protobuf:"bytes,5,opt,name=operationID,proto3" json:"operationID"` + OperationID string `protobuf:"bytes,5,opt,name=operationID,proto3" json:"operationID"` } func (x *SetRecvMsgOptReq) Reset() { @@ -732,8 +734,8 @@ type GetConversationReq struct { unknownFields protoimpl.UnknownFields ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID"` - OwnerUserID string `protobuf:"bytes,2,opt,name=ownerUserID,proto3" json:"ownerUserID"` - OperationID string `protobuf:"bytes,3,opt,name=operationID,proto3" json:"operationID"` + OwnerUserID string `protobuf:"bytes,2,opt,name=ownerUserID,proto3" json:"ownerUserID"` + OperationID string `protobuf:"bytes,3,opt,name=operationID,proto3" json:"operationID"` } func (x *GetConversationReq) Reset() { @@ -841,9 +843,9 @@ type GetConversationsReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` + OwnerUserID string `protobuf:"bytes,1,opt,name=ownerUserID,proto3" json:"ownerUserID"` ConversationIDs []string `protobuf:"bytes,2,rep,name=conversationIDs,proto3" json:"conversationIDs"` - OperationID string `protobuf:"bytes,3,opt,name=operationID,proto3" json:"operationID"` + OperationID string `protobuf:"bytes,3,opt,name=operationID,proto3" json:"operationID"` } func (x *GetConversationsReq) Reset() { @@ -1053,10 +1055,10 @@ type BatchSetConversationsReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Conversations []*conversation.Conversation `protobuf:"bytes,1,rep,name=conversations,proto3" json:"conversations"` - OwnerUserID string `protobuf:"bytes,2,opt,name=OwnerUserID,proto3" json:"OwnerUserID"` + Conversations []*conversation.Conversation `protobuf:"bytes,1,rep,name=conversations,proto3" json:"conversations"` + OwnerUserID string `protobuf:"bytes,2,opt,name=OwnerUserID,proto3" json:"OwnerUserID"` NotificationType int32 `protobuf:"varint,3,opt,name=notificationType,proto3" json:"notificationType"` - OperationID string `protobuf:"bytes,4,opt,name=OperationID,proto3" json:"OperationID"` + OperationID string `protobuf:"bytes,4,opt,name=OperationID,proto3" json:"OperationID"` } func (x *BatchSetConversationsReq) Reset() { @@ -1125,7 +1127,7 @@ type BatchSetConversationsResp struct { unknownFields protoimpl.UnknownFields Success []string `protobuf:"bytes,2,rep,name=Success,proto3" json:"Success"` - Failed []string `protobuf:"bytes,3,rep,name=Failed,proto3" json:"Failed"` + Failed []string `protobuf:"bytes,3,rep,name=Failed,proto3" json:"Failed"` } func (x *BatchSetConversationsResp) Reset() { @@ -1227,7 +1229,7 @@ type GetPaginationUsersResp struct { unknownFields protoimpl.UnknownFields Total int32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` - Users []*sdkws.UserInfo `protobuf:"bytes,2,rep,name=users,proto3" json:"users"` + Users []*sdkws.UserInfo `protobuf:"bytes,2,rep,name=users,proto3" json:"users"` } func (x *GetPaginationUsersResp) Reset() { @@ -1282,7 +1284,7 @@ type UserRegisterReq struct { unknownFields protoimpl.UnknownFields Secret string `protobuf:"bytes,1,opt,name=secret,proto3" json:"secret"` - Users []*sdkws.UserInfo `protobuf:"bytes,2,rep,name=users,proto3" json:"users"` + Users []*sdkws.UserInfo `protobuf:"bytes,2,rep,name=users,proto3" json:"users"` } func (x *UserRegisterReq) Reset() { @@ -1469,7 +1471,7 @@ type UserRegisterCountReq struct { unknownFields protoimpl.UnknownFields Start int64 `protobuf:"varint,1,opt,name=start,proto3" json:"start"` - End int64 `protobuf:"varint,2,opt,name=end,proto3" json:"end"` + End int64 `protobuf:"varint,2,opt,name=end,proto3" json:"end"` } func (x *UserRegisterCountReq) Reset() { @@ -1523,9 +1525,9 @@ type UserRegisterCountResp struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Total int64 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` + Total int64 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` Before int64 `protobuf:"varint,2,opt,name=before,proto3" json:"before"` - Count map[string]int64 `protobuf:"bytes,3,rep,name=count,proto3" json:"count" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + Count map[string]int64 `protobuf:"bytes,3,rep,name=count,proto3" json:"count" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` } func (x *UserRegisterCountResp) Reset() { @@ -1586,7 +1588,7 @@ type AccountCheckRespSingleUserStatus struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID"` AccountStatus string `protobuf:"bytes,2,opt,name=accountStatus,proto3" json:"accountStatus"` } diff --git a/pkg/proto/wrapperspb/wrapperspb.pb.go b/pkg/proto/wrapperspb/wrapperspb.pb.go index 9678bb2a0..c08a87822 100644 --- a/pkg/proto/wrapperspb/wrapperspb.pb.go +++ b/pkg/proto/wrapperspb/wrapperspb.pb.go @@ -21,10 +21,11 @@ package wrapperspb import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( From f99e27c2db90cb3811997dd14e8336c3cec49ae1 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Sun, 23 Jul 2023 11:59:32 +0800 Subject: [PATCH 60/62] fix: changing naming irregularities under pkg and internal packages (#520) --- pkg/common/convert/black.go | 1 + pkg/common/mw/rpc_server_interceptor.go | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pkg/common/convert/black.go b/pkg/common/convert/black.go index ba0e2a5da..f8d69ef29 100644 --- a/pkg/common/convert/black.go +++ b/pkg/common/convert/black.go @@ -54,5 +54,6 @@ func BlackDB2Pb( } blackPbs = append(blackPbs, blackPb) } + return blackPbs, nil } diff --git a/pkg/common/mw/rpc_server_interceptor.go b/pkg/common/mw/rpc_server_interceptor.go index 0dba76103..981f7454d 100644 --- a/pkg/common/mw/rpc_server_interceptor.go +++ b/pkg/common/mw/rpc_server_interceptor.go @@ -110,13 +110,15 @@ func RpcServerInterceptor( } log.ZInfo(ctx, "rpc server req", "funcName", funcName, "req", rpcString(req)) resp, err = func() (interface{}, error) { - if err := checker.Validate(req); err != nil { + if err = checker.Validate(req); err != nil { return nil, err } + return handler(ctx, req) }() if err == nil { log.ZInfo(ctx, "rpc server resp", "funcName", funcName, "resp", rpcString(resp)) + return resp, nil } log.ZError(ctx, "rpc server resp", err, "funcName", funcName) @@ -134,7 +136,7 @@ func RpcServerInterceptor( grpcStatus := status.New(codes.Code(code), codeErr.Msg()) var errInfo *errinfo.ErrorInfo if config.Config.Log.WithStack { - if unwrap != err { + if errors.Is(err, unwrap) { var sti interface{ StackTrace() errors.StackTrace } if errors.As(err, &sti) { log.ZWarn( @@ -172,6 +174,7 @@ func RpcServerInterceptor( details, err := grpcStatus.WithDetails(errInfo) if err != nil { log.ZWarn(ctx, "rpc server resp WithDetails error", err, "funcName", funcName) + return nil, errs.Wrap(err) } log.ZWarn(ctx, "rpc server resp", err, "funcName", funcName) From 6bf4d5d277111c12540579be9182ef3b323a6990 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Sun, 23 Jul 2023 12:05:27 +0800 Subject: [PATCH 61/62] Revert "fix: changing naming irregularities under pkg and internal packages (#520)" This reverts commit e67aed5af59dc44391f8a65b40f169e2aa4b224f. --- pkg/common/convert/black.go | 1 - pkg/common/mw/rpc_server_interceptor.go | 7 ++----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/pkg/common/convert/black.go b/pkg/common/convert/black.go index f8d69ef29..ba0e2a5da 100644 --- a/pkg/common/convert/black.go +++ b/pkg/common/convert/black.go @@ -54,6 +54,5 @@ func BlackDB2Pb( } blackPbs = append(blackPbs, blackPb) } - return blackPbs, nil } diff --git a/pkg/common/mw/rpc_server_interceptor.go b/pkg/common/mw/rpc_server_interceptor.go index 981f7454d..0dba76103 100644 --- a/pkg/common/mw/rpc_server_interceptor.go +++ b/pkg/common/mw/rpc_server_interceptor.go @@ -110,15 +110,13 @@ func RpcServerInterceptor( } log.ZInfo(ctx, "rpc server req", "funcName", funcName, "req", rpcString(req)) resp, err = func() (interface{}, error) { - if err = checker.Validate(req); err != nil { + if err := checker.Validate(req); err != nil { return nil, err } - return handler(ctx, req) }() if err == nil { log.ZInfo(ctx, "rpc server resp", "funcName", funcName, "resp", rpcString(resp)) - return resp, nil } log.ZError(ctx, "rpc server resp", err, "funcName", funcName) @@ -136,7 +134,7 @@ func RpcServerInterceptor( grpcStatus := status.New(codes.Code(code), codeErr.Msg()) var errInfo *errinfo.ErrorInfo if config.Config.Log.WithStack { - if errors.Is(err, unwrap) { + if unwrap != err { var sti interface{ StackTrace() errors.StackTrace } if errors.As(err, &sti) { log.ZWarn( @@ -174,7 +172,6 @@ func RpcServerInterceptor( details, err := grpcStatus.WithDetails(errInfo) if err != nil { log.ZWarn(ctx, "rpc server resp WithDetails error", err, "funcName", funcName) - return nil, errs.Wrap(err) } log.ZWarn(ctx, "rpc server resp", err, "funcName", funcName) From 915a7b9b6414591383812e35da4aabeecc5e0be7 Mon Sep 17 00:00:00 2001 From: BanTanger <88583317+BanTanger@users.noreply.github.com> Date: Sun, 23 Jul 2023 12:05:48 +0800 Subject: [PATCH 62/62] fix: changing naming irregularities under pkg and internal packages Signed-off-by: BanTanger <1290288968@qq.com> --- pkg/common/mw/specialerror/error.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/common/mw/specialerror/error.go b/pkg/common/mw/specialerror/error.go index b843ad0d6..c2c6de0fe 100644 --- a/pkg/common/mw/specialerror/error.go +++ b/pkg/common/mw/specialerror/error.go @@ -16,6 +16,7 @@ package specialerror import ( "errors" + "github.com/OpenIMSDK/Open-IM-Server/pkg/errs" )