tencent cloud

All product documents
Chat
Android&iOS&Windows&Mac
Last updated: 2025-03-27 11:29:03
Android&iOS&Windows&Mac
Last updated: 2025-03-27 11:29:03

Search Cloud Messages

Description

Cloud message search, a must-have feature to enhance the App user experience, enables users to directly find the desired content from complex information quickly and conveniently. It can also serve as an OPS tool, facilitating efficient and concise guidance to related content.
Note:
The cloud message search feature is supported only by version 7.3.4358 or later.
The cloud message search feature is only available to Pro Plus and Enterprise customers and can be used after purchasing Pro Plus and Enterprise; the Free Trial version supports a certain limit of free trial, valid for one month.
If this service is not activated, calling the interface will return the error code 60020.

Message Search Class

Message Search Parameter Class

The message search parameter class is V2TIMMessageSearchParam (Android/iOS & Mac/Windows). When searching for messages, the SDK will execute different search logics based on this object's settings.
The parameters of V2TIMMessageSearchParam are as follows:
Parameter
Meaning
Description
keywordList
Keyword list
It can contain up to five keywords. When the message sender and the message type are not specified, the keyword list must be set; in other cases, it can be left empty.
keywordListMatchType
Match type of the keyword list
You can set it to search with "OR" logic or "AND" logic. The values are V2TIM_KEYWORD_LIST_MATCH_TYPE_OR and V2TIM_KEYWORD_LIST_MATCH_TYPE_AND, respectively. By default, it uses "OR" logic.
senderUserIDList
Search for messages sent by a specified userID
Up to five are supported.
messageTypeList
Set of the message types to be searched for
Leaving it empty means searching for all supported types of messages (V2TIMFaceElem and V2TIMGroupTipsElem are not searchable). Refer to V2TIMElemType (Android/iOS & Mac/Windows) for other types.
conversationID
Search "all conversations" or "a specified conversation"
If conversationID is empty, search all sessions; if conversationID is not empty, search the specified session.
searchTimePosition
Start time for the search
The default is 0 (search from now). UTC Timestamp, in seconds.
searchTimePeriod
A past period of time starting from the start time
The default is 0 (unlimited time range). 24 x 60 x 60 represents the past day, in seconds.
searchCount
Number of search results
Number of searches, support up to 100.
searchCursor
Search cursor
Starting position, fill in an empty character string for the first time, and fill in the searchCursor from the last V2TIMMessageSearchResult returned for subsequent pulls.

Message Search Result Class

The message search result class is V2TIMMessageSearchResult(Android/iOS & Mac/Windows). The parameters are as described below:
Parameter
Meaning
Description
totalCount
Total number of the search result items
If a specific session is searched, the total number of messages that meet the search criteria will be returned;
If all sessions are searched, the total number of sessions containing messages that meet the search criteria will be returned.
messageSearchResultItems
Search results list
If a specific session is searched, the returned result list will only include results from that session;
If all sessions are searched, messages that meet the search criteria will be grouped by session ID, and the grouping results will be returned paginated.
searchCursor
Continue pulling the cursor
Cursor required for continuation while calling the search API
Here, messageSearchResultItems is a list containing V2TIMMessageSearchResultItem(Android/iOS & Mac/Windows) objects, with the parameters described as follows:
Parameter
Meaning
Description
conversationID
Session ID
-
messageCount
Number of messages
The total number of messages matching the criteria found in the current session.
messageList
List of messages that meet the search criteria
If a specific session is searched, messageList contains a list of all messages meeting the search criteria within this session.
If all sessions are searched, the number of messages contained in messageList may have the following two possibilities:
If the number of messages matched in a session is > 1, then messageList is empty, and you can display "{messageCount} relevant records" on the UI.
If the number of messages matched in a session = 1, then messageList is the matched message, and you can display it on the UI and highlight the search keywords.

Searching Messages in All Sessions

When a user enters keywords in the search box to search for messages, you can call searchCloudMessages(Android/iOS and Mac/Windows) to search for messages.
If you want to search within the scope of all sessions, you just need to leave conversationID in V2TIMMessageSearchParam unset or set to empty.
Below is the sample code:
Android
iOS & Mac
Windows
List<String> keywordList = new ArrayList<>();
keywordList.add("abc");
keywordList.add("123");
V2TIMMessageSearchParam searchParam = new V2TIMMessageSearchParam();
// Set the keyword for the search
searchParam.setKeywordList(keywordList);
// Search for 20 data entries
searchParam.setSearchCount(20);
// Start searching from the latest session
searchParam.setSearchCursor("");
// Start searching from the current time
searchParam.setSearchTimePosition(0);
// Search for messages within 10 minutes
searchParam.setSearchTimePeriod(600);
V2TIMManager.getMessageManager().searchCloudMessages(searchParam,newV2TIMValueCallback<V2TIMMessageSearchResult>() {
@Override
public void onSuccess(V2TIMMessageSearchResult v2TIMMessageSearchResult) {
// Data found successfully
}
@Override
public void onError(int code, String desc) {
// Failed to find the data
}
});
V2TIMMessageSearchParam *param = [[V2TIMMessageSearchParam alloc] init];
// Set the keyword for the search
param.keywordList = @[@"abc", @"123"];
param.messageTypeList = nil;
param.conversationID = nil;
param.searchTimePosition = 0;
param.searchTimePeriod = 0;
// Search for 20 data entries
param.searchCount = 20;
// Start searching from the latest session
param.searchCursor = @"";
[V2TIMManager.sharedInstance searchCloudMessages:param
succ:^(V2TIMMessageSearchResult *searchResult) {
// The search was successful, and the search results are returned in searchResult
} fail:^(int code, NSString *desc) {
// Failed to find the data
}];
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;
ValueCallback() = default;
~ValueCallback() override = default;
void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}
void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

V2TIMMessageSearchParam searchParam;
// Set the keyword for the search
searchParam.keywordList.PushBack("abc");
searchParam.keywordList.PushBack("123");
// Search for 20 data entries
searchParam.searchCount = 20;
// Start searching from the latest session
searchParam.searchCursor = "";

auto callback = new ValueCallback<V2TIMMessageSearchResult>{};
callback->SetCallback(
[=](const V2TIMMessageSearchResult& messageSearchResult) {
// Data found successfully
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Failed to find the data
delete callback;
});

V2TIMManager::GetInstance()->GetMessageManager()->SearchCloudMessages(searchParam, callback);

Searching for the Messages in the Specified Session

When a user enters keywords in the search box to search for messages, you can call searchCloudMessages (Android/iOS and Mac/Windows) to search for messages.
Below is the sample code:
Android
iOS & Mac
Windows
List<String> keywordList = new ArrayList<>();
keywordList.add("abc");
keywordList.add("123");
V2TIMMessageSearchParam searchParam = new V2TIMMessageSearchParam();
// Search for one-to-one messages with the 'user1' user
searchParam.setConversationID("c2c_user1");
// Set the keyword for the search
searchParam.setKeywordList(keywordList);
// Search for 20 data entries
searchParam.setSearchCount(20);
// Start searching from the latest session
searchParam.setSearchCursor("");
// Start searching from the current time
searchParam.setSearchTimePosition(0);
// Search for messages within 10 minutes
searchParam.setSearchTimePeriod(600);
V2TIMManager.getMessageManager().searchCloudMessages(searchParam,newV2TIMValueCallback<V2TIMMessageSearchResult>() {
@Override
public void onSuccess(V2TIMMessageSearchResult v2TIMMessageSearchResult) {
// Data found successfully
}
@Override
public void onError(int code, String desc) {
// Failed to find the data
}
});
V2TIMMessageSearchParam *param = [[V2TIMMessageSearchParam alloc] init];
// Set the keyword for the search
param.keywordList = @[@"abc", @"123"];
param.messageTypeList = nil;
// Search for one-to-one messages with the 'user1' user
param.conversationID = @"c2c_user1";
param.searchTimePosition = 0;
param.searchTimePeriod = 0;
// Search for 20 data entries
param.searchCount = 20;
// Start searching from the latest session
param.searchCursor = @"";
[V2TIMManager.sharedInstance searchCloudMessages:param
succ:^(V2TIMMessageSearchResult *searchResult) {
// The search was successful, and the search results are returned in searchResult
} fail:^(int code, NSString *desc) {
// Failed to find the data
}];
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;
ValueCallback() = default;
~ValueCallback() override = default;
void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}
void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

V2TIMMessageSearchParam searchParam;
// Search for one-to-one messages with the 'user1' user
searchParam.conversationID = "c2c_user1";
// Set the keyword for the search
searchParam.keywordList.PushBack("abc");
searchParam.keywordList.PushBack("123");
// Search for 20 data entries
searchParam.searchCount = 20;
// Start searching from the latest session
searchParam.searchCursor = "";

auto callback = new ValueCallback<V2TIMMessageSearchResult>{};
callback->SetCallback(
[=](const V2TIMMessageSearchResult& messageSearchResult) {
// Data found successfully
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Failed to find the data
delete callback;
});

V2TIMManager::GetInstance()->GetMessageManager()->SearchCloudMessages(searchParam, callback);

Typical Use Cases for the Search

In general IM chat software, a search UI is usually displayed as follows:
Figure 1. Chat Record
Figure 2. More Chat Record
Figure 3. Messages in the specified session
Loading…

Loading…

Loading…

The following describes how to implement the above use cases through IM SDK's search APIs.

Displaying the Latest Active Sessions

As shown in Figure 1, a list of the latest three sessions to which the messages found belong is displayed at the bottom. The implementation method is as follows:
1. Setting search parameters V2TIMMessageSearchParam
conversationID set to null, indicates searching messages from all sessions.
searchCursor set to "", indicates searching for the latest data.
searchCount set to 3, indicates returning the number of the most recent sessions, typically showing 3 entries on the UI.
2. Handling search callback results V2TIMMessageSearchResult
totalCount indicates the number of all sessions to which the matched messages belong.
The messageSearchResultItems list contains the last 3 sessions (as per the searchCount parameter). messageCount of V2TIMMessageSearchResultItem indicates the total number of messages found in the current session;
If the number of messages found is > 1, then messageList will be empty. You can display "4 related chat records" on the UI, where 4 represents the messageCount.
If the number of messages found = 1, then messageList is the message that matches. You can display the message content on the UI and highlight the search keyword, for example, "test" in the Typical Use Cases for the Search image.
Below is the sample code:
Android
iOS & Mac
Windows
List<String> keywordList = new ArrayList<>();
keywordList.add("test");
V2TIMMessageSearchParam v2TIMMessageSearchParam = new V2TIMMessageSearchParam();
// Setting `conversationID` to `null` is to search for messages in all sessions and the results will be classified by session
v2TIMMessageSearchParam.setConversationID(null);
v2TIMMessageSearchParam.setKeywordList(keywordList);
v2TIMMessageSearchParam.setSearchCursor("");
v2TIMMessageSearchParam.setSearchCount(3);
V2TIMManager.getMessageManager().searchCloudMessages(v2TIMMessageSearchParam, newV2TIMValueCallback<V2TIMMessageSearchResult>() {
@Override
public void onSuccess(V2TIMMessageSearchResult v2TIMMessageSearchResult) {
// Total number of matched sessions to which messages belong
int totalCount = v2TIMMessageSearchResult.getTotalCount();
// Last three messages classified by session
List<V2TIMMessageSearchResultItem> resultItemList = v2TIMMessageSearchResult.getMessageSearchResultItems();
for (V2TIMMessageSearchResultItem resultItem : resultItemList) {
// Session ID
String conversationID = resultItem.getConversationID();
// Total number of messages matching the session
int totalMessageCount = resultItem.getMessageCount();
// Message list: If totalMessageCount > 1, this list is empty; if totalMessageCount = 1, this list Element (XML) is this message
List<V2TIMMessage> v2TIMMessageList = resultItem.getMessageList();
}
}
@Override
public void onError(int code, String desc) {
}
});
V2TIMMessageSearchParam *param = [[V2TIMMessageSearchParam alloc] init];
param.keywordList = @[@"test"];
// Setting `conversationID` to `nil` is to search for messages in all sessions and the results will be classified by session
param.conversationID = nil;
param.searchCursor = @"";
param.searchCount = 3;
[V2TIMManager.sharedInstance searchCloudMessages:param succ:^(V2TIMMessageSearchResult *searchResult) {
// Total number of matched conversations to which messages belong
NSInteger totalCount = searchResult.totalCount;
// Last three messages classified by session
NSArray<V2TIMMessageSearchResultItem *> *messageSearchResultItems = searchResult.messageSearchResultItems;
for (V2TIMMessageSearchResultItem *searchItem in messageSearchResultItems) {
// Conversation ID
NSString *conversationID = searchItem.conversationID;
// Total number of messages matching the session
NSUInteger messageCount = searchItem.messageCount;
// Message list
NSArray<V2TIMMessage *> *messageList = searchItem.messageList ?: @[];
}
} fail:^(int code, NSString *desc) {
// fail
}];
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;
ValueCallback() = default;
~ValueCallback() override = default;
void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}
void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

V2TIMMessageSearchParam searchParam;
// Setting conversationID to null searches for messages in all sessions, and results will be classified by session
searchParam.conversationID = "";
searchParam.keywordList.PushBack("test");
searchParam.searchCursor = "";
searchParam.searchCount = 3;

auto callback = new ValueCallback<V2TIMMessageSearchResult>{};
callback->SetCallback(
[=](const V2TIMMessageSearchResult& messageSearchResult) {
// Total number of matched sessions to which messages belong
uint32_t totalCount = messageSearchResult.totalCount;
// Last three messages classified by session
V2TIMMessageSearchResultItemVector messageSearchResultItems =
messageSearchResult.messageSearchResultItems;
for (size_t i = 0; i < messageSearchResultItems.Size(); ++i) {
// Session ID
V2TIMString conversationID = messageSearchResultItems[i].conversationID;
// Total number of messages matching the session
uint32_t messageCount = messageSearchResultItems[i].messageCount;
// Message list: If messageCount > 1, this list is empty; if messageCount = 1, this list Element (XML) is this message
V2TIMMessageVector messageList = messageSearchResultItems[i].messageList;
}
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Failed to find the data
delete callback;
});

V2TIMManager::GetInstance()->GetMessageManager()->SearchCloudMessages(searchParam, callback);

Displaying the list of sessions to which the messages found belong

Clicking on "More chat records" in figure 1 of the Typical Use Cases for the Search will redirect to figure 2, displaying the list of sessions to which all the found messages belong. The search parameters and results description are similar to the scenario described above.
To prevent memory bloat, we strongly recommend that you load the session list by paging. For example, load by page, displaying 10 session results per page, the search parameter V2TIMMessageSearchParam can be set as follows:
1. For the first call: set searchCount = 10, searchCursor = "". Call searchCloudMessages to obtain the message search results, parse and display them on the homepage, and obtain the total number of sessions totalCount and the cursor for the next request searchCursor from the result callback.
2. When the interface is almost scrolled to the bottom, continue to pull the next page of data based on the cursor searchCursor from the previous request results.
Below is the sample code:
Android
iOS & Mac
Windows
......
// Logging the search cursor
String searchCursor = "";
......

private void searchConversation(String cursor) {
List<String> keywordList = new ArrayList<>();
keywordList.add("test");
V2TIMMessageSearchParam v2TIMMessageSearchParam = new V2TIMMessageSearchParam();
v2TIMMessageSearchParam.setConversationID(null);
v2TIMMessageSearchParam.setKeywordList(keywordList);
v2TIMMessageSearchParam.setSearchCount(10);
v2TIMMessageSearchParam.setSearchCursor(cursor);
V2TIMManager.getMessageManager().searchCloudMessages(v2TIMMessageSearchParam, newV2TIMValueCallback<V2TIMMessageSearchResult>() {
@Override
public void onSuccess(V2TIMMessageSearchResult v2TIMMessageSearchResult) {
// Total number of matched sessions to which messages belong
int totalCount = v2TIMMessageSearchResult.getTotalCount();
// Cursor for the next page
searchCursor = v2TIMMessageSearchResult.getSearchCursor();
// Information of messages classified by session
List<V2TIMMessageSearchResultItem> resultItemList = v2TIMMessageSearchResult.getMessageSearchResultItems();
for (V2TIMMessageSearchResultItem resultItem : resultItemList) {
// Session ID
String conversationID = resultItem.getConversationID();
// Total number of messages matching the session
int totalMessageCount = resultItem.getMessageCount();
// Message list: If totalMessageCount > 1, this list is empty; if totalMessageCount = 1, this list Element (XML) is this message
List<V2TIMMessage> v2TIMMessageList = resultItem.getMessageList();
}
}
@Override
public void onError(int code, String desc) {
}
});
}

// Load the next page
public void loadMore() {
searchConversation(searchCursor);
}
......
// Logging the search cursor
NSString *searchCursor = @"";
......

- (void)searchConversation:(NSString *)cursor {
V2TIMMessageSearchParam *param = [[V2TIMMessageSearchParam alloc] init];
param.keywordList = @[@"test"];
param.conversationID = nil;
param.searchCursor = cursor;
param.searchCount = 10;
[V2TIMManager.sharedInstance searchCloudMessages:param succ:^(V2TIMMessageSearchResult *searchResult) {
// Total number of matched sessions to which messages belong
NSUInteger totalCount = searchResult.totalCount;
// Cursor for the next page
searchCursor = searchResult.searchCursor;
// Information of messages classified by session
NSArray<V2TIMMessageSearchResultItem *> *messageSearchResultItems = searchResult.messageSearchResultItems;
for (V2TIMMessageSearchResultItem *searchItem in messageSearchResultItems) {
// Session ID
NSString *conversationID = searchItem.conversationID;
// Total number of messages matching the session
NSUInteger totalMessageCount = searchItem.messageCount;
// Message list: If totalMessageCount > 1, this list is empty; if totalMessageCount = 1, this list Element (XML) is this message
NSArray<V2TIMMessage *> *messageList = searchItem.messageList ?: @[];
}
} fail:^(int code, NSString *desc) {
// fail
}];
}

// Load the next page
- (void)loadMore {
[self searchConversation:searchCursor];
}
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;
ValueCallback() = default;
~ValueCallback() override = default;
void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}
void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

// Logging the search cursor
V2TIMString searchCursor = "";

void SearchConversation(V2TIMString cursor) {
V2TIMMessageSearchParam searchParam;
searchParam.keywordList.PushBack("test");
searchParam.searchCursor = cursor;
searchParam.searchCount = 10;
auto callback = new ValueCallback<V2TIMMessageSearchResult>{};
callback->SetCallback(
[=](const V2TIMMessageSearchResult& messageSearchResult) {
// Total number of matched sessions to which messages belong
uint32_t totalCount = messageSearchResult.totalCount;
// Cursor for the next page
searchCursor = messageSearchResult.searchCursor;
// Information of messages classified by session
V2TIMMessageSearchResultItemVector messageSearchResultItems =
messageSearchResult.messageSearchResultItems;
for (size_t i = 0; i < messageSearchResultItems.Size(); ++i) {
// Session ID
V2TIMString conversationID = messageSearchResultItems[i].conversationID;
// Total number of messages matching the session
uint32_t messageCount = messageSearchResultItems[i].messageCount;
// Message list: If messageCount > 1, this list is empty; if messageCount = 1, this list Element (XML) is this message
V2TIMMessageVector messageList = messageSearchResultItems[i].messageList;
}
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Failed to find the data
delete callback;
});
V2TIMManager::GetInstance()->GetMessageManager()->SearchLocalMessages(searchParam, callback);
}

// Load the next page
void LoadMore() { SearchConversation(searchCursor); }

Displaying the Messages of a Specified Session

Unlike the session list shown in figure 2 in the Typical Use Cases for the Search, figure 3 displays the list of messages found in a specified session. To prevent memory bloat, we strongly recommend paginating the message display. For example, paginate and show 10 message results per page:
1. Search parameter V2TIMMessageSearchParam settings can be referred to as follows:
Setting the search parameter V2TIMMessageSearchParam's conversationID as the session ID you are searching for.
Initial call: Set the parameter searchCount = 10, searchCursor = "". Call searchCloudMessages to obtain the message search results, parse and display them on the homepage, and obtain the total number of sessions totalCount and the cursor for the next page searchCursor from the result callback.
Subsequent call: Update the value of searchCursor to the return value from the callback of the previous call.
2. Handling the search results V2TIMMessageSearchResult:
totalCount indicates the total number of messages matched in that session.
messageSearchResultItems list contains only the results for that session. In the list, messageCount of V2TIMMessageSearchResultItem is the number of messages on that page, and messageList is the list of messages on that page.
searchCursor represents the starting cursor for the next page search.
Below is the sample code:
Android
iOS & Mac
Windows
......
// Record the search cursor
String searchCursor = "";
......

private void searchMessage(String cursor) {
List<String> keywordList = new ArrayList<>();
keywordList.add("test");
V2TIMMessageSearchParam v2TIMMessageSearchParam = new V2TIMMessageSearchParam();
v2TIMMessageSearchParam.setConversationID(conversationID);
v2TIMMessageSearchParam.setKeywordList(keywordList);
v2TIMMessageSearchParam.setSearchCount(10);
v2TIMMessageSearchParam.setSearcuCursor(cursor);
V2TIMManager.getMessageManager().searchCloudMessages(v2TIMMessageSearchParam,newV2TIMValueCallback<V2TIMMessageSearchResult>() {
@Override
public void onSuccess(V2TIMMessageSearchResult v2TIMMessageSearchResult) {
// Total number of messages matching the session
int totalMessageCount = v2TIMMessageSearchResult.getTotalCount();
// Cursor for the next page
searchCursor = v2TIMMessageSearchResult.getSearchCursor();
// Number of messages on the current page
List<V2TIMMessageSearchResultItem> resultItemList = v2TIMMessageSearchResult.getMessageSearchResultItems();
for (V2TIMMessageSearchResultItem resultItem : resultItemList) {
// Session ID
String conversationID = resultItem.getConversationID();
// The number of messages on the current page
int totalMessageCount = resultItem.getMessageCount();
// List of messages on the current page
List<V2TIMMessage> v2TIMMessageList = resultItem.getMessageList();
}
}
@Override
public void onError(int code, String desc) {
}
});
}
// Load the next page
public void loadMore() {
searchMessage(searchCursor);
}
......
// Record the search cursor
NSString *searchCursor = @"";
......

- (void)searchMessage:(NSString *)cursor {
V2TIMMessageSearchParam *param = [[V2TIMMessageSearchParam alloc] init];
param.keywordList = @[@"test"];
// conversationID is the session ID to search
param.conversationID = conversationID;
param.searchCursor = cursor;
param.searchCount = 10;
[V2TIMManager.sharedInstance searchCloudMessages:param succ:^(V2TIMMessageSearchResult *searchResult) {
// Total number of messages matching the session
NSUInteger totalMessageCount = searchResult.totalCount;
// Cursor for the next page
searchCursor = searchResult.searchCursor;
// Messages on the current page
NSArray<V2TIMMessageSearchResultItem *> *messageSearchResultItems = searchResult.messageSearchResultItems;
for (V2TIMMessageSearchResultItem *searchItem in messageSearchResultItems) {
// Session ID
NSString *conversationID = searchItem.conversationID;
// The number of messages on the current page
NSUInteger totalMessageCount = searchItem.messageCount;
// List of messages on the current page
NSArray<V2TIMMessage *> *messageList = searchItem.messageList ?: @[];
}
} fail:^(int code, NSString *desc) {
// fail
}];
}

// Load the next page
- (void)loadMore {
[self searchMessage:searchCursor];
}
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;
ValueCallback() = default;
~ValueCallback() override = default;
void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}
void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

// Record the search cursor
V2TIMString searchCursor = "";

void SearchConversation(V2TIMString cursor) {
V2TIMMessageSearchParam searchParam;
searchParam.conversationID = conversationID;
searchParam.keywordList.PushBack("test");
searchParam.searchCursor = cursor;
searchParam.searchCount = 10;
auto callback = new ValueCallback<V2TIMMessageSearchResult>{};
callback->SetCallback(
[=](const V2TIMMessageSearchResult& messageSearchResult) {
// The number of all messages matched by the session
uint32_t totalCount = messageSearchResult.totalCount;
// Cursor for the next page
searchCursor = messageSearchResult.searchCursor;
// Messages on the current page
V2TIMMessageSearchResultItemVector messageSearchResultItems =
messageSearchResult.messageSearchResultItems;
for (size_t i = 0; i < messageSearchResultItems.Size(); ++i) {
// Session ID
V2TIMString conversationID = messageSearchResultItems[i].conversationID;
// Number of messages on the current page
uint32_t messageCount = messageSearchResultItems[i].messageCount;
// List of messages on the current page
V2TIMMessageVector messageList = messageSearchResultItems[i].messageList;
}
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Search failed
delete callback;
});
V2TIMManager::GetInstance()->GetMessageManager()->SearchCloudMessages(searchParam, callback);
}

// Load the next page
void LoadMore() { SearchConversation(SearchCursor); }

Searching for a Custom Message

Typically, if you use the createCustomMessage(data) (Android/iOS & Mac/Windows) API to create a custom message, the message cannot be found because the SDK saves it as a binary data stream.
If you want your custom messages to be searchable, you must use the createCustomMessage(data, description, extension) (Android/iOS & Mac/Windows) API to create and send custom messages, placing the searchable text in the description parameter.
If you have configured the offline push feature, after setting the description parameter, your custom messages will also have offline push and the notification bar will display the content of that parameter. If you don't need offline push, you can control it with the disablePush in the V2TIMOfflinePushInfo parameter of the sendMessage (Android/iOS & Mac/Windows) API.
If you do not want the content displayed in the push notification bar to be the searchable text, you can use the desc in the V2TIMOfflinePushInfo parameter to set the push content differently.

Searching for a Rich Media Message

Rich media messages include file, image, audio, and video messages.
For file messages, the interface usually displays the file name. If you pass the fileName parameter when calling createFileMessage to create a file message, fileName will be used as the content of the file message to be searched and matched with the search keyword. If fileName is not set, the SDK will automatically extract the file name from filePath as the search content. Both fileName and filePath information is saved to the local device and server, and can be searched after pulling relevant information on a new device.
For image, audio, and video messages, there is no such name as fileName, and the interface usually displays a thumbnail or duration, making the specification of keywordList ineffective for searches. If you wish to search for such messages, you can specify messageTypeList as V2TIM_ELEM_TYPE_IMAGE/V2TIM_ELEM_TYPE_SOUND/V2TIM_ELEM_TYPE_VIDEO for categorized searches, which will then retrieve all messages of the specified types.


Search Cloud Users

Description

You can search for cloud users by user ID, nickname, gender, and other information to quickly find the required user profile. This feature is suitable for scenarios where specific user information needs to be found, such as finding users to add as friends in familiar social scenes or finding users to follow in stranger social scenes.
Note:
The cloud user search feature is supported only by version 8.4 or later.
This feature is a value-added feature, see Billing Overview for more information.
If this service is not activated, calling the interface will return the error code 60020.

Search Cloud Users Interface

Call the searchUsers (Java / Swift / Objective-C / C++) interface to search for user information in the cloud,This interface returns user information stored in the cloud, including friend and non-friend information. You can call the checkFriend (Java / Swift / Objective-C / C++)
interface to determine whether a user is a friend.
The parameters of V2TIMUserSearchParam are as follows:
Parameter
Meaning
Description
keywordList
Keyword list
It can contain up to five keywords,keyword will automatically match the user ID and nickname.
keywordListMatchType
Match type of the keyword list
You can set it to search with "OR" logic or "AND" logic. The values are V2TIM_KEYWORD_LIST_MATCH_TYPE_OR and V2TIM_KEYWORD_LIST_MATCH_TYPE_AND, respectively. By default, it uses "OR" logic.
gender
User gender
If not set, both male and female are returned by default.
minBirthday
User’s minimum birthday
If not set, the default value is 0.
maxBirthday
User's maximum birthday
If not set, all users with birthday >= minBirthday will be returned by default.
searchCount
Search Count
Must be greater than 0, maximum supported is 100, default is 20.
searchCursor
Search Cursor
Starting position, fill in an empty character string for the first time, and fill in the searchCursor from the last V2TIMUserSearchResult returned for subsequent pulls.

User Search Result Class

The message search result class is V2TIMUserSearchResult(Java / Swift / Objective-C / C++) . The parameters are as described below:
Parameter
Meaning
Description
isFinished
Is the search finished
Whether all users that meet the search criteria have been returned.
totalCount
Total search results
The total count of users that meet the search criteria.
nextCursor
Continue pulling the cursor
The search cursor for the next cloud search.
userList
User List
The user list returned by the current cloud search.
Below is the sample code:
Java
Swift
Objective-C
C++
V2TIMUserSearchParam searchParam = new V2TIMUserSearchParam();
searchParam.setKeywordList(keywordList);
searchParam.setKeywordListMatchType(param.V2TIM_KEYWORD_LIST_MATCH_TYPE_OR);
searchParam.setSearchCount(20);
searchParam.setSearchCursor("");

V2TIMManager.getInstance().searchUsers(searchParam, new V2TIMValueCallback<V2TIMUserSearchResult>() {
@Override
public void onSuccess(V2TIMUserSearchResult userSearchResult) {
// search users succ
}

@Override
public void onError(int code, String desc) {
// search users failed
}
});
let param = V2TIMUserSearchParam()
param.gender = .V2TIM_GENDER_UNKNOWN;
param.keywordList = ["keyword1", "keyword2"];
param.keywordListMatchType = .V2TIM_KEYWORD_LIST_MATCH_TYPE_OR;
param.searchCount = 20;
param.searchCursor = "";
V2TIMManager.shared.searchUsers(param: param) { searchResult in
// search users succ
} fail: { code, desc in
// search users failed
}
V2TIMUserSearchParam *param = [[V2TIMUserSearchParam alloc] init];
param.gender = V2TIM_GENDER_UNKNOWN;
param.keywordList = @[@"keyword1", @"keyword2"];
param.keywordListMatchType = V2TIM_KEYWORD_LIST_MATCH_TYPE_OR;
param.searchCount = 20;
param.searchCursor = @"";
[[V2TIMManager sharedInstance] searchUsers:param succ:^(V2TIMUserSearchResult *searchResult) {
// search users succ
} fail:^(int code, NSString *desc) {
// search users failed
}];

template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

ValueCallback() = default;
~ValueCallback() override = default;

void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}

void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

V2TIMUserSearchParam searchParam;
searchParam.keywordList = keywordList;
param.keywordListMatchType = V2TIM_KEYWORD_LIST_MATCH_TYPE_OR;
param.searchCount = 20;
param.searchCursor = "";

auto callback = new ValueCallback<V2TIMUserSearchResult>{};
callback->SetCallback(
[=](const V2TIMUserSearchResult& userSearchResult) {
// search users succ
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// search users failed
delete callback;
});

V2TIMManager::GetInstance()->SearchUsers(searchParam, callback);


Search Cloud Groups

Description

You can search for cloud groups by group ID, group name, and other information to quickly find the required group profile. This feature is particularly useful for scenarios where specific groups need to be found, such as finding interest groups to join in social settings.
Note:
The cloud group search feature is supported only by version 8.4 or later.
This feature is a value-added feature, see Billing Overview for more information.
If this service is not activated, calling the interface will return the error code 60020.

Search Cloud Groups Interface

Call the searchCloudGroups (Java / Swift / Objective-C / C++) interface to search for group information in the cloud.
The parameters ofV2TIMGroupSearchParam are as follows:
Parameter
Meaning
Description
keywordList
Keyword list
It can contain up to five keywords, the keyword will automatically match the group id and group name.
keywordListMatchType
Match type of the keyword list
You can set it to search with "OR" logic or "AND" logic. The values are V2TIM_KEYWORD_LIST_MATCH_TYPE_OR and V2TIM_KEYWORD_LIST_MATCH_TYPE_AND, respectively. By default, it uses "OR" logic.
searchCount
Search Count
Must be greater than 0, maximum supported is 100, default is 20.
searchCursor
Search Cursor
Starting position, fill in an empty character string for the first time, and fill in the searchCursor from the last V2TIMGroupSearchResult returned for subsequent pulls.

Group Search Result Class

The message search result class is V2TIMGroupSearchResult(Java / Swift / Objective-C / C++) . The parameters are as described below:
Parameter
Meaning
Description
isFinished
Is the search finished
Whether all groups that meet the search criteria have been returned.
totalCount
Total search results
The total count of groups that meet the search criteria.
nextCursor
Continue pulling the cursor
The search cursor for the next cloud search.
groupList
Group List
The group list returned by the current cloud search.
Below is the sample code:
Java
Swift
Objective-C
C++
V2TIMGroupSearchParam searchParam = new V2TIMGroupSearchParam();
searchParam.setKeywordList(keywordList);
searchParam.setKeywordListMatchType(param.V2TIM_KEYWORD_LIST_MATCH_TYPE_OR);
searchParam.setSearchCount(20);
searchParam.setSearchCursor("");

V2TIMManager.getGroupManager().searchCloudGroups(searchParam, new V2TIMValueCallback<V2TIMGroupSearchResult>() {
@Override
public void onSuccess(V2TIMGroupSearchResult groupSearchResult) {
// search cloud groups succ
}

@Override
public void onError(int code, String desc) {
// search cloud groups succ failed
}
});
let param = V2TIMGroupSearchParam()
param.keywordList = ["keyword1", "keyword2"];
param.keywordListMatchType = .V2TIM_KEYWORD_LIST_MATCH_TYPE_OR;
param.searchCount = 20;
param.searchCursor = "";
V2TIMManager.shared.searchCloudGroups(searchParam: param) { searchResult in
// search cloud groups succ
} fail: { code, desc in
// search cloud groups succ failed
}
V2TIMGroupSearchParam *param = [[V2TIMGroupSearchParam alloc] init];
param.keywordList = @[@"keyword1", @"keyword2"];
param.keywordListMatchType = V2TIM_KEYWORD_LIST_MATCH_TYPE_OR;
param.searchCount = 20;
param.searchCursor = @"";
[[V2TIMManager sharedInstance] searchCloudGroups:param succ:^(V2TIMGroupSearchResult *searchResult) {
// search cloud groups succ
} fail:^(int code, NSString *desc) {
// search cloud groups succ failed
}];
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

ValueCallback() = default;
~ValueCallback() override = default;

void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}

void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

V2TIMGroupSearchParam searchParam;
searchParam.keywordList = keywordList;
searchParam.keywordListMatchType = V2TIM_KEYWORD_LIST_MATCH_TYPE_OR;
searchParam.searchCount = 20;
searchParam.searchCursor = "";

auto callback = new ValueCallback<V2TIMGroupSearchResult>{};
callback->SetCallback(
[=](const V2TIMGroupSearchResult& groupSearchResult) {
// search cloud groups succ
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// search cloud groups succ failed
delete callback;
});

V2TIMManager::GetInstance()->GetGroupManager()->SearchCloudGroups(searchParam, callback);


Search Cloud Group Members

Description

You can search for cloud group members by memberID, nickName, and nameCard information. This feature is particularly useful for quickly finding specific group members, such as quickly locating a member in a large group.
Note:
The cloud group member search feature is supported only by version 8.4 or later.
This feature is a value-added feature, see Billing Overview for more information.
If this service is not activated, calling the interface will return the error code 60020.

Search Cloud Group Members Interface

Call the searchCloudGroupMembers (Java / Swift / Objective-C / C++) interface to search for group member information in the cloud。
The parameters of V2TIMGroupMemberSearchParam are as follows:
Parameter
Meaning
Description
keywordList
Keyword list
It can contain up to five keywords, the keyword will automatically match the group member id 、nickname and name card.
keywordListMatchType
Match type of the keyword list
You can set it to search with "OR" logic or "AND" logic. The values are V2TIM_KEYWORD_LIST_MATCH_TYPE_OR and V2TIM_KEYWORD_LIST_MATCH_TYPE_AND, respectively. By default, it uses "OR" logic.
groupIDList
Specify group id list
If groupIDList is set to null,it means searching for group members in all groups, and the returned results will be classified by groupID
If groupIDList is set to not null, it means searching for group members in the specified group.
searchCount
Search Count
Must be greater than 0, maximum supported is 100, default is 20.
searchCursor
Search Cursor
Starting position, fill in an empty character string for the first time, and fill in the searchCursor from the last V2TIMGroupMemberSearchResult returned for subsequent pulls.

Group Member Search Result Class

The message search result class is V2TIMGroupMemberSearchResult(Java / Swift / Objective-C / C++) . The parameters are as described below:
Parameter
Meaning
Description
isFinished
Is the search finished
Whether all group members that meet the search criteria have been returned.
totalCount
Total search results
The total count of group members that meet the search criteria.
nextCursor
Continue pulling the cursor
The search cursor for the next cloud search.
memberList
Member List
The group member list returned by the current cloud search.
Below is the sample code:
Java
Swift
Objective-C
C++
V2TIMGroupMemberSearchParam searchParam = new V2TIMGroupMemberSearchParam();
searchParam.setKeywordList(keywordList);
searchParam.setKeywordListMatchType(param.V2TIM_KEYWORD_LIST_MATCH_TYPE_OR);
searchParam.setGroupIDList(groupIDList);
searchParam.setSearchCount(20);
searchParam.setSearchCursor("");

V2TIMManager.getGroupManager().searchCloudGroupMembers(searchParam, new V2TIMValueCallback<V2TIMGroupMemberSearchResult>() {
@Override
public void onSuccess(V2TIMGroupMemberSearchResult groupMemberSearchResult) {
// search cloud groups succ
}

@Override
public void onError(int code, String desc) {
// search users failed
}
});
let param = V2TIMGroupMemberSearchParam()
param.keywordList = ["keyword1", "keyword2"];
param.keywordListMatchType = .V2TIM_KEYWORD_LIST_MATCH_TYPE_OR;
param.groupIDList= ["Specify group ID"];
param.searchCount = 20;
param.searchCursor = "";
V2TIMManager.shared.searchCloudGroupMembers(searchParam: param) { searchResult in
// search cloud groups succ
} fail: { code, desc in
// search users failed
}

V2TIMGroupMemberSearchParam *param = [[V2TIMGroupMemberSearchParam alloc] init];
param.keywordList = @[@"keyword1", @"keyword2"];
param.keywordListMatchType = V2TIM_KEYWORD_LIST_MATCH_TYPE_OR;
param.groupIDList= @[@"Specify group ID"];
param.searchCount = 20;
param.searchCursor = "";
[[V2TIMManager sharedInstance] searchCloudGroupMembers:param succ:^(V2TIMGroupMemberSearchResult *searchResult) {
// search cloud groups succ
} fail:^(int code, NSString *desc) {
// search users failed
}];
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

ValueCallback() = default;
~ValueCallback() override = default;

void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}

void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

V2TIMGroupMemberSearchParam param;
param.keywordList = keywordList;
param.keywordListMatchType = V2TIM_KEYWORD_LIST_MATCH_TYPE_OR;
param.groupIDList = groupIDList;
param.searchCount = 20;
param.searchCursor = "";

auto callback = new ValueCallback<V2TIMGroupMemberSearchResult>{};
callback->SetCallback(
[=](const V2TIMGroupMemberSearchResult& groupMemberSearchResult) {
// search cloud groups succ
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// search users failed
delete callback;
});

V2TIMManager::GetInstance()->GetGroupManager()->SearchCloudGroupMembers(param, callback);

Exchange and Feedback

Join the Telegram technical exchange group or WhatsApp discussion group, benefit from the support of professional engineers, and solve your toughest challenges.
Was this page helpful?
You can also Contact Sales or Submit a Ticket for help.
Yes
No

Feedback

Contact Us

Contact our sales team or business advisors to help your business.

Technical Support

Open a ticket if you're looking for further assistance. Our Ticket is 7x24 avaliable.

7x24 Phone Support
Hong Kong, China
+852 800 906 020 (Toll Free)
United States
+1 844 606 0804 (Toll Free)
United Kingdom
+44 808 196 4551 (Toll Free)
Canada
+1 888 605 7930 (Toll Free)
Australia
+61 1300 986 386 (Toll Free)
EdgeOne hotline
+852 300 80699
More local hotlines coming soon