feat: fix make lint bugs

Signed-off-by: AllianceTing <2426446427@qq.com>
pull/503/head
AllianceTing 2 years ago
parent 640e26d8ba
commit 0de8d8b1eb

@ -87,7 +87,7 @@ fmt:
vet:
@$(GO) vet ./...
lint: Check syntax and styling of go sources. ✨
##lint: Check syntax and styling of go sources. ✨
.PHONY: lint
lint:
@$(MAKE) go.lint

@ -15,28 +15,32 @@
package api
import (
"github.com/gin-gonic/gin"
"github.com/OpenIMSDK/Open-IM-Server/pkg/a2r"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/auth"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"github.com/gin-gonic/gin"
)
// export AuthApi
type AuthApi rpcclient.Auth
func NewAuthApi(discov discoveryregistry.SvcDiscoveryRegistry) AuthApi {
// export NewAuthAPI
func NewAuthAPI(discov discoveryregistry.SvcDiscoveryRegistry) AuthApi {
return AuthApi(*rpcclient.NewAuth(discov))
}
// export AuthAPI to call UserToken
func (o *AuthApi) UserToken(c *gin.Context) {
a2r.Call(auth.AuthClient.UserToken, o.Client, c)
}
// export AuthAPI to parse Token
func (o *AuthApi) ParseToken(c *gin.Context) {
a2r.Call(auth.AuthClient.ParseToken, o.Client, c)
}
// export AuthAPI to force logout
func (o *AuthApi) ForceLogout(c *gin.Context) {
a2r.Call(auth.AuthClient.ForceLogout, o.Client, c)
}

@ -15,44 +15,52 @@
package api
import (
"github.com/gin-gonic/gin"
"github.com/OpenIMSDK/Open-IM-Server/pkg/a2r"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/conversation"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"github.com/gin-gonic/gin"
)
type ConversationApi rpcclient.Conversation
// export ConversationAPI
type ConversationAPI rpcclient.Conversation
func NewConversationApi(discov discoveryregistry.SvcDiscoveryRegistry) ConversationApi {
return ConversationApi(*rpcclient.NewConversation(discov))
// NewConversationAPI creates a new Conversation
func NewConversationAPI(discov discoveryregistry.SvcDiscoveryRegistry) ConversationAPI {
return ConversationAPI(*rpcclient.NewConversation(discov))
}
func (o *ConversationApi) GetAllConversations(c *gin.Context) {
// get all conversation
func (o *ConversationAPI) GetAllConversations(c *gin.Context) {
a2r.Call(conversation.ConversationClient.GetAllConversations, o.Client, c)
}
func (o *ConversationApi) GetConversation(c *gin.Context) {
// get conversation
func (o *ConversationAPI) GetConversation(c *gin.Context) {
a2r.Call(conversation.ConversationClient.GetConversation, o.Client, c)
}
func (o *ConversationApi) GetConversations(c *gin.Context) {
// getConversations returns a list of conversations.
func (o *ConversationAPI) GetConversations(c *gin.Context) {
a2r.Call(conversation.ConversationClient.GetConversations, o.Client, c)
}
func (o *ConversationApi) BatchSetConversations(c *gin.Context) {
// set list of conversations
func (o *ConversationAPI) BatchSetConversations(c *gin.Context) {
a2r.Call(conversation.ConversationClient.BatchSetConversations, o.Client, c)
}
func (o *ConversationApi) SetRecvMsgOpt(c *gin.Context) {
// setRecvMsgOpt sets the option for receiving messages.
func (o *ConversationAPI) SetRecvMsgOpt(c *gin.Context) {
a2r.Call(conversation.ConversationClient.SetRecvMsgOpt, o.Client, c)
}
func (o *ConversationApi) ModifyConversationField(c *gin.Context) {
// modifyConversationField modifies the conversation field.
func (o *ConversationAPI) ModifyConversationField(c *gin.Context) {
a2r.Call(conversation.ConversationClient.ModifyConversationField, o.Client, c)
}
func (o *ConversationApi) SetConversations(c *gin.Context) {
// set conversations
func (o *ConversationAPI) SetConversations(c *gin.Context) {
a2r.Call(conversation.ConversationClient.SetConversations, o.Client, c)
}

@ -15,11 +15,11 @@
package api
import (
"github.com/go-playground/validator/v10"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/go-playground/validator/v10"
)
// validate input parameters
func RequiredIf(fl validator.FieldLevel) bool {
sessionType := fl.Parent().FieldByName("SessionType").Int()
switch sessionType {

@ -19,60 +19,73 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/friend"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"github.com/gin-gonic/gin"
)
type FriendApi rpcclient.Friend
// type FriendAPI
type FriendAPI rpcclient.Friend
func NewFriendApi(discov discoveryregistry.SvcDiscoveryRegistry) FriendApi {
return FriendApi(*rpcclient.NewFriend(discov))
// NewFriendAPI creates a new friend
func NewFriendAPI(discov discoveryregistry.SvcDiscoveryRegistry) FriendAPI {
return FriendAPI(*rpcclient.NewFriend(discov))
}
func (o *FriendApi) ApplyToAddFriend(c *gin.Context) {
// apply to add a friend
func (o *FriendAPI) ApplyToAddFriend(c *gin.Context) {
a2r.Call(friend.FriendClient.ApplyToAddFriend, o.Client, c)
}
func (o *FriendApi) RespondFriendApply(c *gin.Context) {
// response Friend's apply
func (o *FriendAPI) RespondFriendApply(c *gin.Context) {
a2r.Call(friend.FriendClient.RespondFriendApply, o.Client, c)
}
func (o *FriendApi) DeleteFriend(c *gin.Context) {
// delete a friend
func (o *FriendAPI) DeleteFriend(c *gin.Context) {
a2r.Call(friend.FriendClient.DeleteFriend, o.Client, c)
}
func (o *FriendApi) GetFriendApplyList(c *gin.Context) {
// get friend list
func (o *FriendAPI) GetFriendApplyList(c *gin.Context) {
a2r.Call(friend.FriendClient.GetPaginationFriendsApplyTo, o.Client, c)
}
func (o *FriendApi) GetSelfApplyList(c *gin.Context) {
// get friend self list for apply
func (o *FriendAPI) GetSelfApplyList(c *gin.Context) {
a2r.Call(friend.FriendClient.GetPaginationFriendsApplyFrom, o.Client, c)
}
func (o *FriendApi) GetFriendList(c *gin.Context) {
// get friend list
func (o *FriendAPI) GetFriendList(c *gin.Context) {
a2r.Call(friend.FriendClient.GetPaginationFriends, o.Client, c)
}
func (o *FriendApi) SetFriendRemark(c *gin.Context) {
// set friend remark sign
func (o *FriendAPI) SetFriendRemark(c *gin.Context) {
a2r.Call(friend.FriendClient.SetFriendRemark, o.Client, c)
}
func (o *FriendApi) AddBlack(c *gin.Context) {
// add friend to blacklist
func (o *FriendAPI) AddBlack(c *gin.Context) {
a2r.Call(friend.FriendClient.AddBlack, o.Client, c)
}
func (o *FriendApi) GetPaginationBlacks(c *gin.Context) {
// get balck list with pagenation
func (o *FriendAPI) GetPaginationBlacks(c *gin.Context) {
a2r.Call(friend.FriendClient.GetPaginationBlacks, o.Client, c)
}
func (o *FriendApi) RemoveBlack(c *gin.Context) {
// remove friend from black
func (o *FriendAPI) RemoveBlack(c *gin.Context) {
a2r.Call(friend.FriendClient.RemoveBlack, o.Client, c)
}
func (o *FriendApi) ImportFriends(c *gin.Context) {
// import friends
func (o *FriendAPI) ImportFriends(c *gin.Context) {
a2r.Call(friend.FriendClient.ImportFriends, o.Client, c)
}
func (o *FriendApi) IsFriend(c *gin.Context) {
// judege friend is or not friend
func (o *FriendAPI) IsFriend(c *gin.Context) {
a2r.Call(friend.FriendClient.IsFriend, o.Client, c)
}

@ -19,112 +19,135 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/group"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"github.com/gin-gonic/gin"
)
type GroupApi rpcclient.Group
// newgroupapi creates a new group
func NewGroupApi(discov discoveryregistry.SvcDiscoveryRegistry) GroupApi {
return GroupApi(*rpcclient.NewGroup(discov))
}
// create a new group
func (o *GroupApi) CreateGroup(c *gin.Context) {
a2r.Call(group.GroupClient.CreateGroup, o.Client, c)
}
// set group info
func (o *GroupApi) SetGroupInfo(c *gin.Context) {
a2r.Call(group.GroupClient.SetGroupInfo, o.Client, c)
}
// take into group
func (o *GroupApi) JoinGroup(c *gin.Context) {
a2r.Call(group.GroupClient.JoinGroup, o.Client, c)
}
// quit group
func (o *GroupApi) QuitGroup(c *gin.Context) {
a2r.Call(group.GroupClient.QuitGroup, o.Client, c)
}
// call group application response
func (o *GroupApi) ApplicationGroupResponse(c *gin.Context) {
a2r.Call(group.GroupClient.GroupApplicationResponse, o.Client, c)
}
// transfer group owner
func (o *GroupApi) TransferGroupOwner(c *gin.Context) {
a2r.Call(group.GroupClient.TransferGroupOwner, o.Client, c)
}
// get group application list
func (o *GroupApi) GetRecvGroupApplicationList(c *gin.Context) {
a2r.Call(group.GroupClient.GetGroupApplicationList, o.Client, c)
}
// get user group list request
func (o *GroupApi) GetUserReqGroupApplicationList(c *gin.Context) {
a2r.Call(group.GroupClient.GetUserReqApplicationList, o.Client, c)
}
// get group infomation
func (o *GroupApi) GetGroupsInfo(c *gin.Context) {
a2r.Call(group.GroupClient.GetGroupsInfo, o.Client, c)
}
// kick user out of group
func (o *GroupApi) KickGroupMember(c *gin.Context) {
a2r.Call(group.GroupClient.KickGroupMember, o.Client, c)
}
// get user info from group
func (o *GroupApi) GetGroupMembersInfo(c *gin.Context) {
a2r.Call(group.GroupClient.GetGroupMembersInfo, o.Client, c)
}
// get user list info from group
func (o *GroupApi) GetGroupMemberList(c *gin.Context) {
a2r.Call(group.GroupClient.GetGroupMemberList, o.Client, c)
}
// invite user to join group
func (o *GroupApi) InviteUserToGroup(c *gin.Context) {
a2r.Call(group.GroupClient.InviteUserToGroup, o.Client, c)
}
// get group list user joined
func (o *GroupApi) GetJoinedGroupList(c *gin.Context) {
a2r.Call(group.GroupClient.GetJoinedGroupList, o.Client, c)
}
// dismiss group
func (o *GroupApi) DismissGroup(c *gin.Context) {
a2r.Call(group.GroupClient.DismissGroup, o.Client, c)
}
// mute group member
func (o *GroupApi) MuteGroupMember(c *gin.Context) {
a2r.Call(group.GroupClient.MuteGroupMember, o.Client, c)
}
// cancel mute group member
func (o *GroupApi) CancelMuteGroupMember(c *gin.Context) {
a2r.Call(group.GroupClient.CancelMuteGroupMember, o.Client, c)
}
// mute group
func (o *GroupApi) MuteGroup(c *gin.Context) {
a2r.Call(group.GroupClient.MuteGroup, o.Client, c)
}
// cancel mute group
func (o *GroupApi) CancelMuteGroup(c *gin.Context) {
a2r.Call(group.GroupClient.CancelMuteGroup, o.Client, c)
}
// set group member info
func (o *GroupApi) SetGroupMemberInfo(c *gin.Context) {
a2r.Call(group.GroupClient.SetGroupMemberInfo, o.Client, c)
}
// get group abstract info
func (o *GroupApi) GetGroupAbstractInfo(c *gin.Context) {
a2r.Call(group.GroupClient.GetGroupAbstractInfo, o.Client, c)
}
//func (g *Group) SetGroupMemberNickname(c *gin.Context) {
// a2r.Call(group.GroupClient.SetGroupMemberNickname, g.userClient, c)
//}
// func (g *Group) SetGroupMemberNickname(c *gin.Context) {
// a2r.Call(group.GroupClient.SetGroupMemberNickname, g.userClient, c)
// }
//
//func (g *Group) GetGroupAllMemberList(c *gin.Context) {
// a2r.Call(group.GroupClient.GetGroupAllMember, g.userClient, c)
//}
// func (g *Group) GetGroupAllMemberList(c *gin.Context) {
// a2r.Call(group.GroupClient.GetGroupAllMember, g.userClient, c)
// }
//
// get joinde super group list
func (o *GroupApi) GetJoinedSuperGroupList(c *gin.Context) {
a2r.Call(group.GroupClient.GetJoinedSuperGroupList, o.Client, c)
}
// get super group info
func (o *GroupApi) GetSuperGroupsInfo(c *gin.Context) {
a2r.Call(group.GroupClient.GetSuperGroupsInfo, o.Client, c)
}

@ -15,11 +15,6 @@
package api
import (
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"github.com/mitchellh/mapstructure"
"google.golang.org/protobuf/proto"
"github.com/OpenIMSDK/Open-IM-Server/pkg/a2r"
"github.com/OpenIMSDK/Open-IM-Server/pkg/apiresp"
"github.com/OpenIMSDK/Open-IM-Server/pkg/apistruct"
@ -31,17 +26,24 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"github.com/mitchellh/mapstructure"
"google.golang.org/protobuf/proto"
)
// type a message api struct
type MessageApi struct {
rpcclient.Message
validate *validator.Validate
}
// newMessageApi returns a new MessageApi.
func NewMessageApi(discov discoveryregistry.SvcDiscoveryRegistry) MessageApi {
return MessageApi{Message: *rpcclient.NewMessage(discov), validate: validator.New()}
}
// set options.
func (MessageApi) SetOptions(options map[string]bool, value bool) {
utils.SetSwitchFromOptions(options, constant.IsHistory, value)
utils.SetSwitchFromOptions(options, constant.IsPersistent, value)
@ -49,6 +51,7 @@ func (MessageApi) SetOptions(options map[string]bool, value bool) {
utils.SetSwitchFromOptions(options, constant.IsConversationUpdate, value)
}
// create a new user send message request.
func (m MessageApi) newUserSendMsgReq(c *gin.Context, params *apistruct.ManagementSendMsgReq) *msg.SendMsgReq {
var newContent string
var err error
@ -114,70 +117,87 @@ func (m MessageApi) newUserSendMsgReq(c *gin.Context, params *apistruct.Manageme
return &pbData
}
// get max seq.
func (m *MessageApi) GetSeq(c *gin.Context) {
a2r.Call(msg.MsgClient.GetMaxSeq, m.Client, c)
}
// pull message by seqs.
func (m *MessageApi) PullMsgBySeqs(c *gin.Context) {
a2r.Call(msg.MsgClient.PullMessageBySeqs, m.Client, c)
}
// revoke message.
func (m *MessageApi) RevokeMsg(c *gin.Context) {
a2r.Call(msg.MsgClient.RevokeMsg, m.Client, c)
}
// mark msgs as read.
func (m *MessageApi) MarkMsgsAsRead(c *gin.Context) {
a2r.Call(msg.MsgClient.MarkMsgsAsRead, m.Client, c)
}
// mark conversations as read.
func (m *MessageApi) MarkConversationAsRead(c *gin.Context) {
a2r.Call(msg.MsgClient.MarkConversationAsRead, m.Client, c)
}
// get conversations which has read and max seq.
func (m *MessageApi) GetConversationsHasReadAndMaxSeq(c *gin.Context) {
a2r.Call(msg.MsgClient.GetConversationsHasReadAndMaxSeq, m.Client, c)
}
// set conversations which has read and max seq
func (m *MessageApi) SetConversationHasReadSeq(c *gin.Context) {
a2r.Call(msg.MsgClient.SetConversationHasReadSeq, m.Client, c)
}
// clear conversation message
func (m *MessageApi) ClearConversationsMsg(c *gin.Context) {
a2r.Call(msg.MsgClient.ClearConversationsMsg, m.Client, c)
}
// clear all message about user
func (m *MessageApi) UserClearAllMsg(c *gin.Context) {
a2r.Call(msg.MsgClient.UserClearAllMsg, m.Client, c)
}
// delete message
func (m *MessageApi) DeleteMsgs(c *gin.Context) {
a2r.Call(msg.MsgClient.DeleteMsgs, m.Client, c)
}
// delete message form disk by seq
func (m *MessageApi) DeleteMsgPhysicalBySeq(c *gin.Context) {
a2r.Call(msg.MsgClient.DeleteMsgPhysicalBySeq, m.Client, c)
}
// delete msg from disk
func (m *MessageApi) DeleteMsgPhysical(c *gin.Context) {
a2r.Call(msg.MsgClient.DeleteMsgPhysical, m.Client, c)
}
// set message reaction extension
func (m *MessageApi) SetMessageReactionExtensions(c *gin.Context) {
a2r.Call(msg.MsgClient.SetMessageReactionExtensions, m.Client, c)
}
// get message list reaction extension
func (m *MessageApi) GetMessageListReactionExtensions(c *gin.Context) {
a2r.Call(msg.MsgClient.GetMessagesReactionExtensions, m.Client, c)
}
// add message reaction extension
func (m *MessageApi) AddMessageReactionExtensions(c *gin.Context) {
a2r.Call(msg.MsgClient.AddMessageReactionExtensions, m.Client, c)
}
// delete message reaction extension
func (m *MessageApi) DeleteMessageReactionExtensions(c *gin.Context) {
a2r.Call(msg.MsgClient.DeleteMessageReactionExtensions, m.Client, c)
}
// send message
func (m *MessageApi) SendMessage(c *gin.Context) {
params := apistruct.ManagementSendMsgReq{}
if err := c.BindJSON(&params); err != nil {
@ -185,7 +205,7 @@ func (m *MessageApi) SendMessage(c *gin.Context) {
return
}
// todo
//if !tokenverify.IsAppManagerUid(c) {
// if !tokenverify.IsAppManagerUid(c) {
// apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
// return
//}
@ -242,14 +262,17 @@ func (m *MessageApi) SendMessage(c *gin.Context) {
apiresp.GinSuccess(c, respPb)
}
// manage send message batch
func (m *MessageApi) ManagementBatchSendMsg(c *gin.Context) {
a2r.Call(msg.MsgClient.SendMsg, m.Client, c)
}
// check message send is or not success
func (m *MessageApi) CheckMsgIsSendSuccess(c *gin.Context) {
a2r.Call(msg.MsgClient.GetSendMsgStatus, m.Client, c)
}
// get user online status
func (m *MessageApi) GetUsersOnlineStatus(c *gin.Context) {
a2r.Call(msg.MsgClient.GetSendMsgStatus, m.Client, c)
}

@ -17,18 +17,17 @@ package api
import (
"context"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mw"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/prome"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"github.com/go-playground/validator/v10"
"github.com/redis/go-redis/v9"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mw"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/prome"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
)
func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.UniversalClient) *gin.Engine {
@ -60,7 +59,7 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
userRouterGroup.POST("/get_users", ParseToken, u.GetUsers)
userRouterGroup.POST("/get_users_online_status", ParseToken, u.GetUsersOnlineStatus)
}
//friend routing group
// friend routing group
friendRouterGroup := r.Group("/friend", ParseToken)
{
f := NewFriendApi(discov)
@ -107,7 +106,7 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
superGroupRouterGroup.POST("/get_joined_group_list", g.GetJoinedSuperGroupList)
superGroupRouterGroup.POST("/get_groups_info", g.GetSuperGroupsInfo)
}
//certificate
// certificate
authRouterGroup := r.Group("/auth")
{
a := NewAuthApi(discov)
@ -116,7 +115,7 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
authRouterGroup.POST("/parse_token", a.ParseToken)
authRouterGroup.POST("/force_logout", ParseToken, a.ForceLogout)
}
//Third service
// Third service
thirdGroup := r.Group("/third", ParseToken)
{
t := NewThirdApi(discov)
@ -130,7 +129,7 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
thirdGroup.POST("/object", t.GetURL)
thirdGroup.GET("/object", t.GetURL)
}
//Message
// Message
msgGroup := r.Group("/msg", ParseToken)
{
m := NewMessageApi(discov)
@ -152,7 +151,7 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
msgGroup.POST("/batch_send_msg", m.ManagementBatchSendMsg)
msgGroup.POST("/check_msg_is_send_success", m.CheckMsgIsSendSuccess)
}
//Conversation
// Conversation
conversationGroup := r.Group("/conversation", ParseToken)
{
c := NewConversationApi(discov)

@ -15,20 +15,22 @@
package api
import (
"github.com/gin-gonic/gin"
"github.com/OpenIMSDK/Open-IM-Server/pkg/a2r"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/user"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"github.com/gin-gonic/gin"
)
// define a statistic api
type StatisticsApi rpcclient.User
// create a new statistics api
func NewStatisticsApi(discov discoveryregistry.SvcDiscoveryRegistry) StatisticsApi {
return StatisticsApi(*rpcclient.NewUser(discov))
}
// user registry
func (s *StatisticsApi) UserRegister(c *gin.Context) {
a2r.Call(user.UserClient.UserRegisterCount, s.Client, c)
}

@ -19,8 +19,6 @@ import (
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"github.com/OpenIMSDK/Open-IM-Server/pkg/a2r"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
@ -28,26 +26,32 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/third"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"github.com/gin-gonic/gin"
)
type ThirdApi rpcclient.Third
// create a new third api
func NewThirdApi(discov discoveryregistry.SvcDiscoveryRegistry) ThirdApi {
return ThirdApi(*rpcclient.NewThird(discov))
}
// apply put
func (o *ThirdApi) ApplyPut(c *gin.Context) {
a2r.Call(third.ThirdClient.ApplyPut, o.Client, c)
}
// het put
func (o *ThirdApi) GetPut(c *gin.Context) {
a2r.Call(third.ThirdClient.GetPut, o.Client, c)
}
// confirm put
func (o *ThirdApi) ConfirmPut(c *gin.Context) {
a2r.Call(third.ThirdClient.ConfirmPut, o.Client, c)
}
// get hash code
func (o *ThirdApi) GetHash(c *gin.Context) {
a2r.Call(third.ThirdClient.GetHashInfo, o.Client, c)
}

@ -18,8 +18,6 @@ import (
"context"
"encoding/json"
"github.com/Shopify/sarama"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller"
@ -30,10 +28,11 @@ import (
pbMsg "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"github.com/Shopify/sarama"
"google.golang.org/protobuf/proto"
)
// define a ModifyMsgConsumerHandler struct
type ModifyMsgConsumerHandler struct {
modifyMsgConsumerGroup *kfk.MConsumerGroup
@ -41,6 +40,7 @@ type ModifyMsgConsumerHandler struct {
extendSetMsgModel unRelationTb.ExtendMsgSetModel
}
// create a new ModifyMsgConsumerHandler
func NewModifyMsgConsumerHandler(database controller.ExtendMsgDatabase) *ModifyMsgConsumerHandler {
return &ModifyMsgConsumerHandler{
modifyMsgConsumerGroup: kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{KafkaVersion: sarama.V2_0_0_0,
@ -50,8 +50,13 @@ func NewModifyMsgConsumerHandler(database controller.ExtendMsgDatabase) *ModifyM
}
}
func (ModifyMsgConsumerHandler) Setup(_ sarama.ConsumerGroupSession) error { return nil }
// setup
func (ModifyMsgConsumerHandler) Setup(_ sarama.ConsumerGroupSession) error { return nil }
// clean up
func (ModifyMsgConsumerHandler) Cleanup(_ sarama.ConsumerGroupSession) error { return nil }
// consume claim
func (mmc *ModifyMsgConsumerHandler) ConsumeClaim(sess sarama.ConsumerGroupSession,
claim sarama.ConsumerGroupClaim) error {
for msg := range claim.Messages() {
@ -78,6 +83,7 @@ func (mmc *ModifyMsgConsumerHandler) ConsumeClaim(sess sarama.ConsumerGroupSessi
return nil
}
// modify message
func (mmc *ModifyMsgConsumerHandler) ModifyMsg(
ctx context.Context,
cMsg *sarama.ConsumerMessage,

@ -21,21 +21,19 @@ import (
"sync"
"time"
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
"github.com/Shopify/sarama"
"github.com/go-redis/redis"
"google.golang.org/protobuf/proto"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/kafka"
"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/errs"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"github.com/Shopify/sarama"
"github.com/go-redis/redis"
"google.golang.org/protobuf/proto"
)
const ConsumerMsgs = 3
@ -63,6 +61,7 @@ type ContextMsg struct {
ctx context.Context
}
// define a OnlineHistoryRedisConsumerHandler struct
type OnlineHistoryRedisConsumerHandler struct {
historyConsumerGroup *kafka.MConsumerGroup
chArrays [ChannelNum]chan Cmd2Value
@ -120,7 +119,8 @@ func (och *OnlineHistoryRedisConsumerHandler) Run(channelID int) {
"uniqueKey",
msgChannelValue.uniqueKey,
)
storageMsgList, notStorageMsgList, storageNotificationList, notStorageNotificationList, modifyMsgList := och.getPushStorageMsgList(
storageMsgList, notStorageMsgList, storageNotificationList,
notStorageNotificationList, modifyMsgList := och.getPushStorageMsgList(
ctxMsgList,
)
log.ZDebug(
@ -147,7 +147,8 @@ func (och *OnlineHistoryRedisConsumerHandler) Run(channelID int) {
storageNotificationList,
notStorageNotificationList,
)
if err := och.msgDatabase.MsgToModifyMQ(ctx, msgChannelValue.uniqueKey, conversationIDNotification, modifyMsgList); err != nil {
if err := och.msgDatabase.MsgToModifyMQ(ctx, msgChannelValue.uniqueKey,
conversationIDNotification, modifyMsgList); err != nil {
log.ZError(
ctx,
"msg to modify mq error",
@ -302,6 +303,7 @@ func (och *OnlineHistoryRedisConsumerHandler) handleMsg(
}
}
// MessagesDistributionHandle
func (och *OnlineHistoryRedisConsumerHandler) MessagesDistributionHandle() {
for {
aggregationMsgs := make(map[string][]*ContextMsg, ChannelNum)
@ -378,6 +380,8 @@ func (och *OnlineHistoryRedisConsumerHandler) MessagesDistributionHandle() {
}
}
}
// withAggregationCtx
func withAggregationCtx(ctx context.Context, values []*ContextMsg) context.Context {
var allMessageOperationID string
for i, v := range values {
@ -393,11 +397,15 @@ func withAggregationCtx(ctx context.Context, values []*ContextMsg) context.Conte
return mcontext.SetOperationID(ctx, allMessageOperationID)
}
// setup
func (och *OnlineHistoryRedisConsumerHandler) Setup(_ sarama.ConsumerGroupSession) error { return nil }
// clean up
func (och *OnlineHistoryRedisConsumerHandler) Cleanup(_ sarama.ConsumerGroupSession) error {
return nil
}
// consume claim
func (och *OnlineHistoryRedisConsumerHandler) ConsumeClaim(
sess sarama.ConsumerGroupSession,
claim sarama.ConsumerGroupClaim,

@ -17,21 +17,22 @@ package msgtransfer
import (
"context"
"github.com/Shopify/sarama"
"google.golang.org/protobuf/proto"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller"
kfk "github.com/OpenIMSDK/Open-IM-Server/pkg/common/kafka"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
pbMsg "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
"github.com/Shopify/sarama"
"google.golang.org/protobuf/proto"
)
// define a OnlineHistoryMongoConsumerHandler struct
type OnlineHistoryMongoConsumerHandler struct {
historyConsumerGroup *kfk.MConsumerGroup
msgDatabase controller.CommonMsgDatabase
}
// create a NewOnlineHistoryMongoConsumerHandler
func NewOnlineHistoryMongoConsumerHandler(database controller.CommonMsgDatabase) *OnlineHistoryMongoConsumerHandler {
mc := &OnlineHistoryMongoConsumerHandler{
historyConsumerGroup: kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{KafkaVersion: sarama.V2_0_0_0,
@ -42,6 +43,7 @@ func NewOnlineHistoryMongoConsumerHandler(database controller.CommonMsgDatabase)
return mc
}
// create a handleChatWs2Mongo
func (mc *OnlineHistoryMongoConsumerHandler) handleChatWs2Mongo(
ctx context.Context,
cMsg *sarama.ConsumerMessage,
@ -91,9 +93,13 @@ func (mc *OnlineHistoryMongoConsumerHandler) handleChatWs2Mongo(
mc.msgDatabase.DelUserDeleteMsgsList(ctx, msgFromMQ.ConversationID, seqs)
}
func (OnlineHistoryMongoConsumerHandler) Setup(_ sarama.ConsumerGroupSession) error { return nil }
// setup
func (OnlineHistoryMongoConsumerHandler) Setup(_ sarama.ConsumerGroupSession) error { return nil }
// clean up
func (OnlineHistoryMongoConsumerHandler) Cleanup(_ sarama.ConsumerGroupSession) error { return nil }
// consume claim
func (mc *OnlineHistoryMongoConsumerHandler) ConsumeClaim(
sess sarama.ConsumerGroupSession,
claim sarama.ConsumerGroupClaim,

@ -17,13 +17,12 @@ package msg
import (
"context"
"github.com/redis/go-redis/v9"
"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/errs"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
"github.com/redis/go-redis/v9"
)
func (m *msgServer) GetConversationsHasReadAndMaxSeq(
@ -76,10 +75,11 @@ func (m *msgServer) SetConversationHasReadSeq(
if req.HasReadSeq > maxSeq {
return nil, errs.ErrArgs.Wrap("hasReadSeq must not be bigger than maxSeq")
}
if err := m.MsgDatabase.SetHasReadSeq(ctx, req.UserID, req.ConversationID, req.HasReadSeq); err != nil {
return nil, err
if err1 := m.MsgDatabase.SetHasReadSeq(ctx, req.UserID, req.ConversationID, req.HasReadSeq); err != nil {
return nil, err1
}
if err = m.sendMarkAsReadNotification(ctx, req.ConversationID, constant.SingleChatType, req.UserID, req.UserID, nil, req.HasReadSeq); err != nil {
if err = m.sendMarkAsReadNotification(ctx, req.ConversationID, constant.SingleChatType,
req.UserID, req.UserID, nil, req.HasReadSeq); err != nil {
return
}
return &msg.SetConversationHasReadSeqResp{}, nil
@ -117,7 +117,8 @@ func (m *msgServer) MarkMsgsAsRead(
return
}
}
if err = m.sendMarkAsReadNotification(ctx, req.ConversationID, conversation.ConversationType, req.UserID, m.conversationAndGetRecvID(conversation, req.UserID), req.Seqs, hasReadSeq); err != nil {
if err = m.sendMarkAsReadNotification(ctx, req.ConversationID, conversation.ConversationType, req.UserID,
m.conversationAndGetRecvID(conversation, req.UserID), req.Seqs, hasReadSeq); err != nil {
return
}
return &msg.MarkMsgsAsReadResp{}, nil
@ -147,17 +148,18 @@ func (m *msgServer) MarkConversationAsRead(
if len(seqs) > 0 {
log.ZDebug(ctx, "MarkConversationAsRead", "seqs", seqs, "conversationID", req.ConversationID)
if err = m.MsgDatabase.MarkSingleChatMsgsAsRead(ctx, req.UserID, req.ConversationID, seqs); err != nil {
return
return resp, err
}
}
if req.HasReadSeq > hasReadSeq {
err = m.MsgDatabase.SetHasReadSeq(ctx, req.UserID, req.ConversationID, req.HasReadSeq)
if err != nil {
return
return resp, err
}
hasReadSeq = req.HasReadSeq
}
if err = m.sendMarkAsReadNotification(ctx, req.ConversationID, conversation.ConversationType, req.UserID, m.conversationAndGetRecvID(conversation, req.UserID), seqs, hasReadSeq); err != nil {
if err = m.sendMarkAsReadNotification(ctx, req.ConversationID, conversation.ConversationType, req.UserID,
m.conversationAndGetRecvID(conversation, req.UserID), seqs, hasReadSeq); err != nil {
return
}
return &msg.MarkConversationAsReadResp{}, nil

@ -63,7 +63,8 @@ func callbackBeforeSendSingleMsg(ctx context.Context, msg *pbChat.SendMsgReq) er
RecvID: msg.MsgData.RecvID,
}
resp := &cbapi.CallbackBeforeSendSingleMsgResp{}
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackBeforeSendSingleMsg); err != nil {
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp,
config.Config.Callback.CallbackBeforeSendSingleMsg); err != nil {
if err == errs.ErrCallbackContinue {
return nil
}
@ -81,7 +82,8 @@ func callbackAfterSendSingleMsg(ctx context.Context, msg *pbChat.SendMsgReq) err
RecvID: msg.MsgData.RecvID,
}
resp := &cbapi.CallbackAfterSendSingleMsgResp{}
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackAfterSendSingleMsg); err != nil {
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp,
config.Config.Callback.CallbackAfterSendSingleMsg); err != nil {
if err == errs.ErrCallbackContinue {
return nil
}
@ -99,7 +101,8 @@ func callbackBeforeSendGroupMsg(ctx context.Context, msg *pbChat.SendMsgReq) err
GroupID: msg.MsgData.GroupID,
}
resp := &cbapi.CallbackBeforeSendGroupMsgResp{}
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackBeforeSendGroupMsg); err != nil {
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp,
config.Config.Callback.CallbackBeforeSendGroupMsg); err != nil {
if err == errs.ErrCallbackContinue {
return nil
}
@ -117,7 +120,8 @@ func callbackAfterSendGroupMsg(ctx context.Context, msg *pbChat.SendMsgReq) erro
GroupID: msg.MsgData.GroupID,
}
resp := &cbapi.CallbackAfterSendGroupMsgResp{}
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackAfterSendGroupMsg); err != nil {
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp,
config.Config.Callback.CallbackAfterSendGroupMsg); err != nil {
if err == errs.ErrCallbackContinue {
return nil
}

@ -152,8 +152,8 @@ func (m *msgServer) clearConversation(
if err != nil {
return err
}
var existConversations []*conversation.Conversation
var existConversationIDs []string
var existConversations = make([]*conversation.Conversation, 0, 100)
var existConversationIDs = make([]string, 0, 100)
for _, conversation := range conversations {
existConversations = append(existConversations, conversation)
existConversationIDs = append(existConversationIDs, conversation.ConversationID)

@ -158,7 +158,6 @@ func (m *msgServer) SetMessageReactionExtensions(
//}
//log.Debug(req.OperationID, utils.GetSelfFuncName(), "m return is:", resp.String())
return resp, nil
}
func (m *msgServer) setKeyResultInfo(
@ -195,14 +194,14 @@ func (m *msgServer) GetMessagesReactionExtensions(
ctx context.Context,
req *msg.GetMessagesReactionExtensionsReq,
) (resp *msg.GetMessagesReactionExtensionsResp, err error) {
//log.Debug(req.OperationID, utils.GetSelfFuncName(), "m args is:", req.String())
//var rResp msg.GetMessageListReactionExtensionsResp
//for _, messageValue := range req.MessageReactionKeyList {
// var oneMessage msg.SingleMessageExtensionResult
// oneMessage.ClientMsgID = messageValue.ClientMsgID
// log.Debug(req.OperationID, utils.GetSelfFuncName(), "m args is:", req.String())
// var rResp msg.GetMessageListReactionExtensionsResp
// for _, messageValue := range req.MessageReactionKeyList {
// var oneMessage msg.SingleMessageExtensionResult
// oneMessage.ClientMsgID = messageValue.ClientMsgID
//
// isExists, err := db.DB.JudgeMessageReactionExist(messageValue.ClientMsgID, req.SessionType)
// if err != nil {
// isExists, err := db.DB.JudgeMessageReactionExist(messageValue.ClientMsgID, req.SessionType)
// if err != nil {
// rResp.ErrCode = 100
// rResp.ErrMsg = err.Error()
// return &rResp, nil
@ -248,7 +247,6 @@ func (m *msgServer) GetMessagesReactionExtensions(
//}
//log.Debug(req.OperationID, utils.GetSelfFuncName(), "m return is:", rResp.String())
return resp, nil
}
func (m *msgServer) AddMessageReactionExtensions(
@ -262,13 +260,13 @@ func (m *msgServer) DeleteMessageReactionExtensions(
ctx context.Context,
req *msg.DeleteMessagesReactionExtensionsReq,
) (resp *msg.DeleteMessagesReactionExtensionsResp, err error) {
//log.Debug(req.OperationID, utils.GetSelfFuncName(), "m args is:", req.String())
//var rResp msg.DeleteMessagesReactionExtensionsResp
//callbackResp := notification.callbackDeleteMessageReactionExtensions(req)
//if callbackResp.ActionCode != constant.ActionAllow || callbackResp.ErrCode != 0 {
// rResp.ErrCode = int32(callbackResp.ErrCode)
// rResp.ErrMsg = callbackResp.ErrMsg
// for _, value := range req.Pb2Model {
// log.Debug(req.OperationID, utils.GetSelfFuncName(), "m args is:", req.String())
// var rResp msg.DeleteMessagesReactionExtensionsResp
// callbackResp := notification.callbackDeleteMessageReactionExtensions(req)
// if callbackResp.ActionCode != constant.ActionAllow || callbackResp.ErrCode != 0 {
// rResp.ErrCode = int32(callbackResp.ErrCode)
// rResp.ErrMsg = callbackResp.ErrMsg
// for _, value := range req.Pb2Model {
// temp := new(msg.KeyValueResp)
// temp.KeyValue = value
// temp.ErrMsg = callbackResp.ErrMsg

@ -42,7 +42,8 @@ func callbackSetMessageReactionExtensions(ctx context.Context, setReq *msg.SetMe
MsgFirstModifyTime: setReq.MsgFirstModifyTime,
}
resp := &cbapi.CallbackBeforeSetMessageReactionExtResp{}
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackAfterSendGroupMsg); err != nil {
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp,
config.Config.Callback.CallbackAfterSendGroupMsg); err != nil {
return err
}
setReq.MsgFirstModifyTime = resp.MsgFirstModifyTime

@ -21,21 +21,28 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
)
// type constant GLOBALLOCK
const GlOBALLOCK = "GLOBAL_LOCK"
// type interface messageLocker
type MessageLocker interface {
LockMessageTypeKey(ctx context.Context, clientMsgID, typeKey string) (err error)
UnLockMessageTypeKey(ctx context.Context, clientMsgID string, typeKey string) error
LockGlobalMessage(ctx context.Context, clientMsgID string) (err error)
UnLockGlobalMessage(ctx context.Context, clientMsgID string) (err error)
}
// type lockmessage struct
type LockerMessage struct {
cache cache.MsgModel
}
// create a new locker message
func NewLockerMessage(cache cache.MsgModel) *LockerMessage {
return &LockerMessage{cache: cache}
}
// lock message type key
func (l *LockerMessage) LockMessageTypeKey(ctx context.Context, clientMsgID, typeKey string) (err error) {
for i := 0; i < 3; i++ {
err = l.cache.LockMessageTypeKey(ctx, clientMsgID, typeKey)
@ -47,8 +54,9 @@ func (l *LockerMessage) LockMessageTypeKey(ctx context.Context, clientMsgID, typ
}
}
return err
}
// lock global message
func (l *LockerMessage) LockGlobalMessage(ctx context.Context, clientMsgID string) (err error) {
for i := 0; i < 3; i++ {
err = l.cache.LockMessageTypeKey(ctx, clientMsgID, GlOBALLOCK)
@ -60,11 +68,14 @@ func (l *LockerMessage) LockGlobalMessage(ctx context.Context, clientMsgID strin
}
}
return err
}
// unlock message type key
func (l *LockerMessage) UnLockMessageTypeKey(ctx context.Context, clientMsgID string, typeKey string) error {
return l.cache.UnLockMessageTypeKey(ctx, clientMsgID, typeKey)
}
// unclock global message
func (l *LockerMessage) UnLockGlobalMessage(ctx context.Context, clientMsgID string) error {
return l.cache.UnLockMessageTypeKey(ctx, clientMsgID, GlOBALLOCK)
}

@ -24,8 +24,10 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
)
// type message interceptorfunc
type MessageInterceptorFunc func(ctx context.Context, req *msg.SendMsgReq) (*sdkws.MsgData, error)
// confirm message is or not has been read enabled
func MessageHasReadEnabled(_ context.Context, req *msg.SendMsgReq) (*sdkws.MsgData, error) {
switch {
case req.MsgData.ContentType == constant.HasReadReceipt && req.MsgData.SessionType == constant.SingleChatType:

@ -19,8 +19,6 @@ import (
"encoding/json"
"time"
"github.com/google/uuid"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
unRelationTb "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
@ -29,6 +27,7 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"github.com/google/uuid"
)
func (m *msgServer) RevokeMsg(ctx context.Context, req *msg.RevokeMsgReq) (*msg.RevokeMsgResp, error) {
@ -65,19 +64,19 @@ func (m *msgServer) RevokeMsg(ctx context.Context, req *msg.RevokeMsgReq) (*msg.
if !tokenverify.IsAppManagerUid(ctx) {
switch msgs[0].SessionType {
case constant.SingleChatType:
if err := tokenverify.CheckAccessV3(ctx, msgs[0].SendID); err != nil {
return nil, err
if err1 := tokenverify.CheckAccessV3(ctx, msgs[0].SendID); err != nil {
return nil, err1
}
role = user.AppMangerLevel
case constant.SuperGroupChatType:
members, err := m.Group.GetGroupMemberInfoMap(
members, err2 := m.Group.GetGroupMemberInfoMap(
ctx,
msgs[0].GroupID,
utils.Distinct([]string{req.UserID, msgs[0].SendID}),
true,
)
if err != nil {
return nil, err
if err2 != nil {
return nil, err2
}
if req.UserID != msgs[0].SendID {
switch members[req.UserID].RoleLevel {
@ -122,7 +121,8 @@ func (m *msgServer) RevokeMsg(ctx context.Context, req *msg.RevokeMsgReq) (*msg.
} else {
recvID = msgs[0].RecvID
}
if err := m.notificationSender.NotificationWithSesstionType(ctx, req.UserID, recvID, constant.MsgRevokeNotification, msgs[0].SessionType, &tips); err != nil {
if err := m.notificationSender.NotificationWithSesstionType(ctx, req.UserID, recvID,
constant.MsgRevokeNotification, msgs[0].SessionType, &tips); err != nil {
return nil, err
}
return &msg.RevokeMsgResp{}, nil

@ -30,7 +30,7 @@ import (
)
func (m *msgServer) SendMsg(ctx context.Context, req *pbMsg.SendMsgReq) (resp *pbMsg.SendMsgResp, error error) {
resp = &pbMsg.SendMsgResp{}
// resp = &pbMsg.SendMsgResp{}
flag := isMessageHasReadEnabled(req.MsgData)
if !flag {
return nil, errs.ErrMessageHasReadDisable.Wrap()
@ -60,8 +60,8 @@ func (m *msgServer) sendMsgSuperGroupChat(
if err = callbackBeforeSendGroupMsg(ctx, req); err != nil {
return nil, err
}
if err := callbackMsgModify(ctx, req); err != nil {
return nil, err
if err1 := callbackMsgModify(ctx, req); err != nil {
return nil, err1
}
err = m.MsgDatabase.MsgToMQ(ctx, utils.GenConversationUniqueKeyForGroup(req.MsgData.GroupID), req.MsgData)
if err != nil {
@ -97,9 +97,11 @@ func (m *msgServer) setConversationAtInfo(nctx context.Context, msg *sdkws.MsgDa
return
}
atUserID = utils.DifferenceString([]string{constant.AtAllString}, msg.AtUserIDList)
if len(atUserID) == 0 { //just @everyone
if len(atUserID) == 0 {
// just @everyone
conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtAll}
} else { //@Everyone and @other people
} else {
// @Everyone and @other people
conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtAllAtMe}
err := m.Conversation.SetConversations(ctx, atUserID, conversation)
if err != nil {
@ -119,7 +121,6 @@ func (m *msgServer) setConversationAtInfo(nctx context.Context, msg *sdkws.MsgDa
log.ZWarn(ctx, "SetConversations", err, msg.AtUserIDList, conversation)
}
}
}
func (m *msgServer) sendMsgNotification(
@ -127,7 +128,8 @@ func (m *msgServer) sendMsgNotification(
req *pbMsg.SendMsgReq,
) (resp *pbMsg.SendMsgResp, err error) {
promePkg.Inc(promePkg.SingleChatMsgRecvSuccessCounter)
if err := m.MsgDatabase.MsgToMQ(ctx, utils.GenConversationUniqueKeyForSingle(req.MsgData.SendID, req.MsgData.RecvID), req.MsgData); err != nil {
if err := m.MsgDatabase.MsgToMQ(ctx, utils.GenConversationUniqueKeyForSingle(req.MsgData.SendID,
req.MsgData.RecvID), req.MsgData); err != nil {
promePkg.Inc(promePkg.SingleChatMsgProcessFailedCounter)
return nil, err
}
@ -144,7 +146,7 @@ func (m *msgServer) sendMsgSingleChat(ctx context.Context, req *pbMsg.SendMsgReq
if err := m.messageVerification(ctx, req); err != nil {
return nil, err
}
var isSend bool = true
isSend := true
isNotification := utils.IsNotificationByMsg(req.MsgData)
if !isNotification {
isSend, err = m.modifyMessageByUserMessageReceiveOpt(
@ -165,12 +167,13 @@ func (m *msgServer) sendMsgSingleChat(ctx context.Context, req *pbMsg.SendMsgReq
if err = callbackBeforeSendSingleMsg(ctx, req); err != nil {
return nil, err
}
if err := callbackMsgModify(ctx, req); err != nil {
return nil, err
if err1 := callbackMsgModify(ctx, req); err != nil {
return nil, err1
}
if err := m.MsgDatabase.MsgToMQ(ctx, utils.GenConversationUniqueKeyForSingle(req.MsgData.SendID, req.MsgData.RecvID), req.MsgData); err != nil {
if err2 := m.MsgDatabase.MsgToMQ(ctx, utils.GenConversationUniqueKeyForSingle(req.MsgData.SendID, req.MsgData.RecvID),
req.MsgData); err != nil {
promePkg.Inc(promePkg.SingleChatMsgProcessFailedCounter)
return nil, err
return nil, err2
}
err = callbackAfterSendSingleMsg(ctx, req)
if err != nil {

@ -17,8 +17,6 @@ package msg
import (
"context"
"google.golang.org/grpc"
"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"
@ -30,8 +28,10 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/conversation"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"google.golang.org/grpc"
)
// type message intercaptorchain
type MessageInterceptorChain []MessageInterceptorFunc
type msgServer struct {
RegisterCenter discoveryregistry.SvcDiscoveryRegistry
@ -63,6 +63,7 @@ func (m *msgServer) execInterceptorHandler(ctx context.Context, req *msg.SendMsg
return nil
}
// define fuction start cache
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
rdb, err := cache.NewRedis()
if err != nil {
@ -86,19 +87,19 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
)
msgDatabase := controller.NewCommonMsgDatabase(msgDocModel, cacheModel)
conversationClient := rpcclient.NewConversationRpcClient(client)
userRpcClient := rpcclient.NewUserRpcClient(client)
groupRpcClient := rpcclient.NewGroupRpcClient(client)
friendRpcClient := rpcclient.NewFriendRpcClient(client)
userRPCClient := rpcclient.NewUserRpcClient(client)
groupRPCClient := rpcclient.NewGroupRpcClient(client)
friendRPCClient := rpcclient.NewFriendRpcClient(client)
s := &msgServer{
Conversation: &conversationClient,
User: &userRpcClient,
Group: &groupRpcClient,
User: &userRPCClient,
Group: &groupRPCClient,
MsgDatabase: msgDatabase,
ExtendMsgDatabase: extendMsgDatabase,
RegisterCenter: client,
GroupLocalCache: localcache.NewGroupLocalCache(&groupRpcClient),
GroupLocalCache: localcache.NewGroupLocalCache(&groupRPCClient),
ConversationLocalCache: localcache.NewConversationLocalCache(&conversationClient),
friend: &friendRpcClient,
friend: &friendRPCClient,
MessageLocker: NewLockerMessage(cacheModel),
}
s.notificationSender = rpcclient.NewNotificationSender(rpcclient.WithLocalSendMsg(s.SendMsg))

@ -15,13 +15,12 @@
package msg
import (
"github.com/redis/go-redis/v9"
"gorm.io/gorm"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"github.com/redis/go-redis/v9"
"gorm.io/gorm"
)
func isMessageHasReadEnabled(msgData *sdkws.MsgData) bool {
@ -42,6 +41,7 @@ func isMessageHasReadEnabled(msgData *sdkws.MsgData) bool {
return true
}
// define func is not found to used by redis.nil
func IsNotFound(err error) bool {
switch utils.Unwrap(err) {
case redis.Nil, gorm.ErrRecordNotFound:

@ -29,13 +29,16 @@ import (
)
var (
// define exclude content type
ExcludeContentType = []int{constant.HasReadReceipt}
)
// define validator
type Validator interface {
validate(pb *msg.SendMsgReq) (bool, int32, string)
}
// define message revoked type
type MessageRevoked struct {
RevokerID string `json:"revokerID"`
RevokerRole int32 `json:"revokerRole"`
@ -173,6 +176,7 @@ func (m *msgServer) encapsulateMsgData(msg *sdkws.MsgData) {
}
}
// get message Id
func GetMsgID(sendID string) string {
t := time.Now().Format("2006-01-02 15:04:05")
return utils.Md5(t + "-" + sendID + "-" + strconv.Itoa(rand.Int()))

@ -19,7 +19,7 @@ type AwsStorageCredentialReq struct {
}
type AwsStorageCredentialRespData struct {
AccessKeyId string `json:"accessKeyID"`
AccessKeyID string `json:"accessKeyID"`
SecretAccessKey string `json:"secretAccessKey"`
SessionToken string `json:"sessionToken"`
RegionID string `json:"regionId"`

@ -15,7 +15,7 @@
package apistruct
import (
sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
)
type KickGroupMemberReq struct {
@ -26,7 +26,7 @@ type KickGroupMemberReq struct {
}
type KickGroupMemberResp struct {
//UserIDResultList []*UserIDResult `json:"data"`
// UserIDResultList []*UserIDResult `json:"data"`
}
type GetGroupMembersInfoReq struct {

@ -15,37 +15,53 @@
package apistruct
import (
sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
)
// define a DeleteUsersReq struct
type DeleteUsersReq struct {
OperationID string `json:"operationID" binding:"required"`
DeleteUserIDList []string `json:"deleteUserIDList" binding:"required"`
}
// define a DeleteUsersResp struct
type DeleteUsersResp struct {
FailedUserIDList []string `json:"data"`
}
// define a GetAllUsersUidReq struct
type GetAllUsersUidReq struct {
OperationID string `json:"operationID" binding:"required"`
}
// define a GetAllUsersUidResp struct
type GetAllUsersUidResp struct {
UserIDList []string `json:"data"`
}
// define a GetUsersOnlineStatusReq struct
type GetUsersOnlineStatusReq struct {
OperationID string `json:"operationID" binding:"required"`
UserIDList []string `json:"userIDList" binding:"required,lte=200"`
}
// define a GetUsersOnlineStatusResp struct
type GetUsersOnlineStatusResp struct {
//SuccessResult []*msggateway.GetUsersOnlineStatusResp_SuccessResult `json:"data"`
}
// define a AccountCheckReq struct
type AccountCheckReq struct {
OperationID string `json:"operationID" binding:"required"`
CheckUserIDList []string `json:"checkUserIDList" binding:"required,lte=100"`
}
// define a AccountCheckResp struct
type AccountCheckResp struct {
}
// define a ManagementSendMsg struct
type ManagementSendMsg struct {
SendID string `json:"sendID" binding:"required"`
GroupID string `json:"groupID" binding:"required_if=SessionType 2|required_if=SessionType 3"`
@ -60,6 +76,7 @@ type ManagementSendMsg struct {
OfflinePushInfo *sdkws.OfflinePushInfo `json:"offlinePushInfo"`
}
// define a ManagementSendMsgReq struct
type ManagementSendMsgReq struct {
SendID string `json:"sendID" binding:"required"`
RecvID string `json:"recvID" binding:"required_if" message:"recvID is required if sessionType is SingleChatType or NotificationChatType"`
@ -75,22 +92,27 @@ type ManagementSendMsgReq struct {
OfflinePushInfo *sdkws.OfflinePushInfo `json:"offlinePushInfo"`
}
// define a ManagementSendMsgResp struct
type ManagementSendMsgResp struct {
ResultList sdkws.UserSendMsgResp `json:"data"`
}
// define a ManagementBatchSendMsgReq struct
type ManagementBatchSendMsgReq struct {
ManagementSendMsg
IsSendAll bool `json:"isSendAll"`
RecvIDList []string `json:"recvIDList"`
}
// define a ManagementBatchSendMsgResp struct
type ManagementBatchSendMsgResp struct {
Data struct {
ResultList []*SingleReturnResult `json:"resultList"`
FailedIDList []string
} `json:"data"`
}
// define a SingleReturnResult struct
type SingleReturnResult struct {
ServerMsgID string `json:"serverMsgID"`
ClientMsgID string `json:"clientMsgID"`
@ -98,10 +120,12 @@ type SingleReturnResult struct {
RecvID string `json:"recvID"`
}
// define a CheckMsgIsSendSuccessReq struct
type CheckMsgIsSendSuccessReq struct {
OperationID string `json:"operationID"`
}
// define a CheckMsgIsSendSuccessResp struct
type CheckMsgIsSendSuccessResp struct {
Status int32 `json:"status"`
}

@ -16,26 +16,31 @@ package apistruct
import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
)
// define a DelMsgReq struct
type DelMsgReq struct {
UserID string `json:"userID,omitempty" binding:"required"`
SeqList []uint32 `json:"seqList,omitempty" binding:"required"`
OperationID string `json:"operationID,omitempty" binding:"required"`
}
// define a DelMsgResp struct
type DelMsgResp struct {
}
// define a CleanUpMsgReq struct
type CleanUpMsgReq struct {
UserID string `json:"userID" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
// define a CleanUpMsgResp struct
type CleanUpMsgResp struct {
}
// define a DelSuperGroupMsgReq struct
type DelSuperGroupMsgReq struct {
UserID string `json:"userID" binding:"required"`
GroupID string `json:"groupID" binding:"required"`
@ -44,15 +49,18 @@ type DelSuperGroupMsgReq struct {
OperationID string `json:"operationID" binding:"required"`
}
// define a DelSuperGroupMsgResp struct
type DelSuperGroupMsgResp struct {
}
// difine a MsgDeleteNotificationElem struct
type MsgDeleteNotificationElem struct {
GroupID string `json:"groupID"`
IsAllDelete bool `json:"isAllDelete"`
SeqList []uint32 `json:"seqList"`
}
// define a SetMsgMinSeqReq struct
type SetMsgMinSeqReq struct {
UserID string `json:"userID" binding:"required"`
GroupID string `json:"groupID"`
@ -60,9 +68,11 @@ type SetMsgMinSeqReq struct {
OperationID string `json:"operationID" binding:"required"`
}
// define a SetMsgMinSeqResp struct
type SetMsgMinSeqResp struct {
}
// define s ModifyMessageReactionExtensionsReq struct
type ModifyMessageReactionExtensionsReq struct {
OperationID string `json:"operationID" binding:"required"`
conversationID string `json:"conversationID" binding:"required"`
@ -76,6 +86,7 @@ type ModifyMessageReactionExtensionsReq struct {
MsgFirstModifyTime int64 `json:"msgFirstModifyTime"`
}
// define a ModifyMessageReactionExtensionsResp struct
type ModifyMessageReactionExtensionsResp struct {
Data struct {
ResultKeyValue []*msg.KeyValueResp `json:"result"`
@ -99,20 +110,24 @@ type OperateMessageListReactionExtensionsResp struct {
} `json:"data"`
}
// renamed SetMessageReactionExtensionsCallbackResp
type SetMessageReactionExtensionsCallbackReq ModifyMessageReactionExtensionsReq
// renamed SetMessageReactionExtensionsCallbackResp
type SetMessageReactionExtensionsCallbackResp ModifyMessageReactionExtensionsResp
//type GetMessageListReactionExtensionsReq OperateMessageListReactionExtensionsReq
// type GetMessageListReactionExtensionsReq OperateMessageListReactionExtensionsReq
type GetMessageListReactionExtensionsResp struct {
Data []*msg.SingleMessageExtensionResult `json:"data"`
}
// AddMessageReactionExtensionsReq struct
type AddMessageReactionExtensionsReq ModifyMessageReactionExtensionsReq
// AddMessageReactionExtensionsResp struct
type AddMessageReactionExtensionsResp ModifyMessageReactionExtensionsResp
// DeleteMessageReactionExtensionsReq struct
type DeleteMessageReactionExtensionsReq struct {
OperationID string `json:"operationID" binding:"required"`
conversationID string `json:"conversationID" binding:"required"`
@ -123,25 +138,30 @@ type DeleteMessageReactionExtensionsReq struct {
ReactionExtensionList []*sdkws.KeyValue `json:"reactionExtensionList" binding:"required"`
}
// DeleteMessageReactionExtensionsResp struct
type DeleteMessageReactionExtensionsResp struct {
Data []*msg.KeyValueResp
}
// define a picture base info struct
type PictureBaseInfo struct {
UUID string `mapstructure:"uuid"`
Type string `mapstructure:"type"`
Size int64 `mapstructure:"size"`
Width int32 `mapstructure:"width"`
Height int32 `mapstructure:"height"`
Url string `mapstructure:"url"`
URL string `mapstructure:"url"`
}
// define a picture elem struct
type PictureElem struct {
SourcePath string `mapstructure:"sourcePath"`
SourcePicture PictureBaseInfo `mapstructure:"sourcePicture"`
BigPicture PictureBaseInfo `mapstructure:"bigPicture"`
SnapshotPicture PictureBaseInfo `mapstructure:"snapshotPicture"`
}
// define a sound elem struct
type SoundElem struct {
UUID string `mapstructure:"uuid"`
SoundPath string `mapstructure:"soundPath"`
@ -149,6 +169,8 @@ type SoundElem struct {
DataSize int64 `mapstructure:"dataSize"`
Duration int64 `mapstructure:"duration"`
}
// define a video element struct
type VideoElem struct {
VideoPath string `mapstructure:"videoPath"`
VideoUUID string `mapstructure:"videoUUID"`
@ -163,6 +185,8 @@ type VideoElem struct {
SnapshotWidth int32 `mapstructure:"snapshotWidth"`
SnapshotHeight int32 `mapstructure:"snapshotHeight"`
}
// define a file elem struct
type FileElem struct {
FilePath string `mapstructure:"filePath"`
UUID string `mapstructure:"uuid"`
@ -170,34 +194,45 @@ type FileElem struct {
FileName string `mapstructure:"fileName"`
FileSize int64 `mapstructure:"fileSize"`
}
// define a atelem struct
type AtElem struct {
Text string `mapstructure:"text"`
AtUserList []string `mapstructure:"atUserList"`
IsAtSelf bool `mapstructure:"isAtSelf"`
}
// define a locatinelem struct
type LocationElem struct {
Description string `mapstructure:"description"`
Longitude float64 `mapstructure:"longitude"`
Latitude float64 `mapstructure:"latitude"`
}
// define a customelem struct
type CustomElem struct {
Data string `mapstructure:"data" validate:"required"`
Description string `mapstructure:"description"`
Extension string `mapstructure:"extension"`
}
// define a textelem struct
type TextElem struct {
Text string `mapstructure:"text" validate:"required"`
}
// define a revoke elem struct
type RevokeElem struct {
RevokeMsgClientID string `mapstructure:"revokeMsgClientID" validate:"required"`
}
// define a OANotificationElem struct
type OANotificationElem struct {
NotificationName string `mapstructure:"notificationName" json:"notificationName" validate:"required"`
NotificationFaceURL string `mapstructure:"notificationFaceURL" json:"notificationFaceURL"`
NotificationType int32 `mapstructure:"notificationType" json:"notificationType" validate:"required"`
Text string `mapstructure:"text" json:"text" validate:"required"`
Url string `mapstructure:"url" json:"url"`
UrL string `mapstructure:"url" json:"url"`
MixType int32 `mapstructure:"mixType" json:"mixType"`
PictureElem PictureElem `mapstructure:"pictureElem" json:"pictureElem"`
SoundElem SoundElem `mapstructure:"soundElem" json:"soundElem"`
@ -205,6 +240,8 @@ type OANotificationElem struct {
FileElem FileElem `mapstructure:"fileElem" json:"fileElem"`
Ex string `mapstructure:"ex" json:"ex"`
}
// define a message revoked struct
type MessageRevoked struct {
RevokerID string `mapstructure:"revokerID" json:"revokerID" validate:"required"`
RevokerRole int32 `mapstructure:"revokerRole" json:"revokerRole" validate:"required"`

@ -14,21 +14,24 @@
package apistruct
// define a OSSCredentialReq struct
type OSSCredentialReq struct {
OperationID string `json:"operationID"`
Filename string `json:"filename"`
FileType string `json:"file_type"`
}
// define a OSSCredentialRespData struct
type OSSCredentialRespData struct {
Endpoint string `json:"endpoint"`
AccessKeyId string `json:"access_key_id"`
AccessKeyID string `json:"access_key_id"`
AccessKeySecret string `json:"access_key_secret"`
Token string `json:"token"`
Bucket string `json:"bucket"`
FinalHost string `json:"final_host"`
}
// define a OSSCredentialResp
type OSSCredentialResp struct {
OssData OSSCredentialRespData `json:"-"`
Data map[string]interface{} `json:"data"`

@ -14,18 +14,22 @@
package apistruct
// define a GetJoinedSuperGroupListReq
type GetJoinedSuperGroupListReq struct {
GetJoinedGroupListReq
}
// define a GetJoinedGroupListresp
type GetJoinedSuperGroupListResp struct {
GetJoinedGroupListResp
}
// define a GetSuperGroupsInfoReq
type GetSuperGroupsInfoReq struct {
GetGroupInfoReq
}
// define a GetSuperGroupsInforesp
type GetSuperGroupsInfoResp struct {
GetGroupInfoResp
}

@ -16,10 +16,12 @@ package apistruct
import "mime/multipart"
// define a MinioStorageCredentialReq
type MinioStorageCredentialReq struct {
OperationID string `json:"operationID"`
}
// define a MiniostorageCredentialResp
type MiniostorageCredentialResp struct {
SecretAccessKey string `json:"secretAccessKey"`
AccessKeyID string `json:"accessKeyID"`
@ -30,11 +32,13 @@ type MiniostorageCredentialResp struct {
IsDistributedMod bool `json:"isDistributedMod"`
}
// define a MinioUploadFileReq
type MinioUploadFileReq struct {
OperationID string `form:"operationID" binding:"required"`
FileType int `form:"fileType" binding:"required"`
}
// define a MinioUploadFile
type MinioUploadFile struct {
URL string `json:"URL"`
NewName string `json:"newName"`
@ -42,12 +46,14 @@ type MinioUploadFile struct {
SnapshotNewName string `json:"snapshotName,omitempty"`
}
// define a MinioUploadFileResp
type MinioUploadFileResp struct {
Data struct {
MinioUploadFile
} `json:"data"`
}
// define a UploadUpdateAppReq
type UploadUpdateAppReq struct {
OperationID string `form:"operationID" binding:"required"`
Type int `form:"type" binding:"required"`
@ -58,9 +64,11 @@ type UploadUpdateAppReq struct {
UpdateLog string `form:"updateLog" binding:"required"`
}
// define a UploadUpdateAppResp
type UploadUpdateAppResp struct {
}
// define a GetDownloadURLReq
type GetDownloadURLReq struct {
OperationID string `json:"operationID" binding:"required"`
Type int `json:"type" binding:"required"`
@ -119,13 +127,17 @@ type FcmUpdateTokenReq struct {
FcmToken string `json:"fcmToken" binding:"required"`
}
// define a fcm update token resep struct
type FcmUpdateTokenResp struct {
}
// define a set appbadge request struct
type SetAppBadgeReq struct {
OperationID string `json:"operationID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
AppUnreadCount int32 `json:"appUnreadCount"`
}
// null struct
type SetAppBadgeResp struct {
}

@ -16,14 +16,17 @@ package cmd
import "github.com/spf13/cobra"
// define a api command struct
type ApiCmd struct {
*RootCmd
}
// create a new api command
func NewApiCmd() *ApiCmd {
return &ApiCmd{NewRootCmd("api")}
}
// add api
func (a *ApiCmd) AddApi(f func(port int) error) {
a.Command.RunE = func(cmd *cobra.Command, args []string) error {
return f(a.getPortFlag(cmd))

@ -16,14 +16,17 @@ package cmd
import "github.com/spf13/cobra"
// define a cron task command
type CronTaskCmd struct {
*RootCmd
}
// create a new cron task command
func NewCronTaskCmd() *CronTaskCmd {
return &CronTaskCmd{NewRootCmd("cronTask")}
}
// add rune
func (c *CronTaskCmd) addRunE(f func() error) {
c.Command.RunE = func(cmd *cobra.Command, args []string) error {
return f()

@ -16,35 +16,41 @@ package cmd
import (
"github.com/OpenIMSDK/Open-IM-Server/internal/msggateway"
//"github.com/OpenIMSDK/Open-IM-Server/internal/msggateway"
"github.com/spf13/cobra"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
// "github.com/OpenIMSDK/Open-IM-Server/internal/msggateway"
"github.com/spf13/cobra"
)
// define a message gateway command
type MsgGatewayCmd struct {
*RootCmd
}
// create a new MsgGateway command
func NewMsgGatewayCmd() MsgGatewayCmd {
return MsgGatewayCmd{NewRootCmd("msgGateway")}
}
// add ws port flag
func (m *MsgGatewayCmd) AddWsPortFlag() {
m.Command.Flags().IntP(constant.FlagWsPort, "w", 0, "ws server listen port")
}
// get ws port flag
func (m *MsgGatewayCmd) getWsPortFlag(cmd *cobra.Command) int {
port, _ := cmd.Flags().GetInt(constant.FlagWsPort)
return port
}
// add rune
func (m *MsgGatewayCmd) addRunE() {
m.Command.RunE = func(cmd *cobra.Command, args []string) error {
return msggateway.RunWsAndServer(m.getPortFlag(cmd), m.getWsPortFlag(cmd), m.getPrometheusPortFlag(cmd))
}
}
// exec
func (m *MsgGatewayCmd) Exec() error {
m.addRunE()
return m.Execute()

@ -15,25 +15,28 @@
package cmd
import (
"github.com/spf13/cobra"
"github.com/OpenIMSDK/Open-IM-Server/internal/msgtransfer"
"github.com/spf13/cobra"
)
// define a message transfer command
type MsgTransferCmd struct {
*RootCmd
}
// create a message transfer command
func NewMsgTransferCmd() MsgTransferCmd {
return MsgTransferCmd{NewRootCmd("msgTransfer")}
}
// add rune
func (m *MsgTransferCmd) addRunE() {
m.Command.RunE = func(cmd *cobra.Command, args []string) error {
return msgtransfer.StartTransfer(m.getPrometheusPortFlag(cmd))
}
}
// exec
func (m *MsgTransferCmd) Exec() error {
m.addRunE()
return m.Execute()

@ -15,74 +15,88 @@
package cmd
import (
"github.com/spf13/cobra"
"github.com/OpenIMSDK/Open-IM-Server/internal/tools"
"github.com/spf13/cobra"
)
// define a message util command struct
type MsgUtilsCmd struct {
cobra.Command
msgTool *tools.MsgTool
}
// add userID flag
func (m *MsgUtilsCmd) AddUserIDFlag() {
m.Command.PersistentFlags().StringP("userID", "u", "", "openIM userID")
}
// get userID flag
func (m *MsgUtilsCmd) getUserIDFlag(cmdLines *cobra.Command) string {
userID, _ := cmdLines.Flags().GetString("userID")
return userID
}
// add fix all flag
func (m *MsgUtilsCmd) AddFixAllFlag() {
m.Command.PersistentFlags().BoolP("fixAll", "f", false, "openIM fix all seqs")
}
// get fix all flag
func (m *MsgUtilsCmd) getFixAllFlag(cmdLines *cobra.Command) bool {
fixAll, _ := cmdLines.Flags().GetBool("fixAll")
return fixAll
}
// add clear all flag
func (m *MsgUtilsCmd) AddClearAllFlag() {
m.Command.PersistentFlags().BoolP("clearAll", "c", false, "openIM clear all seqs")
}
// get clear all flag
func (m *MsgUtilsCmd) getClearAllFlag(cmdLines *cobra.Command) bool {
clearAll, _ := cmdLines.Flags().GetBool("clearAll")
return clearAll
}
// add super groupID flag
func (m *MsgUtilsCmd) AddSuperGroupIDFlag() {
m.Command.PersistentFlags().StringP("superGroupID", "g", "", "openIM superGroupID")
}
// get super groupID flag
func (m *MsgUtilsCmd) getSuperGroupIDFlag(cmdLines *cobra.Command) string {
superGroupID, _ := cmdLines.Flags().GetString("superGroupID")
return superGroupID
}
// add begin sequence flag
func (m *MsgUtilsCmd) AddBeginSeqFlag() {
m.Command.PersistentFlags().Int64P("beginSeq", "b", 0, "openIM beginSeq")
}
// get begin sequence flag
func (m *MsgUtilsCmd) getBeginSeqFlag(cmdLines *cobra.Command) int64 {
beginSeq, _ := cmdLines.Flags().GetInt64("beginSeq")
return beginSeq
}
// add limited flag
func (m *MsgUtilsCmd) AddLimitFlag() {
m.Command.PersistentFlags().Int64P("limit", "l", 0, "openIM limit")
}
// get limited flag
func (m *MsgUtilsCmd) getLimitFlag(cmdLines *cobra.Command) int64 {
limit, _ := cmdLines.Flags().GetInt64("limit")
return limit
}
// execute
func (m *MsgUtilsCmd) Execute() error {
return m.Command.Execute()
}
// new message utils command
func NewMsgUtilsCmd(use, short string, args cobra.PositionalArgs) *MsgUtilsCmd {
return &MsgUtilsCmd{
Command: cobra.Command{
@ -93,40 +107,48 @@ func NewMsgUtilsCmd(use, short string, args cobra.PositionalArgs) *MsgUtilsCmd {
}
}
// define a getcommand dtruct
type GetCmd struct {
*MsgUtilsCmd
}
// create a new command
func NewGetCmd() *GetCmd {
return &GetCmd{
NewMsgUtilsCmd("get [resource]", "get action", cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs)),
}
}
// define a fix command struct
type FixCmd struct {
*MsgUtilsCmd
}
// new a fixed command
func NewFixCmd() *FixCmd {
return &FixCmd{
NewMsgUtilsCmd("fix [resource]", "fix action", cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs)),
}
}
// define a clear command
type ClearCmd struct {
*MsgUtilsCmd
}
// create a new command
func NewClearCmd() *ClearCmd {
return &ClearCmd{
NewMsgUtilsCmd("clear [resource]", "clear action", cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs)),
}
}
// define a sequnce command struct
type SeqCmd struct {
*MsgUtilsCmd
}
// create a new seq command
func NewSeqCmd() *SeqCmd {
seqCmd := &SeqCmd{
NewMsgUtilsCmd("seq", "seq", nil),
@ -134,6 +156,7 @@ func NewSeqCmd() *SeqCmd {
return seqCmd
}
// get a sequence command
func (s *SeqCmd) GetSeqCmd() *cobra.Command {
s.Command.Run = func(cmdLines *cobra.Command, args []string) {
_, err := tools.InitMsgTool()
@ -161,14 +184,17 @@ func (s *SeqCmd) GetSeqCmd() *cobra.Command {
return &s.Command
}
// fix a sequence command
func (s *SeqCmd) FixSeqCmd() *cobra.Command {
return &s.Command
}
// define a message command
type MsgCmd struct {
*MsgUtilsCmd
}
// create a message command
func NewMsgCmd() *MsgCmd {
msgCmd := &MsgCmd{
NewMsgUtilsCmd("msg", "msg", nil),
@ -176,10 +202,12 @@ func NewMsgCmd() *MsgCmd {
return msgCmd
}
// get message command
func (m *MsgCmd) GetMsgCmd() *cobra.Command {
return &m.Command
}
// clear message command
func (m *MsgCmd) ClearMsgCmd() *cobra.Command {
return &m.Command
}

@ -17,13 +17,13 @@ package cmd
import (
"fmt"
"github.com/spf13/cobra"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
"github.com/spf13/cobra"
)
// define a root command
type RootCmd struct {
Command cobra.Command
Name string
@ -31,6 +31,7 @@ type RootCmd struct {
prometheusPort int
}
// create a new root command
func NewRootCmd(name string) (rootCmd *RootCmd) {
rootCmd = &RootCmd{Name: name}
c := cobra.Command{
@ -41,7 +42,10 @@ func NewRootCmd(name string) (rootCmd *RootCmd) {
if err := rootCmd.getConfFromCmdAndInit(cmd); err != nil {
panic(err)
}
if err := log.InitFromConfig("OpenIM.log.all", name, config.Config.Log.RemainLogLevel, config.Config.Log.IsStdout, config.Config.Log.IsJson, config.Config.Log.StorageLocation, config.Config.Log.RemainRotationCount); err != nil {
if err := log.InitFromConfig("OpenIM.log.all", name,
config.Config.Log.RemainLogLevel, config.Config.Log.IsStdout,
config.Config.Log.IsJson, config.Config.Log.StorageLocation,
config.Config.Log.RemainRotationCount); err != nil {
panic(err)
}
return nil
@ -52,45 +56,55 @@ func NewRootCmd(name string) (rootCmd *RootCmd) {
return rootCmd
}
// add config flag
func (r *RootCmd) addConfFlag() {
r.Command.Flags().StringP(constant.FlagConf, "c", "", "Path to config file folder")
}
// add port flag
func (r *RootCmd) AddPortFlag() {
r.Command.Flags().IntP(constant.FlagPort, "p", 0, "server listen port")
}
// get port flag
func (r *RootCmd) getPortFlag(cmd *cobra.Command) int {
port, _ := cmd.Flags().GetInt(constant.FlagPort)
return port
}
// get port flag
func (r *RootCmd) GetPortFlag() int {
return r.port
}
// add promethus port flag
func (r *RootCmd) AddPrometheusPortFlag() {
r.Command.Flags().IntP(constant.FlagPrometheusPort, "", 0, "server prometheus listen port")
}
// // gey promethus port plag
func (r *RootCmd) getPrometheusPortFlag(cmd *cobra.Command) int {
port, _ := cmd.Flags().GetInt(constant.FlagPrometheusPort)
return port
}
// gey promethus port plag
func (r *RootCmd) GetPrometheusPortFlag() int {
return r.prometheusPort
}
// get config from cmd and init
func (r *RootCmd) getConfFromCmdAndInit(cmdLines *cobra.Command) error {
configFolderPath, _ := cmdLines.Flags().GetString(constant.FlagConf)
return config.InitConfig(configFolderPath)
}
// excute
func (r *RootCmd) Execute() error {
return r.Command.Execute()
}
// add command
func (r *RootCmd) AddCommand(cmds ...*cobra.Command) {
r.Command.AddCommand(cmds...)
}

@ -17,22 +17,24 @@ package cmd
import (
"errors"
"github.com/spf13/cobra"
"google.golang.org/grpc"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/startrpc"
"github.com/spf13/cobra"
"google.golang.org/grpc"
)
// define a rpccmd struct
type RpcCmd struct {
*RootCmd
}
// create a new rpc command
func NewRpcCmd(name string) *RpcCmd {
authCmd := &RpcCmd{NewRootCmd(name)}
return authCmd
}
// exec
func (a *RpcCmd) Exec() error {
a.Command.Run = func(cmd *cobra.Command, args []string) {
a.port = a.getPortFlag(cmd)
@ -41,6 +43,7 @@ func (a *RpcCmd) Exec() error {
return a.Execute()
}
// start server
func (a *RpcCmd) StartSvr(
name string,
rpcFn func(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error,

@ -18,24 +18,28 @@ import (
_ "embed"
)
//go:embed version
// go:embed Version
var Version string
// renamed config
var Config config
// define CallBackConfig struct
type CallBackConfig struct {
Enable bool `yaml:"enable"`
CallbackTimeOut int `yaml:"timeout"`
CallbackFailedContinue *bool `yaml:"failedContinue"`
}
// define Notificationconf struct
type NotificationConf struct {
IsSendMsg bool `yaml:"isSendMsg"`
ReliabilityLevel int `yaml:"reliabilityLevel"` // 1 online 2 presistent
ReliabilityLevel int `yaml:"reliabilityLevel"` // 1 online 2 persistent
UnreadCount bool `yaml:"unreadCount"`
OfflinePush POfflinePush `yaml:"offlinePush"`
}
// define POfflinePush struct
type POfflinePush struct {
Enable bool `yaml:"enable"`
Title string `yaml:"title"`
@ -64,7 +68,7 @@ type config struct {
} `yaml:"mysql"`
Mongo struct {
Uri string `yaml:"uri"`
URI string `yaml:"URI"`
Address []string `yaml:"address"`
Database string `yaml:"database"`
Username string `yaml:"username"`
@ -97,25 +101,25 @@ type config struct {
ConsumerGroupID struct {
MsgToRedis string `yaml:"msgToRedis"`
MsgToMongo string `yaml:"msgToMongo"`
MsgToMySql string `yaml:"msgToMySql"`
MsgToMySQL string `yaml:"MsgToMySQL"`
MsgToPush string `yaml:"msgToPush"`
MsgToModify string `yaml:"msgToModify"`
} `yaml:"consumerGroupID"`
} `yaml:"kafka"`
Rpc struct {
RPC struct {
RegisterIP string `yaml:"registerIP"`
ListenIP string `yaml:"listenIP"`
} `yaml:"rpc"`
} `yaml:"RPC"`
Api struct {
OpenImApiPort []int `yaml:"openImApiPort"`
API struct {
OpenImAPIPort []int `yaml:"OpenImAPIPort"`
ListenIP string `yaml:"listenIP"`
} `yaml:"api"`
} `yaml:"API"`
Object struct {
Enable string `yaml:"enable"`
ApiURL string `yaml:"apiURL"`
APIURL string `yaml:" APIURL"`
Minio struct {
TempBucket string `yaml:"tempBucket"`
DataBucket string `yaml:"dataBucket"`
@ -150,12 +154,12 @@ type config struct {
Bucket string `yaml:"bucket"`
FinalHost string `yaml:"finalHost"`
RoleArn string `yaml:"roleArn"`
ExternalId string `yaml:"externalId"`
ExternalID string `yaml:"ExternalID"`
RoleSessionName string `yaml:"roleSessionName"`
} `yaml:"aws"`
} `yaml:"object"`
RpcPort struct {
RPCPort struct {
OpenImUserPort []int `yaml:"openImUserPort"`
OpenImFriendPort []int `yaml:"openImFriendPort"`
OpenImMessagePort []int `yaml:"openImMessagePort"`
@ -166,9 +170,9 @@ type config struct {
OpenImConversationPort []int `yaml:"openImConversationPort"`
OpenImRtcPort []int `yaml:"openImRtcPort"`
OpenImThirdPort []int `yaml:"openImThirdPort"`
} `yaml:"rpcPort"`
} `yaml:"RPCPort"`
RpcRegisterName struct {
RPCRegisterName struct {
OpenImUserName string `yaml:"openImUserName"`
OpenImFriendName string `yaml:"openImFriendName"`
OpenImMsgName string `yaml:"openImMsgName"`
@ -178,7 +182,7 @@ type config struct {
OpenImAuthName string `yaml:"openImAuthName"`
OpenImConversationName string `yaml:"openImConversationName"`
OpenImThirdName string `yaml:"openImThirdName"`
} `yaml:"rpcRegisterName"`
} `yaml:"RPCRegisterName"`
Log struct {
StorageLocation string `yaml:"storageLocation"`
@ -200,7 +204,7 @@ type config struct {
Push struct {
Enable string `yaml:"enable"`
GeTui struct {
PushUrl string `yaml:"pushUrl"`
PushURL string `yaml:"PushURL"`
AppKey string `yaml:"appKey"`
Intent string `yaml:"intent"`
MasterSecret string `yaml:"masterSecret"`
@ -213,7 +217,7 @@ type config struct {
Jpns struct {
AppKey string `yaml:"appKey"`
MasterSecret string `yaml:"masterSecret"`
PushUrl string `yaml:"pushUrl"`
PushURL string `yaml:"PushURL"`
PushIntent string `yaml:"pushIntent"`
} `yaml:"jpns"`
}
@ -318,14 +322,14 @@ type notification struct {
func GetServiceNames() []string {
return []string{
Config.RpcRegisterName.OpenImUserName,
Config.RpcRegisterName.OpenImFriendName,
Config.RpcRegisterName.OpenImMsgName,
Config.RpcRegisterName.OpenImPushName,
Config.RpcRegisterName.OpenImMessageGatewayName,
Config.RpcRegisterName.OpenImGroupName,
Config.RpcRegisterName.OpenImAuthName,
Config.RpcRegisterName.OpenImConversationName,
Config.RpcRegisterName.OpenImThirdName,
Config.RPCRegisterName.OpenImUserName,
Config.RPCRegisterName.OpenImFriendName,
Config.RPCRegisterName.OpenImMsgName,
Config.RPCRegisterName.OpenImPushName,
Config.RPCRegisterName.OpenImMessageGatewayName,
Config.RPCRegisterName.OpenImGroupName,
Config.RPCRegisterName.OpenImAuthName,
Config.RPCRegisterName.OpenImConversationName,
Config.RPCRegisterName.OpenImThirdName,
}
}

@ -21,16 +21,15 @@ import (
"path/filepath"
"runtime"
"gopkg.in/yaml.v3"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"gopkg.in/yaml.v3"
)
var (
_, b, _, _ = runtime.Caller(0)
// Root folder of this project
// Root folder of this project.
Root = filepath.Join(filepath.Dir(b), "../../..")
)
@ -42,6 +41,7 @@ const (
ConfKey = "conf"
)
// get options by notification
func GetOptionsByNotification(cfg NotificationConf) utils.Options {
opts := utils.NewOptions()
if cfg.UnreadCount {
@ -59,6 +59,7 @@ func GetOptionsByNotification(cfg NotificationConf) utils.Options {
return opts
}
// unmarshal config
func (c *config) unmarshalConfig(config interface{}, configPath string) error {
bytes, err := os.ReadFile(configPath)
if err != nil {
@ -70,6 +71,7 @@ func (c *config) unmarshalConfig(config interface{}, configPath string) error {
return nil
}
// init config
func (c *config) initConfig(config interface{}, configName, configFolderPath string) error {
if configFolderPath == "" {
configFolderPath = DefaultFolderPath
@ -90,6 +92,7 @@ func (c *config) initConfig(config interface{}, configName, configFolderPath str
return c.unmarshalConfig(config, configPath)
}
// register conf2
func (c *config) RegisterConf2Registry(registry discoveryregistry.SvcDiscoveryRegistry) error {
bytes, err := yaml.Marshal(Config)
if err != nil {
@ -98,10 +101,12 @@ func (c *config) RegisterConf2Registry(registry discoveryregistry.SvcDiscoveryRe
return registry.RegisterConf2Registry(ConfKey, bytes)
}
// get conf from registry
func (c *config) GetConfFromRegistry(registry discoveryregistry.SvcDiscoveryRegistry) ([]byte, error) {
return registry.GetConfFromRegistry(ConfKey)
}
// init config
func InitConfig(configFolderPath string) error {
err := Config.initConfig(&Config, FileName, configFolderPath)
if err != nil {
@ -114,6 +119,7 @@ func InitConfig(configFolderPath string) error {
return nil
}
// encode config
func EncodeConfig() []byte {
buf := bytes.NewBuffer(nil)
if err := yaml.NewEncoder(buf).Encode(Config); err != nil {

@ -16,6 +16,7 @@ package log
import "context"
// define a logger interface
type Logger interface {
Debug(ctx context.Context, msg string, keysAndValues ...interface{})
Info(ctx context.Context, msg string, keysAndValues ...interface{})

@ -25,12 +25,14 @@ import (
gormUtils "gorm.io/gorm/utils"
)
// type a sql logger struct
type SqlLogger struct {
LogLevel gormLogger.LogLevel
IgnoreRecordNotFoundError bool
SlowThreshold time.Duration
}
// create a new sql logger
func NewSqlLogger(
logLevel gormLogger.LogLevel,
ignoreRecordNotFoundError bool,
@ -43,31 +45,37 @@ func NewSqlLogger(
}
}
// type log mode
func (l *SqlLogger) LogMode(logLevel gormLogger.LogLevel) gormLogger.Interface {
newLogger := *l
newLogger.LogLevel = logLevel
return &newLogger
}
// info
func (SqlLogger) Info(ctx context.Context, msg string, args ...interface{}) {
ZInfo(ctx, msg, args)
}
// warn
func (SqlLogger) Warn(ctx context.Context, msg string, args ...interface{}) {
ZWarn(ctx, msg, nil, args)
}
// error
func (SqlLogger) Error(ctx context.Context, msg string, args ...interface{}) {
ZError(ctx, msg, nil, args)
}
// trace
func (l *SqlLogger) Trace(ctx context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) {
if l.LogLevel <= gormLogger.Silent {
return
}
elapsed := time.Since(begin)
switch {
case err != nil && l.LogLevel >= gormLogger.Error && (!errors.Is(err, gorm.ErrRecordNotFound) || !l.IgnoreRecordNotFoundError):
case err != nil && l.LogLevel >= gormLogger.Error && (!errors.Is(err, gorm.ErrRecordNotFound) ||
!l.IgnoreRecordNotFoundError):
sql, rows := fc()
if rows == -1 {
ZError(
@ -82,7 +90,9 @@ func (l *SqlLogger) Trace(ctx context.Context, begin time.Time, fc func() (sql s
sql,
)
} else {
ZError(ctx, "sql exec detail", err, "gorm", gormUtils.FileWithLineNum(), "elapsed time", fmt.Sprintf("%f(ms)", float64(elapsed.Nanoseconds())/1e6), "rows", rows, "sql", sql)
ZError(ctx, "sql exec detail", err, "gorm",
gormUtils.FileWithLineNum(), "elapsed time",
fmt.Sprintf("%f(ms)", float64(elapsed.Nanoseconds())/1e6), "rows", rows, "sql", sql)
}
case elapsed > l.SlowThreshold && l.SlowThreshold != 0 && l.LogLevel >= gormLogger.Warn:
sql, rows := fc()
@ -103,7 +113,10 @@ func (l *SqlLogger) Trace(ctx context.Context, begin time.Time, fc func() (sql s
sql,
)
} else {
ZWarn(ctx, "sql exec detail", nil, "gorm", gormUtils.FileWithLineNum(), nil, "slow sql", slowLog, "elapsed time", fmt.Sprintf("%f(ms)", float64(elapsed.Nanoseconds())/1e6), "rows", rows, "sql", sql)
ZWarn(ctx, "sql exec detail", nil, "gorm",
gormUtils.FileWithLineNum(), nil, "slow sql",
slowLog, "elapsed time", fmt.Sprintf("%f(ms)",
float64(elapsed.Nanoseconds())/1e6), "rows", rows, "sql", sql)
}
case l.LogLevel == gormLogger.Info:
sql, rows := fc()
@ -119,7 +132,9 @@ func (l *SqlLogger) Trace(ctx context.Context, begin time.Time, fc func() (sql s
sql,
)
} else {
ZDebug(ctx, "sql exec detail", "gorm", gormUtils.FileWithLineNum(), "elapsed time", fmt.Sprintf("%f(ms)", float64(elapsed.Nanoseconds())/1e6), "rows", rows, "sql", sql)
ZDebug(ctx, "sql exec detail", "gorm", gormUtils.FileWithLineNum(),
"elapsed time", fmt.Sprintf("%f(ms)", float64(elapsed.Nanoseconds())/1e6),
"rows", rows, "sql", sql)
}
}
}

@ -21,12 +21,10 @@ import (
"path/filepath"
"time"
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
@ -104,7 +102,7 @@ func NewZapLogger(
loggerPrefixName, loggerName string,
logLevel int,
isStdout bool,
isJson bool,
isJSON bool,
logLocation string,
rotateCount uint,
) (*ZapLogger, error) {
@ -114,7 +112,7 @@ func NewZapLogger(
// InitialFields: map[string]interface{}{"PID": os.Getegid()},
DisableStacktrace: true,
}
if isJson {
if isJSON {
zapConfig.Encoding = "json"
} else {
zapConfig.Encoding = "console"
@ -123,7 +121,7 @@ func NewZapLogger(
// zapConfig.OutputPaths = append(zapConfig.OutputPaths, "stdout", "stderr")
// }
zl := &ZapLogger{level: logLevelMap[logLevel], loggerName: loggerName, loggerPrefixName: loggerPrefixName}
opts, err := zl.cores(isStdout, isJson, logLocation, rotateCount)
opts, err := zl.cores(isStdout, isJSON, logLocation, rotateCount)
if err != nil {
return nil, err
}
@ -176,6 +174,7 @@ func (l *ZapLogger) cores(isStdout bool, isJson bool, logLocation string, rotate
}), nil
}
// customCallerEncoder
func (l *ZapLogger) customCallerEncoder(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) {
s := "[" + caller.TrimmedPath() + "]"
// color, ok := _levelToColor[l.level]
@ -186,6 +185,7 @@ func (l *ZapLogger) customCallerEncoder(caller zapcore.EntryCaller, enc zapcore.
}
// time encodor
func (l *ZapLogger) timeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
layout := "2006-01-02 15:04:05.000"
type appendTimeEncoder interface {
@ -198,6 +198,7 @@ func (l *ZapLogger) timeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder)
enc.AppendString(t.Format(layout))
}
// get writter
func (l *ZapLogger) getWriter(logLocation string, rorateCount uint) (zapcore.WriteSyncer, error) {
logf, err := rotatelogs.New(logLocation+sp+l.loggerPrefixName+".%Y-%m-%d",
rotatelogs.WithRotationCount(rorateCount),
@ -209,6 +210,7 @@ func (l *ZapLogger) getWriter(logLocation string, rorateCount uint) (zapcore.Wri
return zapcore.AddSync(logf), nil
}
// capitalColorLevelEncoder
func (l *ZapLogger) capitalColorLevelEncoder(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) {
s, ok := _levelToCapitalColorString[level]
if !ok {
@ -223,20 +225,24 @@ func (l *ZapLogger) capitalColorLevelEncoder(level zapcore.Level, enc zapcore.Pr
}
}
// tozap
func (l *ZapLogger) ToZap() *zap.SugaredLogger {
return l.zap
}
// debug
func (l *ZapLogger) Debug(ctx context.Context, msg string, keysAndValues ...interface{}) {
keysAndValues = l.kvAppend(ctx, keysAndValues)
l.zap.Debugw(msg, keysAndValues...)
}
// info
func (l *ZapLogger) Info(ctx context.Context, msg string, keysAndValues ...interface{}) {
keysAndValues = l.kvAppend(ctx, keysAndValues)
l.zap.Infow(msg, keysAndValues...)
}
// warn
func (l *ZapLogger) Warn(ctx context.Context, msg string, err error, keysAndValues ...interface{}) {
if err != nil {
keysAndValues = append(keysAndValues, "error", err.Error())
@ -245,6 +251,7 @@ func (l *ZapLogger) Warn(ctx context.Context, msg string, err error, keysAndValu
l.zap.Warnw(msg, keysAndValues...)
}
// error
func (l *ZapLogger) Error(ctx context.Context, msg string, err error, keysAndValues ...interface{}) {
if err != nil {
keysAndValues = append(keysAndValues, "error", err.Error())
@ -253,6 +260,7 @@ func (l *ZapLogger) Error(ctx context.Context, msg string, err error, keysAndVal
l.zap.Errorw(msg, keysAndValues...)
}
// kv append
func (l *ZapLogger) kvAppend(ctx context.Context, keysAndValues []interface{}) []interface{} {
if ctx == nil {
return keysAndValues
@ -284,18 +292,21 @@ func (l *ZapLogger) kvAppend(ctx context.Context, keysAndValues []interface{}) [
return keysAndValues
}
// with namevalues
func (l *ZapLogger) WithValues(keysAndValues ...interface{}) Logger {
dup := *l
dup.zap = l.zap.With(keysAndValues...)
return &dup
}
// with name
func (l *ZapLogger) WithName(name string) Logger {
dup := *l
dup.zap = l.zap.Named(name)
return &dup
}
// with call depth
func (l *ZapLogger) WithCallDepth(depth int) Logger {
dup := *l
dup.zap = l.zap.WithOptions(zap.AddCallerSkip(depth))

@ -19,12 +19,15 @@ import (
"fmt"
)
// type zookeeper struct
type ZkLogger struct{}
// cteate a new zookeeper logger
func NewZkLogger() *ZkLogger {
return &ZkLogger{}
}
// printf
func (l *ZkLogger) Printf(format string, a ...interface{}) {
ZInfo(context.Background(), "zookeeper output", "msg", fmt.Sprintf(format, a...))
}

@ -18,6 +18,7 @@ import "github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
var handlers []func(err error) errs.CodeError
// add error handler
func AddErrHandler(h func(err error) errs.CodeError) {
if h == nil {
panic("nil handler")
@ -25,6 +26,7 @@ func AddErrHandler(h func(err error) errs.CodeError) {
handlers = append(handlers, h)
}
// add replace
func AddReplace(target error, codeErr errs.CodeError) {
AddErrHandler(func(err error) errs.CodeError {
if err == target {
@ -34,6 +36,7 @@ func AddReplace(target error, codeErr errs.CodeError) {
})
}
// error code
func ErrCode(err error) errs.CodeError {
if codeErr, ok := err.(errs.CodeError); ok {
return codeErr

@ -22,15 +22,17 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
)
// define a conversation notification sender struct
type ConversationNotificationSender struct {
*rpcclient.NotificationSender
}
// create a new conversation notification sender
func NewConversationNotificationSender(msgRpcClient *rpcclient.MessageRpcClient) *ConversationNotificationSender {
return &ConversationNotificationSender{rpcclient.NewNotificationSender(rpcclient.WithRpcClient(msgRpcClient))}
}
// SetPrivate调用
// SetPrivate调用.
func (c *ConversationNotificationSender) ConversationSetPrivateNotification(
ctx context.Context,
sendID, recvID string,
@ -44,7 +46,7 @@ func (c *ConversationNotificationSender) ConversationSetPrivateNotification(
return c.Notification(ctx, sendID, recvID, constant.ConversationPrivateChatNotification, tips)
}
// 会话改变
// 会话改变.
func (c *ConversationNotificationSender) ConversationChangeNotification(ctx context.Context, userID string) error {
tips := &sdkws.ConversationUpdateTips{
UserID: userID,
@ -52,7 +54,7 @@ func (c *ConversationNotificationSender) ConversationChangeNotification(ctx cont
return c.Notification(ctx, userID, userID, constant.ConversationChangeNotification, tips)
}
// 会话未读数同步
// 会话未读数同步.
func (c *ConversationNotificationSender) ConversationUnreadChangeNotification(
ctx context.Context,
userID, conversationID string,

@ -18,8 +18,6 @@ import (
"context"
"encoding/json"
"google.golang.org/protobuf/proto"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
@ -28,16 +26,20 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"google.golang.org/protobuf/proto"
)
// define a extend message notificaion sender
type ExtendMsgNotificationSender struct {
*rpcclient.MessageRpcClient
}
// new extend message notification sender
func NewExtendMsgNotificationSender(client discoveryregistry.SvcDiscoveryRegistry) *ExtendMsgNotificationSender {
return &ExtendMsgNotificationSender{}
}
// extend message updated notification
func (e *ExtendMsgNotificationSender) ExtendMessageUpdatedNotification(
ctx context.Context,
sendID string,
@ -78,6 +80,7 @@ func (e *ExtendMsgNotificationSender) ExtendMessageUpdatedNotification(
)
}
// extend message deleted notification
func (e *ExtendMsgNotificationSender) ExtendMessageDeleteNotification(
ctx context.Context,
sendID string,
@ -116,6 +119,7 @@ func (e *ExtendMsgNotificationSender) ExtendMessageDeleteNotification(
)
}
// message reaction sender
func (e *ExtendMsgNotificationSender) messageReactionSender(
ctx context.Context,
sendID string,

@ -17,17 +17,17 @@ package notification
import (
"context"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/convert"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller"
relationTb "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/relation"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
pbFriend "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/friend"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
)
// define a friend notification sender struct
type FriendNotificationSender struct {
*rpcclient.NotificationSender
// 找不到报错
@ -36,14 +36,17 @@ type FriendNotificationSender struct {
db controller.FriendDatabase
}
// friend notification send option
type friendNotificationSenderOptions func(*FriendNotificationSender)
// friend db
func WithFriendDB(db controller.FriendDatabase) friendNotificationSenderOptions {
return func(s *FriendNotificationSender) {
s.db = db
}
}
// db func
func WithDBFunc(
fn func(ctx context.Context, userIDs []string) (users []*relationTb.UserModel, err error),
) friendNotificationSenderOptions {
@ -62,6 +65,7 @@ func WithDBFunc(
}
}
// rpc
func WithRpcFunc(
fn func(ctx context.Context, userIDs []string) ([]*sdkws.UserInfo, error),
) friendNotificationSenderOptions {
@ -80,6 +84,7 @@ func WithRpcFunc(
}
}
// a new friend notification send
func NewFriendNotificationSender(
msgRpcClient *rpcclient.MessageRpcClient,
opts ...friendNotificationSenderOptions,
@ -93,6 +98,7 @@ func NewFriendNotificationSender(
return f
}
// get user info group
func (f *FriendNotificationSender) getUsersInfoMap(
ctx context.Context,
userIDs []string,
@ -108,6 +114,7 @@ func (f *FriendNotificationSender) getUsersInfoMap(
return result, nil
}
// get from to user nickname
func (f *FriendNotificationSender) getFromToUserNickname(
ctx context.Context,
fromUserID, toUserID string,
@ -119,11 +126,13 @@ func (f *FriendNotificationSender) getFromToUserNickname(
return users[fromUserID].Nickname, users[toUserID].Nickname, nil
}
// user infi uodated notification
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)
}
// friend application added notification
func (f *FriendNotificationSender) FriendApplicationAddNotification(
ctx context.Context,
req *pbFriend.ApplyToAddFriendReq,
@ -135,6 +144,7 @@ func (f *FriendNotificationSender) FriendApplicationAddNotification(
return f.Notification(ctx, req.FromUserID, req.ToUserID, constant.FriendApplicationNotification, &tips)
}
// friend application agreed notification
func (c *FriendNotificationSender) FriendApplicationAgreedNotification(
ctx context.Context,
req *pbFriend.RespondFriendApplyReq,
@ -146,6 +156,7 @@ func (c *FriendNotificationSender) FriendApplicationAgreedNotification(
return c.Notification(ctx, req.ToUserID, req.FromUserID, constant.FriendApplicationApprovedNotification, &tips)
}
// friend application refused notification
func (c *FriendNotificationSender) FriendApplicationRefusedNotification(
ctx context.Context,
req *pbFriend.RespondFriendApplyReq,
@ -157,6 +168,7 @@ func (c *FriendNotificationSender) FriendApplicationRefusedNotification(
return c.Notification(ctx, req.ToUserID, req.FromUserID, constant.FriendApplicationRejectedNotification, &tips)
}
// friend added notification
func (c *FriendNotificationSender) FriendAddedNotification(
ctx context.Context,
operationID, opUserID, fromUserID, toUserID string,
@ -181,6 +193,7 @@ func (c *FriendNotificationSender) FriendAddedNotification(
return c.Notification(ctx, fromUserID, toUserID, constant.FriendAddedNotification, &tips)
}
// friend deleted notification
func (c *FriendNotificationSender) FriendDeletedNotification(ctx context.Context, req *pbFriend.DeleteFriendReq) error {
tips := sdkws.FriendDeletedTips{FromToUserID: &sdkws.FromToUserID{
FromUserID: req.OwnerUserID,
@ -189,6 +202,7 @@ func (c *FriendNotificationSender) FriendDeletedNotification(ctx context.Context
return c.Notification(ctx, req.OwnerUserID, req.FriendUserID, constant.FriendDeletedNotification, &tips)
}
// friend remark set notification
func (c *FriendNotificationSender) FriendRemarkSetNotification(ctx context.Context, fromUserID, toUserID string) error {
tips := sdkws.FriendInfoChangedTips{FromToUserID: &sdkws.FromToUserID{}}
tips.FromToUserID.FromUserID = fromUserID
@ -196,6 +210,7 @@ func (c *FriendNotificationSender) FriendRemarkSetNotification(ctx context.Conte
return c.Notification(ctx, fromUserID, toUserID, constant.FriendRemarkSetNotification, &tips)
}
// black added notification
func (c *FriendNotificationSender) BlackAddedNotification(ctx context.Context, req *pbFriend.AddBlackReq) error {
tips := sdkws.BlackAddedTips{FromToUserID: &sdkws.FromToUserID{}}
tips.FromToUserID.FromUserID = req.OwnerUserID
@ -203,6 +218,7 @@ func (c *FriendNotificationSender) BlackAddedNotification(ctx context.Context, r
return c.Notification(ctx, req.OwnerUserID, req.BlackUserID, constant.BlackAddedNotification, &tips)
}
// black delter notification
func (c *FriendNotificationSender) BlackDeletedNotification(ctx context.Context, req *pbFriend.RemoveBlackReq) {
blackDeletedTips := sdkws.BlackDeletedTips{FromToUserID: &sdkws.FromToUserID{
FromUserID: req.OwnerUserID,
@ -211,6 +227,7 @@ func (c *FriendNotificationSender) BlackDeletedNotification(ctx context.Context,
c.Notification(ctx, req.OwnerUserID, req.BlackUserID, constant.BlackDeletedNotification, &blackDeletedTips)
}
// friend info updated notification
func (c *FriendNotificationSender) FriendInfoUpdatedNotification(
ctx context.Context,
changedUserID string,

@ -42,12 +42,14 @@ func NewGroupNotificationSender(
}
}
// type a group notification sender struct
type GroupNotificationSender struct {
*rpcclient.NotificationSender
getUsersInfo func(ctx context.Context, userIDs []string) ([]CommonUser, error)
db controller.GroupDatabase
}
// get user
func (g *GroupNotificationSender) getUser(ctx context.Context, userID string) (*sdkws.PublicUserInfo, error) {
users, err := g.getUsersInfo(ctx, []string{userID})
if err != nil {
@ -64,6 +66,7 @@ func (g *GroupNotificationSender) getUser(ctx context.Context, userID string) (*
}, nil
}
// get group info
func (g *GroupNotificationSender) getGroupInfo(ctx context.Context, groupID string) (*sdkws.GroupInfo, error) {
gm, err := g.db.TakeGroup(ctx, groupID)
if err != nil {
@ -98,6 +101,7 @@ func (g *GroupNotificationSender) getGroupInfo(ctx context.Context, groupID stri
}, nil
}
// get group members
func (g *GroupNotificationSender) getGroupMembers(
ctx context.Context,
groupID string,
@ -141,6 +145,7 @@ func (g *GroupNotificationSender) getGroupMembers(
return res, nil
}
// get group member map
func (g *GroupNotificationSender) getGroupMemberMap(
ctx context.Context,
groupID string,
@ -157,6 +162,7 @@ func (g *GroupNotificationSender) getGroupMemberMap(
return m, nil
}
// get group member
func (g *GroupNotificationSender) getGroupMember(
ctx context.Context,
groupID string,
@ -172,6 +178,7 @@ func (g *GroupNotificationSender) getGroupMember(
return members[0], nil
}
// get group owner and admin user id
func (g *GroupNotificationSender) getGroupOwnerAndAdminUserID(ctx context.Context, groupID string) ([]string, error) {
members, err := g.db.FindGroupMember(ctx, []string{groupID}, nil, []int32{constant.GroupOwner, constant.GroupAdmin})
if err != nil {
@ -181,6 +188,7 @@ func (g *GroupNotificationSender) getGroupOwnerAndAdminUserID(ctx context.Contex
return utils.Slice(members, fn), nil
}
// get group db2pb
func (g *GroupNotificationSender) groupDB2PB(
group *relation.GroupModel,
ownerUserID string,
@ -207,6 +215,7 @@ func (g *GroupNotificationSender) groupDB2PB(
}
}
// get group member db2pb
func (g *GroupNotificationSender) groupMemberDB2PB(
member *relation.GroupMemberModel,
appMangerLevel int32,
@ -227,6 +236,7 @@ func (g *GroupNotificationSender) groupMemberDB2PB(
}
}
// get user info map
func (g *GroupNotificationSender) getUsersInfoMap(
ctx context.Context,
userIDs []string,
@ -242,6 +252,7 @@ func (g *GroupNotificationSender) getUsersInfoMap(
return result, nil
}
// fill op user
func (g *GroupNotificationSender) fillOpUser(
ctx context.Context,
opUser **sdkws.GroupMemberFullInfo,
@ -285,6 +296,7 @@ func (g *GroupNotificationSender) fillOpUser(
return nil
}
// group created notification
func (g *GroupNotificationSender) GroupCreatedNotification(
ctx context.Context,
tips *sdkws.GroupCreatedTips,
@ -295,6 +307,7 @@ func (g *GroupNotificationSender) GroupCreatedNotification(
return g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupCreatedNotification, tips)
}
// group info set notification
func (g *GroupNotificationSender) GroupInfoSetNotification(
ctx context.Context,
tips *sdkws.GroupInfoSetTips,
@ -305,6 +318,7 @@ func (g *GroupNotificationSender) GroupInfoSetNotification(
return g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupInfoSetNotification, tips)
}
// group info set name notification
func (g *GroupNotificationSender) GroupInfoSetNameNotification(
ctx context.Context,
tips *sdkws.GroupInfoSetNameTips,
@ -321,6 +335,7 @@ func (g *GroupNotificationSender) GroupInfoSetNameNotification(
)
}
// group info set announcement notification
func (g *GroupNotificationSender) GroupInfoSetAnnouncementNotification(
ctx context.Context,
tips *sdkws.GroupInfoSetAnnouncementTips,
@ -337,6 +352,7 @@ func (g *GroupNotificationSender) GroupInfoSetAnnouncementNotification(
)
}
// join group application notification
func (g *GroupNotificationSender) JoinGroupApplicationNotification(
ctx context.Context,
req *pbGroup.JoinGroupReq,
@ -364,6 +380,7 @@ func (g *GroupNotificationSender) JoinGroupApplicationNotification(
return nil
}
// member quit notification
func (g *GroupNotificationSender) MemberQuitNotification(
ctx context.Context,
member *sdkws.GroupMemberFullInfo,
@ -382,6 +399,7 @@ func (g *GroupNotificationSender) MemberQuitNotification(
return g.Notification(ctx, mcontext.GetOpUserID(ctx), member.GroupID, constant.MemberQuitNotification, tips)
}
// group application accepted notification
func (g *GroupNotificationSender) GroupApplicationAcceptedNotification(
ctx context.Context,
req *pbGroup.GroupApplicationResponseReq,
@ -419,6 +437,7 @@ func (g *GroupNotificationSender) GroupApplicationAcceptedNotification(
return nil
}
// group application rejected notification
func (g *GroupNotificationSender) GroupApplicationRejectedNotification(
ctx context.Context,
req *pbGroup.GroupApplicationResponseReq,
@ -450,6 +469,7 @@ func (g *GroupNotificationSender) GroupApplicationRejectedNotification(
return nil
}
// Group Owner Transferred Notification
func (g *GroupNotificationSender) GroupOwnerTransferredNotification(
ctx context.Context,
req *pbGroup.TransferGroupOwnerReq,
@ -480,6 +500,7 @@ func (g *GroupNotificationSender) GroupOwnerTransferredNotification(
)
}
// member kick out notification
func (g *GroupNotificationSender) MemberKickedNotification(
ctx context.Context,
tips *sdkws.MemberKickedTips,
@ -490,6 +511,7 @@ func (g *GroupNotificationSender) MemberKickedNotification(
return g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.MemberKickedNotification, tips)
}
// member invited notification
func (g *GroupNotificationSender) MemberInvitedNotification(
ctx context.Context,
groupID, reason string,
@ -513,6 +535,7 @@ func (g *GroupNotificationSender) MemberInvitedNotification(
return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.MemberInvitedNotification, tips)
}
// member enter notification
func (g *GroupNotificationSender) MemberEnterNotification(
ctx context.Context,
req *pbGroup.GroupApplicationResponseReq,
@ -529,6 +552,7 @@ func (g *GroupNotificationSender) MemberEnterNotification(
return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.MemberEnterNotification, tips)
}
// group dismissed notification
func (g *GroupNotificationSender) GroupDismissedNotification(
ctx context.Context,
tips *sdkws.GroupDismissedTips,
@ -539,6 +563,7 @@ func (g *GroupNotificationSender) GroupDismissedNotification(
return g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupDismissedNotification, tips)
}
// group member muted notification
func (g *GroupNotificationSender) GroupMemberMutedNotification(
ctx context.Context,
groupID, groupMemberUserID string,
@ -560,6 +585,7 @@ func (g *GroupNotificationSender) GroupMemberMutedNotification(
return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberMutedNotification, tips)
}
// group member cancel nuted notification
func (g *GroupNotificationSender) GroupMemberCancelMutedNotification(
ctx context.Context,
groupID, groupMemberUserID string,
@ -589,6 +615,7 @@ func (g *GroupNotificationSender) GroupMemberCancelMutedNotification(
)
}
// group muted notification
func (g *GroupNotificationSender) GroupMutedNotification(ctx context.Context, groupID string) (err error) {
group, err := g.getGroupInfo(ctx, groupID)
if err != nil {
@ -608,6 +635,7 @@ func (g *GroupNotificationSender) GroupMutedNotification(ctx context.Context, gr
return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMutedNotification, tips)
}
// group cancel notification
func (g *GroupNotificationSender) GroupCancelMutedNotification(ctx context.Context, groupID string) (err error) {
group, err := g.getGroupInfo(ctx, groupID)
if err != nil {
@ -621,12 +649,13 @@ func (g *GroupNotificationSender) GroupCancelMutedNotification(ctx context.Conte
if len(users) > 0 {
tips.OpUser = users[0]
}
if err := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil {
return err
if err2 := g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil {
return err2
}
return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupCancelMutedNotification, tips)
}
// group member info set notification
func (g *GroupNotificationSender) GroupMemberInfoSetNotification(
ctx context.Context,
groupID, groupMemberUserID string,
@ -650,6 +679,7 @@ func (g *GroupNotificationSender) GroupMemberInfoSetNotification(
return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberInfoSetNotification, tips)
}
// group member set to admin notification
func (g *GroupNotificationSender) GroupMemberSetToAdminNotification(
ctx context.Context,
groupID, groupMemberUserID string,
@ -679,6 +709,7 @@ func (g *GroupNotificationSender) GroupMemberSetToAdminNotification(
)
}
// group member set to ordinary user notification
func (g *GroupNotificationSender) GroupMemberSetToOrdinaryUserNotification(
ctx context.Context,
groupID, groupMemberUserID string,
@ -708,6 +739,7 @@ func (g *GroupNotificationSender) GroupMemberSetToOrdinaryUserNotification(
)
}
// member enter directly notification
func (g *GroupNotificationSender) MemberEnterDirectlyNotification(
ctx context.Context,
groupID string,
@ -731,6 +763,7 @@ func (g *GroupNotificationSender) MemberEnterDirectlyNotification(
return g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.MemberEnterNotification, tips)
}
// super group notification
func (g *GroupNotificationSender) SuperGroupNotification(ctx context.Context, sendID, recvID string) (err error) {
defer log.ZDebug(ctx, "return")
defer func() {

@ -19,8 +19,6 @@ import (
"strings"
"time"
"google.golang.org/grpc"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
@ -28,6 +26,7 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/user"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"google.golang.org/grpc"
)
type User struct {
@ -37,7 +36,8 @@ type User struct {
}
func NewUser(discov discoveryregistry.SvcDiscoveryRegistry) *User {
ctx, _ := context.WithTimeout(context.Background(), time.Second*3)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
defer cancel()
conn, err := discov.GetConn(ctx, config.Config.RpcRegisterName.OpenImUserName)
if err != nil {
panic(err)

@ -21,6 +21,7 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
)
// type a statistics struct
type Statistics struct {
AllCount *uint64
ModuleName string
@ -28,6 +29,7 @@ type Statistics struct {
SleepTime uint64
}
// output
func (s *Statistics) output() {
var intervalCount uint64
t := time.NewTicker(time.Duration(s.SleepTime) * time.Second)
@ -63,6 +65,7 @@ func (s *Statistics) output() {
}
}
// create a new statistics
func NewStatistics(allCount *uint64, moduleName, printArgs string, sleepTime int) *Statistics {
p := &Statistics{AllCount: allCount, ModuleName: moduleName, SleepTime: uint64(sleepTime), PrintArgs: printArgs}
go p.output()

@ -16,10 +16,12 @@ package utils
import "encoding/base64"
// base64 encode
func Base64Encode(data string) string {
return base64.StdEncoding.EncodeToString([]byte(data))
}
// base64 decode
func Base64Decode(data string) string {
decodedByte, _ := base64.StdEncoding.DecodeString(data)
return string(decodedByte)

@ -23,6 +23,7 @@ import (
"errors"
)
// md5 encrypt
func Md5(s string, salt ...string) string {
h := md5.New()
h.Write([]byte(s))
@ -33,6 +34,7 @@ func Md5(s string, salt ...string) string {
return hex.EncodeToString(cipher)
}
// aes encrypt
func AesEncrypt(data []byte, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
@ -46,6 +48,7 @@ func AesEncrypt(data []byte, key []byte) ([]byte, error) {
return crypted, nil
}
// aes decrypt
func AesDecrypt(data []byte, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
@ -62,12 +65,14 @@ func AesDecrypt(data []byte, key []byte) ([]byte, error) {
return crypted, nil
}
// PKCS7 padding on a byte array
func pkcs7Padding(data []byte, blockSize int) []byte {
padding := blockSize - len(data)%blockSize
padText := bytes.Repeat([]byte{byte(padding)}, padding)
return append(data, padText...)
}
// PKCS7 padding removal on a byte array
func pkcs7UnPadding(data []byte) ([]byte, error) {
length := len(data)
if length == 0 {

@ -55,6 +55,7 @@ func MkDir(path string) error {
return os.MkdirAll(path, os.ModePerm)
}
// get new file name and content type
func GetNewFileNameAndContentType(fileName string, fileType int) (string, string) {
suffix := path.Ext(fileName)
newName := fmt.Sprintf("%d-%d%s", time.Now().UnixNano(), rand.Int(), fileName)
@ -65,6 +66,7 @@ func GetNewFileNameAndContentType(fileName string, fileType int) (string, string
return newName, contentType
}
// get byte size
func ByteSize(bytes uint64) string {
unit := ""
value := float64(bytes)

@ -27,6 +27,7 @@ import (
"golang.org/x/image/bmp"
)
// generate image small
func GenSmallImage(src, dst string) error {
fIn, _ := os.Open(src)
defer fIn.Close()

@ -24,7 +24,7 @@ import (
var (
_, b, _, _ = runtime.Caller(0)
// Root folder of this project
// Root folder of this project
Root = filepath.Join(filepath.Dir(b), "../..")
)

@ -24,12 +24,14 @@ type Map struct {
m map[interface{}]interface{}
}
// init map by make method
func (m *Map) init() {
if m.m == nil {
m.m = make(map[interface{}]interface{})
}
}
// / get unsafe
func (m *Map) UnsafeGet(key interface{}) interface{} {
if m.m == nil {
return nil
@ -44,6 +46,7 @@ func (m *Map) Get(key interface{}) interface{} {
return m.UnsafeGet(key)
}
// set by unsafe
func (m *Map) UnsafeSet(key interface{}, value interface{}) {
m.init()
m.m[key] = value
@ -55,6 +58,7 @@ func (m *Map) Set(key interface{}, value interface{}) {
m.UnsafeSet(key, value)
}
// test and set
func (m *Map) TestAndSet(key interface{}, value interface{}) interface{} {
m.Lock()
defer m.Unlock()
@ -69,6 +73,7 @@ func (m *Map) TestAndSet(key interface{}, value interface{}) interface{} {
}
}
// dele by unsafe
func (m *Map) UnsafeDel(key interface{}) {
m.init()
delete(m.m, key)
@ -80,6 +85,7 @@ func (m *Map) Del(key interface{}) {
m.UnsafeDel(key)
}
// get unsafe length
func (m *Map) UnsafeLen() int {
if m.m == nil {
return 0
@ -88,12 +94,14 @@ func (m *Map) UnsafeLen() int {
}
}
// get length
func (m *Map) Len() int {
m.RLock()
defer m.RUnlock()
return m.UnsafeLen()
}
// judege unsafe range
func (m *Map) UnsafeRange(f func(interface{}, interface{})) {
if m.m == nil {
return

@ -19,6 +19,7 @@ import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
type Options map[string]bool
type OptionsOpt func(Options)
// new option
func NewOptions(opts ...OptionsOpt) Options {
options := make(map[string]bool, 11)
options[constant.IsNotNotification] = false
@ -39,12 +40,14 @@ func NewOptions(opts ...OptionsOpt) Options {
return options
}
// new message option
func NewMsgOptions() Options {
options := make(map[string]bool, 11)
options[constant.IsOfflinePush] = false
return make(map[string]bool)
}
// WithOptions
func WithOptions(options Options, opts ...OptionsOpt) Options {
for _, opt := range opts {
opt(options)
@ -52,78 +55,91 @@ func WithOptions(options Options, opts ...OptionsOpt) Options {
return options
}
// WithNotNotification
func WithNotNotification(b bool) OptionsOpt {
return func(options Options) {
options[constant.IsNotNotification] = b
}
}
// WithSendMsg
func WithSendMsg(b bool) OptionsOpt {
return func(options Options) {
options[constant.IsSendMsg] = b
}
}
// WithHistory
func WithHistory(b bool) OptionsOpt {
return func(options Options) {
options[constant.IsHistory] = b
}
}
// WithPersistent
func WithPersistent() OptionsOpt {
return func(options Options) {
options[constant.IsPersistent] = true
}
}
// WithOfflinePush
func WithOfflinePush(b bool) OptionsOpt {
return func(options Options) {
options[constant.IsOfflinePush] = b
}
}
// unread count
func WithUnreadCount(b bool) OptionsOpt {
return func(options Options) {
options[constant.IsUnreadCount] = b
}
}
// WithConversationUpdate
func WithConversationUpdate() OptionsOpt {
return func(options Options) {
options[constant.IsConversationUpdate] = true
}
}
// WithSenderSync
func WithSenderSync() OptionsOpt {
return func(options Options) {
options[constant.IsSenderSync] = true
}
}
// WithNotPrivate
func WithNotPrivate() OptionsOpt {
return func(options Options) {
options[constant.IsNotPrivate] = true
}
}
// WithSenderConversationUpdate
func WithSenderConversationUpdate() OptionsOpt {
return func(options Options) {
options[constant.IsSenderConversationUpdate] = true
}
}
// WithSenderNotificationPush
func WithSenderNotificationPush() OptionsOpt {
return func(options Options) {
options[constant.IsSenderNotificationPush] = true
}
}
// react from cache is or not
func WithReactionFromCache() OptionsOpt {
return func(options Options) {
options[constant.IsReactionFromCache] = true
}
}
// is or not exit in map named o
func (o Options) Is(notification string) bool {
v, ok := o[notification]
if !ok || v {
@ -132,50 +148,62 @@ func (o Options) Is(notification string) bool {
return false
}
// is or nit notification
func (o Options) IsNotNotification() bool {
return o.Is(constant.IsNotNotification)
}
// is or not send msg
func (o Options) IsSendMsg() bool {
return o.Is(constant.IsSendMsg)
}
// is or not a history
func (o Options) IsHistory() bool {
return o.Is(constant.IsHistory)
}
// is or not persistent
func (o Options) IsPersistent() bool {
return o.Is(constant.IsPersistent)
}
// is oor not push offline
func (o Options) IsOfflinePush() bool {
return o.Is(constant.IsOfflinePush)
}
// unread count
func (o Options) IsUnreadCount() bool {
return o.Is(constant.IsUnreadCount)
}
// is or not conversation update
func (o Options) IsConversationUpdate() bool {
return o.Is(constant.IsConversationUpdate)
}
// is or not send async
func (o Options) IsSenderSync() bool {
return o.Is(constant.IsSenderSync)
}
// is or not private
func (o Options) IsNotPrivate() bool {
return o.Is(constant.IsNotPrivate)
}
// is or not notification push update
func (o Options) IsSenderConversationUpdate() bool {
return o.Is(constant.IsSenderConversationUpdate)
}
// is or not notification push sender
func (o Options) IsSenderNotificationPush() bool {
return o.Is(constant.IsSenderNotificationPush)
}
// reaction is or not from cache
func (o Options) IsReactionFromCache() bool {
return o.Is(constant.IsReactionFromCache)
}

@ -16,6 +16,7 @@ package utils
import "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
// get page
func GetPage(pagination *sdkws.RequestPagination) (pageNumber, showNumber int32) {
if pagination != nil {
return pagination.PageNumber, pagination.ShowNumber

@ -22,6 +22,7 @@ import (
"time"
)
// const constants
var (
ErrorAbort = errors.New("stop retry")
ErrorTimeout = errors.New("retry timeout")
@ -30,10 +31,19 @@ var (
ErrorTimeFormat = errors.New("time out err")
)
// define a retry func
type RetriesFunc func() error
// option func
type Option func(c *Config)
// define hook func
type HookFunc func()
// define a retry check func
type RetriesChecker func(err error) (needRetry bool)
// type a config struct
type Config struct {
MaxRetryTimes int
Timeout time.Duration
@ -44,6 +54,7 @@ type Config struct {
AfterTry HookFunc
}
// const constants
var (
DefaultMaxRetryTimes = 3
DefaultTimeout = time.Minute
@ -53,6 +64,7 @@ var (
}
)
// create a default config
func newDefaultConfig() *Config {
return &Config{
MaxRetryTimes: DefaultMaxRetryTimes,
@ -64,42 +76,49 @@ func newDefaultConfig() *Config {
}
}
// with time out
func WithTimeout(timeout time.Duration) Option {
return func(c *Config) {
c.Timeout = timeout
}
}
// with max retry times
func WithMaxRetryTimes(times int) Option {
return func(c *Config) {
c.MaxRetryTimes = times
}
}
// with recover panic
func WithRecoverPanic() Option {
return func(c *Config) {
c.RecoverPanic = true
}
}
// a before hook
func WithBeforeHook(hook HookFunc) Option {
return func(c *Config) {
c.BeforeTry = hook
}
}
// a hook with after
func WithAfterHook(hook HookFunc) Option {
return func(c *Config) {
c.AfterTry = hook
}
}
// retry check
func WithRetryChecker(checker RetriesChecker) Option {
return func(c *Config) {
c.RetryChecker = checker
}
}
// with backoff strategy
func WithBackOffStrategy(s BackoffStrategy, duration time.Duration) Option {
return func(c *Config) {
switch s {
@ -113,12 +132,14 @@ func WithBackOffStrategy(s BackoffStrategy, duration time.Duration) Option {
}
}
// with custom strategy
func WithCustomStrategy(s Strategy) Option {
return func(c *Config) {
c.Strategy = s
}
}
// do
func Do(ctx context.Context, fn RetriesFunc, opts ...Option) error {
if fn == nil {
return ErrorEmptyRetryFunc
@ -146,7 +167,7 @@ func Do(ctx context.Context, fn RetriesFunc, opts ...Option) error {
if e := recover(); e == nil {
return
} else {
panicInfoChan <- fmt.Sprintf("retry function panic has occured, err=%v, stack:%s", e, string(debug.Stack()))
panicInfoChan <- fmt.Sprintf("retry function panic has occurred, err=%v, stack:%s", e, string(debug.Stack()))
}
}()
for i := 0; i < config.MaxRetryTimes; i++ {

@ -16,51 +16,65 @@ package retry
import "time"
// renamed int to backofstrategy
type BackoffStrategy int
// const a constant
const (
StrategyConstant BackoffStrategy = iota
StrategyLinear
StrategyFibonacci
)
// define a interface of strategy
type Strategy interface {
Sleep(times int) time.Duration
}
// define constant struct
type Constant struct {
startInterval time.Duration
}
// define a new constant
func NewConstant(d time.Duration) *Constant {
return &Constant{startInterval: d}
}
// define a linear struct
type Linear struct {
startInterval time.Duration
}
// define a new linear function
func NewLinear(d time.Duration) *Linear {
return &Linear{startInterval: d}
}
// define fibonacci struct
type Fibonacci struct {
startInterval time.Duration
}
// new fibonacci function
func NewFibonacci(d time.Duration) *Fibonacci {
return &Fibonacci{startInterval: d}
}
// sleep reload
func (c *Constant) Sleep(_ int) time.Duration {
return c.startInterval
}
// sleep reload
func (l *Linear) Sleep(times int) time.Duration {
return l.startInterval * time.Duration(times)
}
// sleep
func (f *Fibonacci) Sleep(times int) time.Duration {
return f.startInterval * time.Duration(fibonacciNumber(times))
}
func fibonacciNumber(n int) int {
if n == 0 || n == 1 {

@ -12,26 +12,35 @@ import (
"strconv"
)
// transfer int to string
func IntToString(i int) string {
return strconv.FormatInt(int64(i), 10)
}
// transfer string to int
func StringToInt(i string) int {
j, _ := strconv.Atoi(i)
return j
}
// transfer string to int64
func StringToInt64(i string) int64 {
j, _ := strconv.ParseInt(i, 10, 64)
return j
}
// transfer string to int32
func StringToInt32(i string) int32 {
j, _ := strconv.ParseInt(i, 10, 64)
return int32(j)
}
// transfer int32 to string
func Int32ToString(i int32) string {
return strconv.FormatInt(int64(i), 10)
}
// transfer unit32 to string
func Uint32ToString(i uint32) string {
return strconv.FormatInt(int64(i), 10)
}
@ -46,6 +55,8 @@ func IsContain(target string, List []string) bool {
}
return false
}
// contain int32 or not
func IsContainInt32(target int32, List []int32) bool {
for _, element := range List {
if target == element {
@ -54,6 +65,8 @@ func IsContainInt32(target int32, List []int32) bool {
}
return false
}
// contain int or not
func IsContainInt(target int, List []int) bool {
for _, element := range List {
if target == element {
@ -62,18 +75,23 @@ func IsContainInt(target int, List []int) bool {
}
return false
}
// transfer array to string array
func InterfaceArrayToStringArray(data []interface{}) (i []string) {
for _, param := range data {
i = append(i, param.(string))
}
return i
}
// transfer struct to json string
func StructToJsonString(param interface{}) string {
dataType, _ := json.Marshal(param)
dataString := string(dataType)
return dataString
}
// transfer struct to jsonBytes
func StructToJsonBytes(param interface{}) []byte {
dataType, _ := json.Marshal(param)
return dataType
@ -85,11 +103,13 @@ func JsonStringToStruct(s string, args interface{}) error {
return err
}
// get message ID
func GetMsgID(sendID string) string {
t := int64ToString(GetCurrentTimestampByNano())
return Md5(t + sendID + int64ToString(rand.Int63n(GetCurrentTimestampByNano())))
}
// transfer int64 to string
func int64ToString(i int64) string {
return strconv.FormatInt(i, 10)
}
@ -97,6 +117,7 @@ func Int64ToString(i int64) string {
return strconv.FormatInt(i, 10)
}
// remove duplicate elment
func RemoveDuplicateElement(idList []string) []string {
result := make([]string, 0, len(idList))
temp := map[string]struct{}{}
@ -109,6 +130,7 @@ func RemoveDuplicateElement(idList []string) []string {
return result
}
// remove duplicate
func RemoveDuplicate[T comparable](arr []T) []T {
result := make([]T, 0, len(arr))
temp := map[T]struct{}{}
@ -121,6 +143,7 @@ func RemoveDuplicate[T comparable](arr []T) []T {
return result
}
// judege is or not a duplicated string clice
func IsDuplicateStringSlice(arr []string) bool {
t := make(map[string]struct{})
for _, s := range arr {

@ -1,9 +1,3 @@
/*
** description("").
** copyright('tuoyun,www.tuoyun.net').
** author("fg,Gordon@tuoyun.net").
** time(2021/2/22 11:52).
*/
package utils
import (
@ -74,16 +68,19 @@ func GetTimeStampByFormat(datetime string) string {
return strconv.FormatInt(timestamp, 10)
}
// time format from string to unix
func TimeStringFormatTimeUnix(timeFormat string, timeSrc string) int64 {
tm, _ := time.Parse(timeFormat, timeSrc)
return tm.Unix()
}
// time string to time time
func TimeStringToTime(timeString string) (time.Time, error) {
t, err := time.Parse("2006-01-02", timeString)
return t, err
}
// time to time string
func TimeToString(t time.Time) string {
return t.Format("2006-01-02")
}

@ -23,13 +23,12 @@ import (
"strings"
"time"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
"google.golang.org/protobuf/proto"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
)
// copy a by b b->a
@ -166,6 +165,7 @@ func DifferenceString(slice1, slice2 []string) []string {
return n
}
// generate operation ID
func OperationIDGenerator() string {
return strconv.FormatInt(time.Now().UnixNano()+int64(rand.Uint32()), 10)
}
@ -182,10 +182,12 @@ func String2Pb(s string, pb proto.Message) error {
return proto.Unmarshal([]byte(s), pb)
}
// get hash code
func GetHashCode(s string) uint32 {
return crc32.ChecksumIEEE([]byte(s))
}
// get notification conversation ID
func GetNotificationConversationID(msg *sdkws.MsgData) string {
switch msg.SessionType {
case constant.SingleChatType:
@ -202,6 +204,7 @@ func GetNotificationConversationID(msg *sdkws.MsgData) string {
return ""
}
// get chat conversation ID by message
func GetChatConversationIDByMsg(msg *sdkws.MsgData) string {
switch msg.SessionType {
case constant.SingleChatType:
@ -218,26 +221,31 @@ func GetChatConversationIDByMsg(msg *sdkws.MsgData) string {
return ""
}
// get conversation ID for single
func GenConversationIDForSingle(sendID, recvID string) string {
l := []string{sendID, recvID}
sort.Strings(l)
return "si_" + strings.Join(l, "_")
}
// get conversation ID unique key for group
func GenConversationUniqueKeyForGroup(groupID string) string {
return groupID
}
// generate group conversation ID
func GenGroupConversationID(groupID string) string {
return "sg_" + groupID
}
// generate conversation unique key for single
func GenConversationUniqueKeyForSingle(sendID, recvID string) string {
l := []string{sendID, recvID}
sort.Strings(l)
return strings.Join(l, "_")
}
// generate conversation unique key
func GenConversationUniqueKey(msg *sdkws.MsgData) string {
switch msg.SessionType {
case constant.SingleChatType, constant.NotificationChatType:
@ -250,6 +258,7 @@ func GenConversationUniqueKey(msg *sdkws.MsgData) string {
return ""
}
// get conversation ID by mesage model
func GetConversationIDByMsgModel(msg *unrelation.MsgDataModel) string {
options := Options(msg.Options)
switch msg.SessionType {
@ -279,6 +288,7 @@ func GetConversationIDByMsgModel(msg *unrelation.MsgDataModel) string {
return ""
}
// get conversation ID by message
func GetConversationIDByMsg(msg *sdkws.MsgData) string {
options := Options(msg.Options)
switch msg.SessionType {
@ -308,6 +318,7 @@ func GetConversationIDByMsg(msg *sdkws.MsgData) string {
return ""
}
// get conversation ID by session type
func GetConversationIDBySessionType(sessionType int, ids ...string) string {
sort.Strings(ids)
if len(ids) > 2 || len(ids) < 1 {
@ -326,14 +337,17 @@ func GetConversationIDBySessionType(sessionType int, ids ...string) string {
return ""
}
// judege is or not notification
func IsNotification(conversationID string) bool {
return strings.HasPrefix(conversationID, "n_")
}
// judege is or not notification by message
func IsNotificationByMsg(msg *sdkws.MsgData) bool {
return !Options(msg.Options).IsNotNotification()
}
// parse conversation ID
func ParseConversationID(msg *sdkws.MsgData) (isNotification bool, conversationID string) {
options := Options(msg.Options)
switch msg.SessionType {
@ -358,6 +372,7 @@ func ParseConversationID(msg *sdkws.MsgData) (isNotification bool, conversationI
return false, ""
}
// get notification conversation ID by conversation ID
func GetNotificationConversationIDByConversationID(conversationID string) string {
l := strings.Split(conversationID, "_")
if len(l) > 1 {
@ -367,6 +382,7 @@ func GetNotificationConversationIDByConversationID(conversationID string) string
return ""
}
// get seq begin to end
func GetSeqsBeginEnd(seqs []int64) (int64, int64) {
if len(seqs) == 0 {
return 0, 0
@ -374,6 +390,7 @@ func GetSeqsBeginEnd(seqs []int64) (int64, int64) {
return seqs[0], seqs[len(seqs)-1]
}
// type MsgBySeq
type MsgBySeq []*sdkws.MsgData
func (s MsgBySeq) Len() int {

@ -236,7 +236,7 @@ func Filter[E, T any](es []E, fn func(e E) (T, bool)) []T {
return rs
}
// Slice 批量转换切片类型
// Slice transfer slice batch
func Slice[E any, T any](es []E, fn func(e E) T) []T {
v := make([]T, len(es))
for i := 0; i < len(es); i++ {
@ -414,7 +414,7 @@ func SortAny[E any](es []E, fn func(a, b E) bool) {
})
}
// If true -> a, false -> b
// If true -> a, false -> b
func If[T any](isa bool, a, b T) T {
if isa {
return a
@ -426,7 +426,7 @@ func ToPtr[T any](t T) *T {
return &t
}
// Equal 比较切片是否相对(包括元素顺序)
// Compare slices to each other (including element order)
func Equal[E comparable](a []E, b []E) bool {
if len(a) != len(b) {
return false
@ -439,7 +439,7 @@ func Equal[E comparable](a []E, b []E) bool {
return true
}
// Single a中存在,b中不存在 或 b中存在,a中不存在
// Exists in a, does not exist in b or exists in b, does not exist in a
func Single[E comparable](a, b []E) []E {
kn := make(map[E]uint8)
for _, e := range Distinct(a) {
@ -457,7 +457,7 @@ func Single[E comparable](a, b []E) []E {
return v
}
// Order 将ts按es排序
// sort ts by es
func Order[E comparable, T any](es []E, ts []T, fn func(t T) E) []T {
if len(es) == 0 || len(ts) == 0 {
return ts
@ -485,6 +485,7 @@ func OrderPtr[E comparable, T any](es []E, ts *[]T, fn func(t T) E) []T {
return *ts
}
// join unique
func UniqueJoin(s ...string) string {
data, _ := json.Marshal(s)
return string(data)
@ -507,11 +508,12 @@ func (o *sortSlice[E]) Swap(i, j int) {
o.ts[i], o.ts[j] = o.ts[j], o.ts[i]
}
// Ordered types that can be sorted
// types that can be sorted
type Ordered interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | ~float32 | ~float64 | ~string
}
// unwrap
func Unwrap(err error) error {
for err != nil {
unwrap, ok := err.(interface {
@ -525,7 +527,7 @@ func Unwrap(err error) error {
return err
}
// NotNilReplace 当new_不为空时, 将old设置为new_
// NotNilReplace 当new_不为空时, 将old设置为new_
func NotNilReplace[T any](old, new_ *T) {
if new_ == nil {
return

Loading…
Cancel
Save