You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1178 lines
45 KiB
1178 lines
45 KiB
// Copyright © 2023 OpenIM SDK. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package conversation_msg
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
_ "github.com/openimsdk/openim-sdk-core/v3/internal/common"
|
|
"github.com/openimsdk/openim-sdk-core/v3/internal/util"
|
|
"github.com/openimsdk/openim-sdk-core/v3/pkg/common"
|
|
"github.com/openimsdk/openim-sdk-core/v3/pkg/constant"
|
|
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
|
|
sdk "github.com/openimsdk/openim-sdk-core/v3/pkg/sdk_params_callback"
|
|
"github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs"
|
|
"github.com/openimsdk/openim-sdk-core/v3/pkg/server_api_params"
|
|
"github.com/openimsdk/openim-sdk-core/v3/pkg/utils"
|
|
"github.com/openimsdk/openim-sdk-core/v3/sdk_struct"
|
|
"github.com/openimsdk/tools/utils/datautil"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/jinzhu/copier"
|
|
|
|
"github.com/openimsdk/tools/log"
|
|
|
|
"github.com/openimsdk/protocol/msg"
|
|
"github.com/openimsdk/protocol/sdkws"
|
|
|
|
pbConversation "github.com/openimsdk/protocol/conversation"
|
|
)
|
|
|
|
func (c *Conversation) setConversation(ctx context.Context, apiReq *pbConversation.SetConversationsReq, localConversation *model_struct.LocalConversation) error {
|
|
apiReq.Conversation.ConversationID = localConversation.ConversationID
|
|
apiReq.Conversation.ConversationType = localConversation.ConversationType
|
|
apiReq.Conversation.UserID = localConversation.UserID
|
|
apiReq.Conversation.GroupID = localConversation.GroupID
|
|
apiReq.UserIDs = []string{c.loginUserID}
|
|
if err := util.ApiPost(ctx, constant.SetConversationsRouter, apiReq, nil); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *Conversation) getServerConversationList(ctx context.Context) ([]*model_struct.LocalConversation, error) {
|
|
resp, err := util.CallApi[pbConversation.GetAllConversationsResp](ctx, constant.GetAllConversationsRouter, pbConversation.GetAllConversationsReq{OwnerUserID: c.loginUserID})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return datautil.Batch(ServerConversationToLocal, resp.Conversations), nil
|
|
}
|
|
|
|
func (c *Conversation) getServerConversationsByIDs(ctx context.Context, conversations []string) ([]*model_struct.LocalConversation, error) {
|
|
resp, err := util.CallApi[pbConversation.GetConversationsResp](ctx, constant.GetConversationsRouter, pbConversation.GetConversationsReq{OwnerUserID: c.loginUserID, ConversationIDs: conversations})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return datautil.Batch(ServerConversationToLocal, resp.Conversations), nil
|
|
}
|
|
|
|
func (c *Conversation) getServerHasReadAndMaxSeqs(ctx context.Context, conversationIDs ...string) (map[string]*msg.Seqs, error) {
|
|
resp := &msg.GetConversationsHasReadAndMaxSeqResp{}
|
|
req := msg.GetConversationsHasReadAndMaxSeqReq{UserID: c.loginUserID}
|
|
req.ConversationIDs = conversationIDs
|
|
err := util.ApiPost(ctx, constant.GetConversationsHasReadAndMaxSeqRouter, &req, resp)
|
|
if err != nil {
|
|
log.ZError(ctx, "getServerHasReadAndMaxSeqs err", err)
|
|
return nil, err
|
|
}
|
|
return resp.Seqs, nil
|
|
}
|
|
|
|
func (c *Conversation) getAdvancedHistoryMessageList(ctx context.Context, req sdk.GetAdvancedHistoryMessageListParams, isReverse bool) (*sdk.GetAdvancedHistoryMessageListCallback, error) {
|
|
t := time.Now()
|
|
var messageListCallback sdk.GetAdvancedHistoryMessageListCallback
|
|
var conversationID string
|
|
var startTime int64
|
|
var sessionType int
|
|
var list []*model_struct.LocalChatLog
|
|
var err error
|
|
var messageList sdk_struct.NewMsgList
|
|
var notStartTime bool
|
|
conversationID = req.ConversationID
|
|
lc, err := c.db.GetConversation(ctx, conversationID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
sessionType = int(lc.ConversationType)
|
|
if req.StartClientMsgID == "" {
|
|
notStartTime = true
|
|
} else {
|
|
m, err := c.db.GetMessage(ctx, conversationID, req.StartClientMsgID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
startTime = m.SendTime
|
|
}
|
|
log.ZDebug(ctx, "Assembly conversation parameters", "cost time", time.Since(t), "conversationID",
|
|
conversationID, "startTime:", startTime, "count:", req.Count, "not start_time", notStartTime)
|
|
t = time.Now()
|
|
if notStartTime {
|
|
list, err = c.db.GetMessageListNoTime(ctx, conversationID, req.Count, isReverse)
|
|
} else {
|
|
list, err = c.db.GetMessageList(ctx, conversationID, req.Count, startTime, isReverse)
|
|
}
|
|
log.ZDebug(ctx, "db get messageList", "cost time", time.Since(t), "len", len(list), "err",
|
|
err, "conversationID", conversationID)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
rawMessageLength := len(list)
|
|
t = time.Now()
|
|
if rawMessageLength < req.Count {
|
|
maxSeq, minSeq, lostSeqListLength := c.messageBlocksInternalContinuityCheck(ctx,
|
|
conversationID, notStartTime, isReverse, req.Count, startTime, &list, &messageListCallback)
|
|
_ = c.messageBlocksBetweenContinuityCheck(ctx, req.LastMinSeq, maxSeq, conversationID,
|
|
notStartTime, isReverse, req.Count, startTime, &list, &messageListCallback)
|
|
if minSeq == 1 && lostSeqListLength == 0 {
|
|
messageListCallback.IsEnd = true
|
|
} else {
|
|
c.messageBlocksEndContinuityCheck(ctx, minSeq, conversationID, notStartTime, isReverse,
|
|
req.Count, startTime, &list, &messageListCallback)
|
|
}
|
|
} else {
|
|
maxSeq, _, _ := c.messageBlocksInternalContinuityCheck(ctx, conversationID, notStartTime, isReverse,
|
|
req.Count, startTime, &list, &messageListCallback)
|
|
c.messageBlocksBetweenContinuityCheck(ctx, req.LastMinSeq, maxSeq, conversationID, notStartTime,
|
|
isReverse, req.Count, startTime, &list, &messageListCallback)
|
|
|
|
}
|
|
log.ZDebug(ctx, "pull message", "pull cost time", time.Since(t))
|
|
t = time.Now()
|
|
var thisMinSeq int64
|
|
for _, v := range list {
|
|
if v.Seq != 0 && thisMinSeq == 0 {
|
|
thisMinSeq = v.Seq
|
|
}
|
|
if v.Seq < thisMinSeq && v.Seq != 0 {
|
|
thisMinSeq = v.Seq
|
|
}
|
|
if v.Status >= constant.MsgStatusHasDeleted {
|
|
log.ZDebug(ctx, "this message has been deleted or exception message", "msg", v)
|
|
continue
|
|
}
|
|
temp := sdk_struct.MsgStruct{}
|
|
temp.ClientMsgID = v.ClientMsgID
|
|
temp.ServerMsgID = v.ServerMsgID
|
|
temp.CreateTime = v.CreateTime
|
|
temp.SendTime = v.SendTime
|
|
temp.SessionType = v.SessionType
|
|
temp.SendID = v.SendID
|
|
temp.RecvID = v.RecvID
|
|
temp.MsgFrom = v.MsgFrom
|
|
temp.ContentType = v.ContentType
|
|
temp.SenderPlatformID = v.SenderPlatformID
|
|
temp.SenderNickname = v.SenderNickname
|
|
temp.SenderFaceURL = v.SenderFaceURL
|
|
temp.Content = v.Content
|
|
temp.Seq = v.Seq
|
|
temp.IsRead = v.IsRead
|
|
temp.Status = v.Status
|
|
var attachedInfo sdk_struct.AttachedInfoElem
|
|
_ = utils.JsonStringToStruct(v.AttachedInfo, &attachedInfo)
|
|
temp.AttachedInfoElem = &attachedInfo
|
|
temp.Ex = v.Ex
|
|
temp.LocalEx = v.LocalEx
|
|
err := c.msgHandleByContentType(&temp)
|
|
if err != nil {
|
|
log.ZError(ctx, "Parsing data error", err, "temp", temp)
|
|
continue
|
|
}
|
|
switch sessionType {
|
|
case constant.GroupChatType:
|
|
fallthrough
|
|
case constant.SuperGroupChatType:
|
|
temp.GroupID = temp.RecvID
|
|
temp.RecvID = c.loginUserID
|
|
}
|
|
if attachedInfo.IsPrivateChat && temp.SendTime+int64(attachedInfo.BurnDuration) < time.Now().Unix() {
|
|
continue
|
|
}
|
|
messageList = append(messageList, &temp)
|
|
}
|
|
log.ZDebug(ctx, "message convert and unmarshal", "unmarshal cost time", time.Since(t))
|
|
t = time.Now()
|
|
if !isReverse {
|
|
sort.Sort(messageList)
|
|
}
|
|
log.ZDebug(ctx, "sort", "sort cost time", time.Since(t))
|
|
messageListCallback.MessageList = messageList
|
|
if thisMinSeq == 0 {
|
|
thisMinSeq = req.LastMinSeq
|
|
}
|
|
messageListCallback.LastMinSeq = thisMinSeq
|
|
return &messageListCallback, nil
|
|
|
|
}
|
|
|
|
func (c *Conversation) typingStatusUpdate(ctx context.Context, recvID, msgTip string) error {
|
|
if recvID == "" {
|
|
return sdkerrs.ErrArgs
|
|
}
|
|
s := sdk_struct.MsgStruct{}
|
|
err := c.initBasicInfo(ctx, &s, constant.UserMsgType, constant.Typing)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
s.RecvID = recvID
|
|
s.SessionType = constant.SingleChatType
|
|
typingElem := sdk_struct.TypingElem{}
|
|
typingElem.MsgTips = msgTip
|
|
s.Content = utils.StructToJsonString(typingElem)
|
|
options := make(map[string]bool, 6)
|
|
utils.SetSwitchFromOptions(options, constant.IsHistory, false)
|
|
utils.SetSwitchFromOptions(options, constant.IsPersistent, false)
|
|
utils.SetSwitchFromOptions(options, constant.IsSenderSync, false)
|
|
utils.SetSwitchFromOptions(options, constant.IsConversationUpdate, false)
|
|
utils.SetSwitchFromOptions(options, constant.IsSenderConversationUpdate, false)
|
|
utils.SetSwitchFromOptions(options, constant.IsUnreadCount, false)
|
|
utils.SetSwitchFromOptions(options, constant.IsOfflinePush, false)
|
|
|
|
var wsMsgData sdkws.MsgData
|
|
copier.Copy(&wsMsgData, s)
|
|
wsMsgData.Content = []byte(s.Content)
|
|
wsMsgData.CreateTime = s.CreateTime
|
|
wsMsgData.Options = options
|
|
var sendMsgResp sdkws.UserSendMsgResp
|
|
err = c.LongConnMgr.SendReqWaitResp(ctx, &wsMsgData, constant.SendMsg, &sendMsgResp)
|
|
if err != nil {
|
|
log.ZError(ctx, "send msg to server failed", err, "message", s)
|
|
return err
|
|
}
|
|
return nil
|
|
|
|
}
|
|
|
|
// funcation (c *Conversation) markMessageAsReadByConID(callback open_im_sdk_callback.Base, msgIDList sdk.MarkMessageAsReadByConIDParams, conversationID, operationID string) {
|
|
// var localMessage db.LocalChatLog
|
|
// var newMessageIDList []string
|
|
// messages, err := c.db.GetMultipleMessage(msgIDList)
|
|
// common.CheckDBErrCallback(callback, err, operationID)
|
|
// for _, v := range messages {
|
|
// if v.IsRead == false && v.ContentType < constant.NotificationBegin && v.SendID != c.loginUserID {
|
|
// newMessageIDList = append(newMessageIDList, v.ClientMsgID)
|
|
// }
|
|
// }
|
|
// if len(newMessageIDList) == 0 {
|
|
// common.CheckAnyErrCallback(callback, 201, errors.New("message has been marked read or sender is yourself"), operationID)
|
|
// }
|
|
// conversationID := c.getConversationIDBySessionType(userID, constant.SingleChatType)
|
|
// s := sdk_struct.MsgStruct{}
|
|
// c.initBasicInfo(&s, constant.UserMsgType, constant.HasReadReceipt, operationID)
|
|
// s.Content = utils.StructToJsonString(newMessageIDList)
|
|
// options := make(map[string]bool, 5)
|
|
// utils.SetSwitchFromOptions(options, constant.IsConversationUpdate, false)
|
|
// utils.SetSwitchFromOptions(options, constant.IsSenderConversationUpdate, false)
|
|
// utils.SetSwitchFromOptions(options, constant.IsUnreadCount, false)
|
|
// utils.SetSwitchFromOptions(options, constant.IsOfflinePush, false)
|
|
// //If there is an error, the coroutine ends, so judgment is not required
|
|
// resp, _ := c.InternalSendMessage(callback, &s, userID, "", operationID, &server_api_params.OfflinePushInfo{}, false, options)
|
|
// s.ServerMsgID = resp.ServerMsgID
|
|
// s.SendTime = resp.SendTime
|
|
// s.Status = constant.MsgStatusFiltered
|
|
// msgStructToLocalChatLog(&localMessage, &s)
|
|
// err = c.db.InsertMessage(&localMessage)
|
|
// if err != nil {
|
|
// log.Error(operationID, "inset into chat log err", localMessage, s, err.Error())
|
|
// }
|
|
// err2 := c.db.UpdateMessageHasRead(userID, newMessageIDList, constant.SingleChatType)
|
|
// if err2 != nil {
|
|
// log.Error(operationID, "update message has read error", newMessageIDList, userID, err2.Error())
|
|
// }
|
|
// _ = common.TriggerCmdUpdateConversation(common.UpdateConNode{ConID: conversationID, Action: constant.UpdateLatestMessageChange}, c.ch)
|
|
// //_ = common.TriggerCmdUpdateConversation(common.UpdateConNode{ConID: conversationID, Action: constant.ConChange, Args: []string{conversationID}}, c.ch)
|
|
// }
|
|
|
|
func (c *Conversation) insertMessageToLocalStorage(ctx context.Context, conversationID string, s *model_struct.LocalChatLog) error {
|
|
return c.db.InsertMessage(ctx, conversationID, s)
|
|
}
|
|
|
|
func (c *Conversation) judgeMultipleSubString(keywordList []string, main string, keywordListMatchType int) bool {
|
|
if len(keywordList) == 0 {
|
|
return true
|
|
}
|
|
if keywordListMatchType == constant.KeywordMatchOr {
|
|
for _, v := range keywordList {
|
|
if utils.KMP(main, v) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
} else {
|
|
for _, v := range keywordList {
|
|
if !utils.KMP(main, v) {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// searchLocalMessages searches for local messages based on the given search parameters.
|
|
func (c *Conversation) searchLocalMessages(ctx context.Context, searchParam *sdk.SearchLocalMessagesParams) (*sdk.SearchLocalMessagesCallback, error) {
|
|
var r sdk.SearchLocalMessagesCallback // Initialize the result structure
|
|
var startTime, endTime int64 // Variables to hold start and end times for the search
|
|
var list []*model_struct.LocalChatLog // Slice to store the search results
|
|
conversationMap := make(map[string]*sdk.SearchByConversationResult, 10) // Map to store results grouped by conversation, with initial capacity of 10
|
|
var err error // Variable to store any errors encountered
|
|
var conversationID string // Variable to store the current conversation ID
|
|
|
|
// Set the end time for the search; if SearchTimePosition is 0, use the current timestamp
|
|
if searchParam.SearchTimePosition == 0 {
|
|
endTime = utils.GetCurrentTimestampBySecond()
|
|
} else {
|
|
endTime = searchParam.SearchTimePosition
|
|
}
|
|
|
|
// Set the start time based on the specified time period
|
|
if searchParam.SearchTimePeriod != 0 {
|
|
startTime = endTime - searchParam.SearchTimePeriod
|
|
}
|
|
// Convert start and end times to milliseconds
|
|
startTime = utils.UnixSecondToTime(startTime).UnixNano() / 1e6
|
|
endTime = utils.UnixSecondToTime(endTime).UnixNano() / 1e6
|
|
|
|
// Validate that either keyword list or message type list is provided
|
|
if len(searchParam.KeywordList) == 0 && len(searchParam.MessageTypeList) == 0 {
|
|
return nil, errors.New("keywordlist and messageTypelist all null")
|
|
}
|
|
|
|
// Search in a specific conversation if ConversationID is provided
|
|
if searchParam.ConversationID != "" {
|
|
// Validate pagination parameters
|
|
if searchParam.PageIndex < 1 || searchParam.Count < 1 {
|
|
return nil, errors.New("page or count is null")
|
|
}
|
|
offset := (searchParam.PageIndex - 1) * searchParam.Count
|
|
_, err := c.db.GetConversation(ctx, searchParam.ConversationID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// Search by content type or keyword based on provided parameters
|
|
if len(searchParam.MessageTypeList) != 0 && len(searchParam.KeywordList) == 0 {
|
|
list, err = c.db.SearchMessageByContentType(ctx, searchParam.MessageTypeList, searchParam.ConversationID, startTime, endTime, offset, searchParam.Count)
|
|
} else {
|
|
newContentTypeList := func(list []int) (result []int) {
|
|
for _, v := range list {
|
|
if utils.IsContainInt(v, SearchContentType) {
|
|
result = append(result, v)
|
|
}
|
|
}
|
|
return result
|
|
}(searchParam.MessageTypeList)
|
|
if len(newContentTypeList) == 0 {
|
|
newContentTypeList = SearchContentType
|
|
}
|
|
list, err = c.db.SearchMessageByKeyword(ctx, newContentTypeList, searchParam.KeywordList, searchParam.KeywordListMatchType,
|
|
searchParam.ConversationID, startTime, endTime, offset, searchParam.Count)
|
|
}
|
|
} else {
|
|
// Comprehensive search across all conversations
|
|
if len(searchParam.MessageTypeList) == 0 {
|
|
searchParam.MessageTypeList = SearchContentType
|
|
}
|
|
list, err = c.messageController.SearchMessageByContentTypeAndKeyword(ctx, searchParam.MessageTypeList, searchParam.KeywordList, searchParam.KeywordListMatchType, startTime, endTime)
|
|
}
|
|
|
|
// Handle any errors encountered during the search
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Logging and processing each message in the search results
|
|
//localChatLogToMsgStruct(&messageList, list)
|
|
|
|
//log.Debug("hahh",utils.KMP("SSSsdf3434","s"))
|
|
//log.Debug("hahh",utils.KMP("SSSsdf3434","g"))
|
|
//log.Debug("hahh",utils.KMP("SSSsdf3434","3434"))
|
|
//log.Debug("hahh",utils.KMP("SSSsdf3434","F3434"))
|
|
//log.Debug("hahh",utils.KMP("SSSsdf3434","SDF3"))
|
|
// log.Debug("", "get raw data length is", len(list))
|
|
log.ZDebug(ctx, "get raw data length is", len(list))
|
|
|
|
for _, v := range list {
|
|
temp := sdk_struct.MsgStruct{}
|
|
temp.ClientMsgID = v.ClientMsgID
|
|
temp.ServerMsgID = v.ServerMsgID
|
|
temp.CreateTime = v.CreateTime
|
|
temp.SendTime = v.SendTime
|
|
temp.SessionType = v.SessionType
|
|
temp.SendID = v.SendID
|
|
temp.RecvID = v.RecvID
|
|
temp.MsgFrom = v.MsgFrom
|
|
temp.ContentType = v.ContentType
|
|
temp.SenderPlatformID = v.SenderPlatformID
|
|
temp.SenderNickname = v.SenderNickname
|
|
temp.SenderFaceURL = v.SenderFaceURL
|
|
temp.Content = v.Content
|
|
temp.Seq = v.Seq
|
|
temp.IsRead = v.IsRead
|
|
temp.Status = v.Status
|
|
var attachedInfo sdk_struct.AttachedInfoElem
|
|
_ = utils.JsonStringToStruct(v.AttachedInfo, &attachedInfo)
|
|
temp.AttachedInfoElem = &attachedInfo
|
|
temp.Ex = v.Ex
|
|
temp.LocalEx = v.LocalEx
|
|
err := c.msgHandleByContentType(&temp)
|
|
if err != nil {
|
|
// log.Error("", "Parsing data error:", err.Error(), temp)
|
|
log.ZError(ctx, "Parsing data error:", err, "msg", temp)
|
|
continue
|
|
}
|
|
if c.filterMsg(&temp, searchParam) {
|
|
continue
|
|
}
|
|
// Determine the conversation ID based on the session type
|
|
switch temp.SessionType {
|
|
case constant.SingleChatType:
|
|
if temp.SendID == c.loginUserID {
|
|
conversationID = c.getConversationIDBySessionType(temp.RecvID, constant.SingleChatType)
|
|
} else {
|
|
conversationID = c.getConversationIDBySessionType(temp.SendID, constant.SingleChatType)
|
|
}
|
|
case constant.GroupChatType:
|
|
temp.GroupID = temp.RecvID
|
|
temp.RecvID = c.loginUserID
|
|
conversationID = c.getConversationIDBySessionType(temp.GroupID, constant.GroupChatType)
|
|
case constant.SuperGroupChatType:
|
|
temp.GroupID = temp.RecvID
|
|
temp.RecvID = c.loginUserID
|
|
conversationID = c.getConversationIDBySessionType(temp.GroupID, constant.SuperGroupChatType)
|
|
}
|
|
// Populate the conversationMap with search results
|
|
if oldItem, ok := conversationMap[conversationID]; !ok {
|
|
searchResultItem := sdk.SearchByConversationResult{}
|
|
localConversation, err := c.db.GetConversation(ctx, conversationID)
|
|
if err != nil {
|
|
// log.Error("", "get conversation err ", err.Error(), conversationID)
|
|
continue
|
|
}
|
|
searchResultItem.ConversationID = conversationID
|
|
searchResultItem.FaceURL = localConversation.FaceURL
|
|
searchResultItem.ShowName = localConversation.ShowName
|
|
searchResultItem.LatestMsgSendTime = localConversation.LatestMsgSendTime
|
|
searchResultItem.ConversationType = localConversation.ConversationType
|
|
searchResultItem.MessageList = append(searchResultItem.MessageList, &temp)
|
|
searchResultItem.MessageCount++
|
|
conversationMap[conversationID] = &searchResultItem
|
|
} else {
|
|
oldItem.MessageCount++
|
|
oldItem.MessageList = append(oldItem.MessageList, &temp)
|
|
conversationMap[conversationID] = oldItem
|
|
}
|
|
}
|
|
|
|
// Compile the results from the conversationMap into the response structure
|
|
for _, v := range conversationMap {
|
|
r.SearchResultItems = append(r.SearchResultItems, v)
|
|
r.TotalCount += v.MessageCount
|
|
}
|
|
|
|
// Sort the search results based on the latest message send time
|
|
sort.Slice(r.SearchResultItems, func(i, j int) bool {
|
|
return r.SearchResultItems[i].LatestMsgSendTime > r.SearchResultItems[j].LatestMsgSendTime
|
|
})
|
|
|
|
return &r, nil // Return the final search results
|
|
}
|
|
|
|
// true is filter, false is not filter
|
|
func (c *Conversation) filterMsg(temp *sdk_struct.MsgStruct, searchParam *sdk.SearchLocalMessagesParams) bool {
|
|
switch temp.ContentType {
|
|
case constant.Text:
|
|
return !c.judgeMultipleSubString(searchParam.KeywordList, temp.TextElem.Content,
|
|
searchParam.KeywordListMatchType)
|
|
case constant.AtText:
|
|
return !c.judgeMultipleSubString(searchParam.KeywordList, temp.AtTextElem.Text,
|
|
searchParam.KeywordListMatchType)
|
|
case constant.File:
|
|
return !c.judgeMultipleSubString(searchParam.KeywordList, temp.FileElem.FileName,
|
|
searchParam.KeywordListMatchType)
|
|
case constant.Merger:
|
|
if !c.judgeMultipleSubString(searchParam.KeywordList, temp.MergeElem.Title, searchParam.KeywordListMatchType) {
|
|
for _, msgStruct := range temp.MergeElem.MultiMessage {
|
|
if c.filterMsg(msgStruct, searchParam) {
|
|
continue
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
case constant.Card:
|
|
return !c.judgeMultipleSubString(searchParam.KeywordList, temp.CardElem.Nickname,
|
|
searchParam.KeywordListMatchType)
|
|
case constant.Location:
|
|
return !c.judgeMultipleSubString(searchParam.KeywordList, temp.LocationElem.Description,
|
|
searchParam.KeywordListMatchType)
|
|
case constant.Custom:
|
|
return !c.judgeMultipleSubString(searchParam.KeywordList, temp.CustomElem.Description,
|
|
searchParam.KeywordListMatchType)
|
|
case constant.Quote:
|
|
if !c.judgeMultipleSubString(searchParam.KeywordList, temp.QuoteElem.Text, searchParam.KeywordListMatchType) {
|
|
return c.filterMsg(temp.QuoteElem.QuoteMessage, searchParam)
|
|
}
|
|
case constant.Picture:
|
|
fallthrough
|
|
case constant.Video:
|
|
if len(searchParam.KeywordList) == 0 {
|
|
return false
|
|
} else {
|
|
return true
|
|
}
|
|
default:
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (c *Conversation) delMsgBySeq(seqList []uint32) error {
|
|
var SPLIT = 1000
|
|
for i := 0; i < len(seqList)/SPLIT; i++ {
|
|
if err := c.delMsgBySeqSplit(seqList[i*SPLIT : (i+1)*SPLIT]); err != nil {
|
|
return utils.Wrap(err, "")
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *Conversation) delMsgBySeqSplit(seqList []uint32) error {
|
|
// var req server_api_params.DelMsgListReq
|
|
// req.SeqList = seqList
|
|
// req.OperationID = utils.OperationIDGenerator()
|
|
// req.OpUserID = c.loginUserID
|
|
// req.UserID = c.loginUserID
|
|
// operationID := req.OperationID
|
|
|
|
// err := c.SendReqWaitResp(context.Background(), &req, constant.WsDelMsg, 30, c.loginUserID)
|
|
// if err != nil {
|
|
// return utils.Wrap(err, "SendReqWaitResp failed")
|
|
// }
|
|
// var delResp server_api_params.DelMsgListResp
|
|
// err = proto.Unmarshal(resp.Data, &delResp)
|
|
// if err != nil {
|
|
// log.Error(operationID, "Unmarshal failed ", err.Error())
|
|
// return utils.Wrap(err, "Unmarshal failed")
|
|
// }
|
|
return nil
|
|
}
|
|
|
|
// old WS method
|
|
//funcation (c *Conversation) deleteMessageFromSvr(callback open_im_sdk_callback.Base, s *sdk_struct.MsgStruct, operationID string) {
|
|
// seq, err := c.db.GetMsgSeqByClientMsgID(s.ClientMsgID)
|
|
// common.CheckDBErrCallback(callback, err, operationID)
|
|
// if seq == 0 {
|
|
// err = errors.New("seq == 0 ")
|
|
// common.CheckArgsErrCallback(callback, err, operationID)
|
|
// }
|
|
// seqList := []uint32{seq}
|
|
// err = c.delMsgBySeq(seqList)
|
|
// common.CheckArgsErrCallback(callback, err, operationID)
|
|
//}
|
|
|
|
func isContainMessageReaction(reactionType int, list []*sdk_struct.ReactionElem) (bool, *sdk_struct.ReactionElem) {
|
|
for _, v := range list {
|
|
if v.Type == reactionType {
|
|
return true, v
|
|
}
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
func isContainUserReactionElem(useID string, list []*sdk_struct.UserReactionElem) (bool, *sdk_struct.UserReactionElem) {
|
|
for _, v := range list {
|
|
if v.UserID == useID {
|
|
return true, v
|
|
}
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
func DeleteUserReactionElem(a []*sdk_struct.UserReactionElem, userID string) []*sdk_struct.UserReactionElem {
|
|
j := 0
|
|
for _, v := range a {
|
|
if v.UserID != userID {
|
|
a[j] = v
|
|
j++
|
|
}
|
|
}
|
|
return a[:j]
|
|
}
|
|
|
|
func (c *Conversation) setMessageReactionExtensions(ctx context.Context, s *sdk_struct.MsgStruct, req sdk.SetMessageReactionExtensionsParams) ([]*server_api_params.ExtensionResult, error) {
|
|
return nil, nil
|
|
//message, err := c.db.GetMessageController(ctx, s)
|
|
//if err != nil {
|
|
// return nil, err
|
|
//}
|
|
//if message.Status != constant.MsgStatusSendSuccess {
|
|
// return nil, errors.New("only send success message can modify reaction extensions")
|
|
//}
|
|
//if message.SessionType != constant.SuperGroupChatType {
|
|
// return nil, errors.New("currently only support super group message")
|
|
//
|
|
//}
|
|
//extendMsg, _ := c.db.GetMessageReactionExtension(ctx, message.ClientMsgID)
|
|
//temp := make(map[string]*server_api_params.KeyValue)
|
|
//_ = json.Unmarshal(extendMsg.LocalReactionExtensions, &temp)
|
|
//reqTemp := make(map[string]*server_api_params.KeyValue)
|
|
//for _, v := range req {
|
|
// if value, ok := temp[v.TypeKey]; ok {
|
|
// v.LatestUpdateTime = value.LatestUpdateTime
|
|
// }
|
|
// reqTemp[v.TypeKey] = v
|
|
//}
|
|
//var sourceID string
|
|
//switch message.SessionType {
|
|
//case constant.SingleChatType:
|
|
// if message.SendID == c.loginUserID {
|
|
// sourceID = message.RecvID
|
|
// } else {
|
|
// sourceID = message.SendID
|
|
// }
|
|
//case constant.NotificationChatType:
|
|
// sourceID = message.RecvID
|
|
//case constant.GroupChatType, constant.SuperGroupChatType:
|
|
// sourceID = message.RecvID
|
|
//}
|
|
//var apiReq server_api_params.SetMessageReactionExtensionsReq
|
|
//apiReq.IsReact = message.IsReact
|
|
//apiReq.ClientMsgID = message.ClientMsgID
|
|
//apiReq.SourceID = sourceID
|
|
//apiReq.SessionType = message.SessionType
|
|
//apiReq.IsExternalExtensions = message.IsExternalExtensions
|
|
//apiReq.ReactionExtensionList = reqTemp
|
|
//apiReq.OperationID = ""
|
|
//apiReq.MsgFirstModifyTime = message.MsgFirstModifyTime
|
|
//resp, err := util.CallApi[server_api_params.ApiResult](ctx, constant.SetMessageReactionExtensionsRouter, &apiReq)
|
|
//if err != nil {
|
|
// return nil, err
|
|
//}
|
|
//var msg model_struct.LocalChatLogReactionExtensions
|
|
//msg.ClientMsgID = message.ClientMsgID
|
|
//resultKeyMap := make(map[string]*sdkws.KeyValue)
|
|
//for _, v := range resp.Result {
|
|
// if v.ErrCode == 0 {
|
|
// temp := new(sdkws.KeyValue)
|
|
// temp.TypeKey = v.TypeKey
|
|
// temp.Value = v.Value
|
|
// temp.LatestUpdateTime = v.LatestUpdateTime
|
|
// resultKeyMap[v.TypeKey] = temp
|
|
// }
|
|
//}
|
|
//err = c.db.GetAndUpdateMessageReactionExtension(ctx, message.ClientMsgID, resultKeyMap)
|
|
//if err != nil {
|
|
// log.Error("", "GetAndUpdateMessageReactionExtension err:", err.Error())
|
|
//}
|
|
//if !message.IsReact {
|
|
// message.IsReact = resp.IsReact
|
|
// message.MsgFirstModifyTime = resp.MsgFirstModifyTime
|
|
// err = c.db.UpdateMessageController(ctx, message)
|
|
// if err != nil {
|
|
// log.Error("", "UpdateMessageController err:", err.Error(), message)
|
|
//
|
|
// }
|
|
//}
|
|
//return resp.Result, nil
|
|
}
|
|
|
|
func (c *Conversation) addMessageReactionExtensions(ctx context.Context, s *sdk_struct.MsgStruct, req sdk.AddMessageReactionExtensionsParams) ([]*server_api_params.ExtensionResult, error) {
|
|
return nil, nil
|
|
//message, err := c.db.GetMessageController(ctx, s)
|
|
//if err != nil {
|
|
// return nil, err
|
|
//}
|
|
//if message.Status != constant.MsgStatusSendSuccess || message.Seq == 0 {
|
|
// return nil, errors.New("only send success message can modify reaction extensions")
|
|
//}
|
|
//reqTemp := make(map[string]*server_api_params.KeyValue)
|
|
//extendMsg, err := c.db.GetMessageReactionExtension(ctx, message.ClientMsgID)
|
|
//if err == nil && extendMsg != nil {
|
|
// temp := make(map[string]*server_api_params.KeyValue)
|
|
// _ = json.Unmarshal(extendMsg.LocalReactionExtensions, &temp)
|
|
// for _, v := range req {
|
|
// if value, ok := temp[v.TypeKey]; ok {
|
|
// v.LatestUpdateTime = value.LatestUpdateTime
|
|
// }
|
|
// reqTemp[v.TypeKey] = v
|
|
// }
|
|
//} else {
|
|
// for _, v := range req {
|
|
// reqTemp[v.TypeKey] = v
|
|
// }
|
|
//}
|
|
//var sourceID string
|
|
//switch message.SessionType {
|
|
//case constant.SingleChatType:
|
|
// if message.SendID == c.loginUserID {
|
|
// sourceID = message.RecvID
|
|
// } else {
|
|
// sourceID = message.SendID
|
|
// }
|
|
//case constant.NotificationChatType:
|
|
// sourceID = message.RecvID
|
|
//case constant.GroupChatType, constant.SuperGroupChatType:
|
|
// sourceID = message.RecvID
|
|
//}
|
|
//var apiReq server_api_params.AddMessageReactionExtensionsReq
|
|
//apiReq.IsReact = message.IsReact
|
|
//apiReq.ClientMsgID = message.ClientMsgID
|
|
//apiReq.SourceID = sourceID
|
|
//apiReq.SessionType = message.SessionType
|
|
//apiReq.IsExternalExtensions = message.IsExternalExtensions
|
|
//apiReq.ReactionExtensionList = reqTemp
|
|
//apiReq.OperationID = ""
|
|
//apiReq.MsgFirstModifyTime = message.MsgFirstModifyTime
|
|
//apiReq.Seq = message.Seq
|
|
//
|
|
//resp, err := util.CallApi[server_api_params.ApiResult](ctx, constant.AddMessageReactionExtensionsRouter, &apiReq)
|
|
//if err != nil {
|
|
// return nil, err
|
|
//}
|
|
//log.Debug("", "api return:", message.IsReact, resp)
|
|
//if !message.IsReact {
|
|
// message.IsReact = resp.IsReact
|
|
// message.MsgFirstModifyTime = resp.MsgFirstModifyTime
|
|
// err = c.db.UpdateMessageController(ctx, message)
|
|
// if err != nil {
|
|
// log.Error("", "UpdateMessageController err:", err.Error(), message)
|
|
// }
|
|
//}
|
|
//return resp.Result, nil
|
|
}
|
|
|
|
func (c *Conversation) deleteMessageReactionExtensions(ctx context.Context, s *sdk_struct.MsgStruct, req sdk.DeleteMessageReactionExtensionsParams) ([]*server_api_params.ExtensionResult, error) {
|
|
// message, err := c.GetMessageController(ctx, s)
|
|
// if err != nil {
|
|
// return nil, err
|
|
// }
|
|
// if message.Status != constant.MsgStatusSendSuccess {
|
|
// return nil, errors.New("only send success message can modify reaction extensions")
|
|
// }
|
|
// if message.SessionType != constant.SuperGroupChatType {
|
|
// return nil, errors.New("currently only support super group message")
|
|
|
|
// }
|
|
// extendMsg, _ := c.db.GetMessageReactionExtension(ctx, message.ClientMsgID)
|
|
// temp := make(map[string]*server_api_params.KeyValue)
|
|
// _ = json.Unmarshal(extendMsg.LocalReactionExtensions, &temp)
|
|
// var reqTemp []*server_api_params.KeyValue
|
|
// for _, v := range req {
|
|
// if value, ok := temp[v]; ok {
|
|
// var tt server_api_params.KeyValue
|
|
// tt.LatestUpdateTime = value.LatestUpdateTime
|
|
// tt.TypeKey = v
|
|
// reqTemp = append(reqTemp, &tt)
|
|
// }
|
|
// }
|
|
// var sourceID string
|
|
// switch message.SessionType {
|
|
// case constant.SingleChatType:
|
|
// if message.SendID == c.loginUserID {
|
|
// sourceID = message.RecvID
|
|
// } else {
|
|
// sourceID = message.SendID
|
|
// }
|
|
// case constant.NotificationChatType:
|
|
// sourceID = message.RecvID
|
|
// case constant.GroupChatType, constant.SuperGroupChatType:
|
|
// sourceID = message.RecvID
|
|
// }
|
|
// var apiReq server_api_params.DeleteMessageReactionExtensionsReq
|
|
// apiReq.ClientMsgID = message.ClientMsgID
|
|
// apiReq.SourceID = sourceID
|
|
// apiReq.SessionType = message.SessionType
|
|
// apiReq.ReactionExtensionList = reqTemp
|
|
// apiReq.OperationID = ""
|
|
// apiReq.IsExternalExtensions = message.IsExternalExtensions
|
|
// apiReq.MsgFirstModifyTime = message.MsgFirstModifyTime
|
|
// resp, err := util.CallApi[server_api_params.ApiResult](ctx, constant.AddMessageReactionExtensionsRouter, &apiReq)
|
|
// if err != nil {
|
|
// return nil, err
|
|
// }
|
|
// var msg model_struct.LocalChatLogReactionExtensions
|
|
// msg.ClientMsgID = message.ClientMsgID
|
|
// resultKeyMap := make(map[string]*sdkws.KeyValue)
|
|
// for _, v := range resp.Result {
|
|
// if v.ErrCode == 0 {
|
|
// temp := new(sdkws.KeyValue)
|
|
// temp.TypeKey = v.TypeKey
|
|
// resultKeyMap[v.TypeKey] = temp
|
|
// }
|
|
// }
|
|
// err = c.db.DeleteAndUpdateMessageReactionExtension(ctx, message.ClientMsgID, resultKeyMap)
|
|
// if err != nil {
|
|
// log.Error("", "GetAndUpdateMessageReactionExtension err:", err.Error())
|
|
// }
|
|
// return resp.Result, nil
|
|
return nil, nil
|
|
}
|
|
|
|
type syncReactionExtensionParams struct {
|
|
MessageList []*model_struct.LocalChatLog
|
|
SessionType int32
|
|
SourceID string
|
|
IsExternalExtension bool
|
|
ExtendMessageList []*model_struct.LocalChatLogReactionExtensions
|
|
TypeKeyList []string
|
|
}
|
|
|
|
func (c *Conversation) getMessageListReactionExtensions(ctx context.Context, conversationID string, messageList []*sdk_struct.MsgStruct) ([]*server_api_params.SingleMessageExtensionResult, error) {
|
|
if len(messageList) == 0 {
|
|
return nil, errors.New("message list is null")
|
|
}
|
|
var msgIDs []string
|
|
var sourceID string
|
|
var sessionType int32
|
|
var isExternalExtension bool
|
|
for _, msgStruct := range messageList {
|
|
switch msgStruct.SessionType {
|
|
case constant.SingleChatType:
|
|
if msgStruct.SendID == c.loginUserID {
|
|
sourceID = msgStruct.RecvID
|
|
} else {
|
|
sourceID = msgStruct.SendID
|
|
}
|
|
case constant.NotificationChatType:
|
|
sourceID = msgStruct.RecvID
|
|
case constant.GroupChatType, constant.SuperGroupChatType:
|
|
sourceID = msgStruct.GroupID
|
|
}
|
|
sessionType = msgStruct.SessionType
|
|
msgIDs = append(msgIDs, msgStruct.ClientMsgID)
|
|
}
|
|
isExternalExtension = c.IsExternalExtensions
|
|
localMessageList, err := c.db.GetMessagesByClientMsgIDs(ctx, conversationID, msgIDs)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, v := range localMessageList {
|
|
if v.IsReact != true {
|
|
return nil, errors.New("have not reaction message in message list:" + v.ClientMsgID)
|
|
}
|
|
}
|
|
var result server_api_params.GetMessageListReactionExtensionsResp
|
|
extendMessage, _ := c.db.GetMultipleMessageReactionExtension(ctx, msgIDs)
|
|
for _, v := range extendMessage {
|
|
var singleResult server_api_params.SingleMessageExtensionResult
|
|
// temp := make(map[string]*sdkws.KeyValue)
|
|
// _ = json.Unmarshal(v.LocalReactionExtensions, &temp)
|
|
singleResult.ClientMsgID = v.ClientMsgID
|
|
// singleResult.ReactionExtensionList = temp
|
|
result = append(result, &singleResult)
|
|
}
|
|
args := syncReactionExtensionParams{}
|
|
args.MessageList = localMessageList
|
|
args.SourceID = sourceID
|
|
args.SessionType = sessionType
|
|
args.ExtendMessageList = extendMessage
|
|
args.IsExternalExtension = isExternalExtension
|
|
_ = common.TriggerCmdSyncReactionExtensions(common.SyncReactionExtensionsNode{
|
|
OperationID: "",
|
|
Action: constant.SyncMessageListReactionExtensions,
|
|
Args: args,
|
|
}, c.GetCh())
|
|
return result, nil
|
|
|
|
}
|
|
|
|
// funcation (c *Conversation) getMessageListSomeReactionExtensions(callback open_im_sdk_callback.Base, messageList []*sdk_struct.MsgStruct, keyList []string, operationID string) server_api_params.GetMessageListReactionExtensionsResp {
|
|
// if len(messageList) == 0 {
|
|
// common.CheckAnyErrCallback(callback, 201, errors.New("message list is null"), operationID)
|
|
// }
|
|
// var msgIDList []string
|
|
// var sourceID string
|
|
// var sessionType int32
|
|
// var isExternalExtension bool
|
|
// for _, msgStruct := range messageList {
|
|
// switch msgStruct.SessionType {
|
|
// case constant.SingleChatType:
|
|
// if msgStruct.SendID == c.loginUserID {
|
|
// sourceID = msgStruct.RecvID
|
|
// } else {
|
|
// sourceID = msgStruct.SendID
|
|
// }
|
|
// case constant.NotificationChatType:
|
|
// sourceID = msgStruct.RecvID
|
|
// case constant.GroupChatType, constant.SuperGroupChatType:
|
|
// sourceID = msgStruct.GroupID
|
|
// }
|
|
// sessionType = msgStruct.SessionType
|
|
// isExternalExtension = msgStruct.IsExternalExtensions
|
|
// msgIDList = append(msgIDList, msgStruct.ClientMsgID)
|
|
// }
|
|
// localMessageList, err := c.db.GetMultipleMessageController(msgIDList, sourceID, sessionType)
|
|
// common.CheckDBErrCallback(callback, err, operationID)
|
|
// var result server_api_params.GetMessageListReactionExtensionsResp
|
|
// extendMsgs, _ := c.db.GetMultipleMessageReactionExtension(msgIDList)
|
|
// for _, v := range extendMsgs {
|
|
// var singleResult server_api_params.SingleMessageExtensionResult
|
|
// temp := make(map[string]*server_api_params.KeyValue)
|
|
// _ = json.Unmarshal(v.LocalReactionExtensions, &temp)
|
|
// for s, _ := range temp {
|
|
// if !utils.IsContain(s, keyList) {
|
|
// delete(temp, s)
|
|
// }
|
|
// }
|
|
// singleResult.ClientMsgID = v.ClientMsgID
|
|
// singleResult.ReactionExtensionList = temp
|
|
// result = append(result, &singleResult)
|
|
// }
|
|
// args := syncReactionExtensionParams{}
|
|
// args.MessageList = localMessageList
|
|
// args.SourceID = sourceID
|
|
// args.TypeKeyList = keyList
|
|
// args.SessionType = sessionType
|
|
// args.ExtendMessageList = extendMsgs
|
|
// args.IsExternalExtension = isExternalExtension
|
|
// _ = common.TriggerCmdSyncReactionExtensions(common.SyncReactionExtensionsNode{
|
|
// OperationID: operationID,
|
|
// Action: constant.SyncMessageListReactionExtensions,
|
|
// Args: args,
|
|
// }, c.GetCh())
|
|
// return result
|
|
// }
|
|
//
|
|
// funcation (c *Conversation) setTypeKeyInfo(callback open_im_sdk_callback.Base, s *sdk_struct.MsgStruct, typeKey, ex string, isCanRepeat bool, operationID string) []*server_api_params.ExtensionResult {
|
|
// message, err := c.db.GetMessageController(s)
|
|
// common.CheckDBErrCallback(callback, err, operationID)
|
|
// if message.Status != constant.MsgStatusSendSuccess {
|
|
// common.CheckAnyErrCallback(callback, 201, errors.New("only send success message can modify reaction extensions"), operationID)
|
|
// }
|
|
// extendMsg, _ := c.db.GetMessageReactionExtension(message.ClientMsgID)
|
|
// temp := make(map[string]*server_api_params.KeyValue)
|
|
// _ = json.Unmarshal(extendMsg.LocalReactionExtensions, &temp)
|
|
// var flag bool
|
|
// var isContainSelfK string
|
|
// var dbIsCanRepeat bool
|
|
// var deletedKeyValue server_api_params.KeyValue
|
|
// var maxTypeKey string
|
|
// var maxTypeKeyValue server_api_params.KeyValue
|
|
// reqTemp := make(map[string]*server_api_params.KeyValue)
|
|
// for k, v := range temp {
|
|
// if strings.HasPrefix(k, typeKey) {
|
|
// flag = true
|
|
// singleTypeKeyInfo := new(sdk.SingleTypeKeyInfo)
|
|
// _ = json.Unmarshal([]byte(v.Value), singleTypeKeyInfo)
|
|
// if _, ok := singleTypeKeyInfo.InfoList[c.loginUserID]; ok {
|
|
// isContainSelfK = k
|
|
// dbIsCanRepeat = singleTypeKeyInfo.IsCanRepeat
|
|
// delete(singleTypeKeyInfo.InfoList, c.loginUserID)
|
|
// singleTypeKeyInfo.Counter--
|
|
// deletedKeyValue.TypeKey = v.TypeKey
|
|
// deletedKeyValue.Value = utils.StructToJsonString(singleTypeKeyInfo)
|
|
// deletedKeyValue.LatestUpdateTime = v.LatestUpdateTime
|
|
// }
|
|
// if k > maxTypeKey {
|
|
// maxTypeKey = k
|
|
// maxTypeKeyValue = *v
|
|
// }
|
|
// }
|
|
// }
|
|
// if !flag {
|
|
// if len(temp) >= 300 {
|
|
// common.CheckAnyErrCallback(callback, 202, errors.New("number of keys only can support 300"), operationID)
|
|
// }
|
|
// singleTypeKeyInfo := new(sdk.SingleTypeKeyInfo)
|
|
// singleTypeKeyInfo.TypeKey = getIndexTypeKey(typeKey, 0)
|
|
// singleTypeKeyInfo.Counter = 1
|
|
// singleTypeKeyInfo.IsCanRepeat = isCanRepeat
|
|
// singleTypeKeyInfo.Index = 0
|
|
// userInfo := new(sdk.Info)
|
|
// userInfo.UserID = c.loginUserID
|
|
// userInfo.Ex = ex
|
|
// singleTypeKeyInfo.InfoList[c.loginUserID] = userInfo
|
|
// keyValue := new(server_api_params.KeyValue)
|
|
// keyValue.TypeKey = singleTypeKeyInfo.TypeKey
|
|
// keyValue.Value = utils.StructToJsonString(singleTypeKeyInfo)
|
|
// reqTemp[singleTypeKeyInfo.TypeKey] = keyValue
|
|
// } else {
|
|
// if isContainSelfK != "" && !dbIsCanRepeat {
|
|
// //删除操作
|
|
// reqTemp[isContainSelfK] = &deletedKeyValue
|
|
// } else {
|
|
// singleTypeKeyInfo := new(sdk.SingleTypeKeyInfo)
|
|
// _ = json.Unmarshal([]byte(maxTypeKeyValue.Value), singleTypeKeyInfo)
|
|
// userInfo := new(sdk.Info)
|
|
// userInfo.UserID = c.loginUserID
|
|
// userInfo.Ex = ex
|
|
// singleTypeKeyInfo.Counter++
|
|
// singleTypeKeyInfo.InfoList[c.loginUserID] = userInfo
|
|
// maxTypeKeyValue.Value = utils.StructToJsonString(singleTypeKeyInfo)
|
|
// data, _ := json.Marshal(maxTypeKeyValue)
|
|
// if len(data) > 1000 { //单key超过了1kb
|
|
// if len(temp) >= 300 {
|
|
// common.CheckAnyErrCallback(callback, 202, errors.New("number of keys only can support 300"), operationID)
|
|
// }
|
|
// newSingleTypeKeyInfo := new(sdk.SingleTypeKeyInfo)
|
|
// newSingleTypeKeyInfo.TypeKey = getIndexTypeKey(typeKey, singleTypeKeyInfo.Index+1)
|
|
// newSingleTypeKeyInfo.Counter = 1
|
|
// newSingleTypeKeyInfo.IsCanRepeat = singleTypeKeyInfo.IsCanRepeat
|
|
// newSingleTypeKeyInfo.Index = singleTypeKeyInfo.Index + 1
|
|
// userInfo := new(sdk.Info)
|
|
// userInfo.UserID = c.loginUserID
|
|
// userInfo.Ex = ex
|
|
// newSingleTypeKeyInfo.InfoList[c.loginUserID] = userInfo
|
|
// keyValue := new(server_api_params.KeyValue)
|
|
// keyValue.TypeKey = newSingleTypeKeyInfo.TypeKey
|
|
// keyValue.Value = utils.StructToJsonString(newSingleTypeKeyInfo)
|
|
// reqTemp[singleTypeKeyInfo.TypeKey] = keyValue
|
|
// } else {
|
|
// reqTemp[maxTypeKey] = &maxTypeKeyValue
|
|
// }
|
|
//
|
|
// }
|
|
// }
|
|
// var sourceID string
|
|
// switch message.SessionType {
|
|
// case constant.SingleChatType:
|
|
// sourceID = message.SendID + message.RecvID
|
|
// case constant.NotificationChatType:
|
|
// sourceID = message.RecvID
|
|
// case constant.GroupChatType, constant.SuperGroupChatType:
|
|
// sourceID = message.RecvID
|
|
// }
|
|
// var apiReq server_api_params.SetMessageReactionExtensionsReq
|
|
// apiReq.IsReact = message.IsReact
|
|
// apiReq.ClientMsgID = message.ClientMsgID
|
|
// apiReq.SourceID = sourceID
|
|
// apiReq.SessionType = message.SessionType
|
|
// apiReq.IsExternalExtensions = message.IsExternalExtensions
|
|
// apiReq.ReactionExtensionList = reqTemp
|
|
// apiReq.OperationID = operationID
|
|
// apiReq.MsgFirstModifyTime = message.MsgFirstModifyTime
|
|
// var apiResp server_api_params.SetMessageReactionExtensionsResp
|
|
// c.p.PostFatalCallback(callback, constant.SetMessageReactionExtensionsRouter, apiReq, &apiResp.ApiResult, apiReq.OperationID)
|
|
// var msg model_struct.LocalChatLogReactionExtensions
|
|
// msg.ClientMsgID = message.ClientMsgID
|
|
// resultKeyMap := make(map[string]*server_api_params.KeyValue)
|
|
// for _, v := range apiResp.ApiResult.Result {
|
|
// if v.ErrCode == 0 {
|
|
// temp := new(server_api_params.KeyValue)
|
|
// temp.TypeKey = v.TypeKey
|
|
// temp.Value = v.Value
|
|
// temp.LatestUpdateTime = v.LatestUpdateTime
|
|
// resultKeyMap[v.TypeKey] = temp
|
|
// }
|
|
// }
|
|
// err = c.db.GetAndUpdateMessageReactionExtension(message.ClientMsgID, resultKeyMap)
|
|
// if err != nil {
|
|
// log.Error(operationID, "GetAndUpdateMessageReactionExtension err:", err.Error())
|
|
// }
|
|
// if !message.IsReact {
|
|
// message.IsReact = apiResp.ApiResult.IsReact
|
|
// message.MsgFirstModifyTime = apiResp.ApiResult.MsgFirstModifyTime
|
|
// err = c.db.UpdateMessageController(message)
|
|
// if err != nil {
|
|
// log.Error(operationID, "UpdateMessageController err:", err.Error(), message)
|
|
//
|
|
// }
|
|
// }
|
|
// return apiResp.ApiResult.Result
|
|
// }
|
|
//
|
|
// funcation getIndexTypeKey(typeKey string, index int) string {
|
|
// return typeKey + "$" + utils.IntToString(index)
|
|
// }
|
|
func getPrefixTypeKey(typeKey string) string {
|
|
list := strings.Split(typeKey, "$")
|
|
if len(list) > 0 {
|
|
return list[0]
|
|
}
|
|
return ""
|
|
}
|
|
|
|
//funcation (c *Conversation) getTypeKeyListInfo(callback open_im_sdk_callback.Base, s *sdk_struct.MsgStruct, keyList []string, operationID string) (result []*sdk.SingleTypeKeyInfoSum) {
|
|
// message, err := c.db.GetMessageController(s)
|
|
// common.CheckDBErrCallback(callback, err, operationID)
|
|
// if message.Status != constant.MsgStatusSendSuccess {
|
|
// common.CheckAnyErrCallback(callback, 201, errors.New("only send success message can modify reaction extensions"), operationID)
|
|
// }
|
|
// if !message.IsReact {
|
|
// common.CheckAnyErrCallback(callback, 202, errors.New("can get message reaction ex"), operationID)
|
|
// }
|
|
// extendMsg, _ := c.db.GetMessageReactionExtension(message.ClientMsgID)
|
|
// temp := make(map[string]*server_api_params.KeyValue)
|
|
// _ = json.Unmarshal(extendMsg.LocalReactionExtensions, &temp)
|
|
// for _, v := range keyList {
|
|
// singleResult := new(sdk.SingleTypeKeyInfoSum)
|
|
// singleResult.TypeKey = v
|
|
// for typeKey, value := range temp {
|
|
// if strings.HasPrefix(typeKey, v) {
|
|
// singleTypeKeyInfo := new(sdk.SingleTypeKeyInfo)
|
|
// _ = json.Unmarshal([]byte(value.Value), singleTypeKeyInfo)
|
|
// if _, ok := singleTypeKeyInfo.InfoList[c.loginUserID]; ok {
|
|
// singleResult.IsContainSelf = true
|
|
// }
|
|
// for _, info := range singleTypeKeyInfo.InfoList {
|
|
// v := *info
|
|
// singleResult.InfoList = append(singleResult.InfoList, &v)
|
|
// }
|
|
// singleResult.Counter += singleTypeKeyInfo.Counter
|
|
// }
|
|
// }
|
|
// result = append(result, singleResult)
|
|
// }
|
|
// messageList := []*sdk_struct.MsgStruct{s}
|
|
// _ = common.TriggerCmdSyncReactionExtensions(common.SyncReactionExtensionsNode{
|
|
// OperationID: operationID,
|
|
// Action: constant.SyncMessageListTypeKeyInfo,
|
|
// Args: messageList,
|
|
// }, c.GetCh())
|
|
//
|
|
// return result
|
|
//}
|
|
//
|
|
//funcation (c *Conversation) getAllTypeKeyInfo(callback open_im_sdk_callback.Base, s *sdk_struct.MsgStruct, operationID string) (result []*sdk.SingleTypeKeyInfoSum) {
|
|
// message, err := c.db.GetMessageController(s)
|
|
// common.CheckDBErrCallback(callback, err, operationID)
|
|
// if message.Status != constant.MsgStatusSendSuccess {
|
|
// common.CheckAnyErrCallback(callback, 201, errors.New("only send success message can modify reaction extensions"), operationID)
|
|
// }
|
|
// if !message.IsReact {
|
|
// common.CheckAnyErrCallback(callback, 202, errors.New("can get message reaction ex"), operationID)
|
|
// }
|
|
// extendMsg, _ := c.db.GetMessageReactionExtension(message.ClientMsgID)
|
|
// temp := make(map[string]*server_api_params.KeyValue)
|
|
// _ = json.Unmarshal(extendMsg.LocalReactionExtensions, &temp)
|
|
// mapResult := make(map[string]*sdk.SingleTypeKeyInfoSum)
|
|
// for typeKey, value := range temp {
|
|
// singleTypeKeyInfo := new(sdk.SingleTypeKeyInfo)
|
|
// err := json.Unmarshal([]byte(value.Value), singleTypeKeyInfo)
|
|
// if err != nil {
|
|
// log.Warn(operationID, "not this type ", value.Value)
|
|
// continue
|
|
// }
|
|
// prefixKey := getPrefixTypeKey(typeKey)
|
|
// if v, ok := mapResult[prefixKey]; ok {
|
|
// for _, info := range singleTypeKeyInfo.InfoList {
|
|
// t := *info
|
|
// v.InfoList = append(v.InfoList, &t)
|
|
// }
|
|
// if _, ok := singleTypeKeyInfo.InfoList[c.loginUserID]; ok {
|
|
// v.IsContainSelf = true
|
|
// }
|
|
// v.Counter += singleTypeKeyInfo.Counter
|
|
// } else {
|
|
// v := new(sdk.SingleTypeKeyInfoSum)
|
|
// v.TypeKey = prefixKey
|
|
// v.Counter = singleTypeKeyInfo.Counter
|
|
// for _, info := range singleTypeKeyInfo.InfoList {
|
|
// t := *info
|
|
// v.InfoList = append(v.InfoList, &t)
|
|
// }
|
|
// if _, ok := singleTypeKeyInfo.InfoList[c.loginUserID]; ok {
|
|
// v.IsContainSelf = true
|
|
// }
|
|
// mapResult[prefixKey] = v
|
|
// }
|
|
// }
|
|
// for _, v := range mapResult {
|
|
// result = append(result, v)
|
|
//
|
|
// }
|
|
// return result
|
|
//}
|
|
|