Browse SDKs · WASM
SDKsWASM

Search messages

Search locally synchronized messages by keyword and conversation criteria.

Copy

The WASM SDK uses searchLocalMessages() to search messages visible to the current user in local storage. To search group messages, pass the group's conversationID, not the groupID used when sending. If your interface stores only groupID, first obtain the group conversation ID through Get a conversation ID.

The search scope consists of messages that the SDK has synchronized to the browser's local cache. Cross-user auditing, complete server-side search, complex permission filtering, and global sorting should be handled by a backend search service. Return the matching conversationID and clientMsgID to the client so it can locate each message.

Create a search query

keywordList accepts one or more keywords. A search box typically represents one user input. Trim it and filter out empty values before calling the SDK.

import { MessageType } from '@openim/wasm-client-sdk';

type SearchGroupMessagesOptions = {
  conversationID: string;
  keyword: string;
  pageIndex?: number;
  count?: number;
  senderUserIDList?: string[];
};

const searchGroupMessagesByKeyword = async ({
  conversationID,
  keyword,
  pageIndex = 1,
  count = 20,
  senderUserIDList,
}: SearchGroupMessagesOptions) => {
  const normalizedKeyword = keyword.trim();

  if (!normalizedKeyword) {
    return {
      totalCount: 0,
      messages: [],
    };
  }

  const { data } = await openimsdk.searchLocalMessages({
    conversationID,
    keywordList: [normalizedKeyword],
    senderUserIDList,
    messageTypeList: [MessageType.TextMessage, MessageType.AtTextMessage],
    pageIndex,
    count,
  });

  return toSearchRows(data);
};

In addition to keywords, searchLocalMessages() can filter by sender, message type, and time window. Use these criteria to narrow results to specific group members, text messages, or a particular period.

const { data } = await openimsdk.searchLocalMessages({
  conversationID,
  keywordList: ['release'],
  senderUserIDList: [senderUserID],
  messageTypeList: [MessageType.TextMessage],
  searchTimePosition,
  searchTimePeriod,
  pageIndex: 1,
  count: 20,
});

If the search interface supports images, files, or custom messages, include the corresponding MessageType values in messageTypeList. If no message-type restriction is needed, omit the field and let the SDK search its default set of local message types.

Parameters

ParameterTypeRequiredDescription
conversationIDstringYesID of the conversation to search.
keywordListstring[]YesSearch keywords. For a single search box, usually pass one normalized keyword.
keywordListMatchTypenumberNoMatch mode for multiple keywords, using the SDK's numeric convention. Omit it when no special matching behavior is needed.
senderUserIDListstring[]NoSearch only messages sent by these users.
messageTypeListMessageType[]NoSearch only specified message types, such as text and @ mention messages.
searchTimePositionnumberNoStarting timestamp of the search window.
searchTimePeriodnumberNoLength of the time window beginning at searchTimePosition.
pageIndexnumberNoSearch result page number.
countnumberNoNumber of results per page.

Handle paginated results

The returned SearchMessageResult contains totalCount and searchResultItems. Each result item represents one conversation and contains matching MessageItem[] in messageList.

FieldTypeDescription
totalCountnumberTotal number of messages matching the current criteria.
searchResultItemsSearchMessageResultItem[] (optional)Results grouped by conversation from searchLocalMessages().
findResultItemsSearchMessageResultItem[] (optional)Results grouped by conversation when findMessageList() locates messages by ID.

Each SearchMessageResultItem has the following structure:

FieldTypeDescription
conversationIDstringID of the conversation containing the result.
conversationTypeSessionTypeType of the conversation containing the result.
showNamestringSnapshot of the conversation's display name.
faceURLstringSnapshot of the conversation's avatar URL.
messageCountnumberNumber of matching messages in this result item.
messageListMessageItem[]Matching messages. For field descriptions, see Message overview.
import type { SearchMessageResult } from '@openim/wasm-client-sdk';

const toSearchRows = (result: SearchMessageResult) => {
  return {
    totalCount: result.totalCount,
    messages: (result.searchResultItems ?? []).flatMap((item) => {
      return item.messageList.map((message) => ({
        conversationID: item.conversationID,
        clientMsgID: message.clientMsgID,
        senderUserID: message.sendID,
        sentAt: message.sendTime,
        message,
      }));
    }),
  };
};

For subsequent pages, keep conversationID, keywordList, and all filters unchanged and increment only pageIndex. If the user changes the keywords, member filter, or time range, reset pageIndex to 1 and clear old results so results from different criteria are not mixed.

When the searchLocalMessages() Promise resolves, use its return value to establish the search result snapshot. The query does not trigger message events. Within one search view, deduplicate by conversationID + clientMsgID; do not persist a selected result by its array position.

Handle changes to search results

A matched message may be revoked or deleted while the search view is open, and newly synchronized messages may change the search scope. Update results through the shared event handlers on Receive messages, Delete messages in a batch, and Revoke a message. This page handles only search queries and pagination and does not register those message events again.

When navigating to a search result, use its conversationID and clientMsgID to locate the target conversation and message. To display the surrounding chat history, use the matched MessageItem as the anchor for a context query. For parameters, an example, and the result structure, see Load message context. Do not use findMessageList() to assemble nearby history.

To refresh results at the current point in time, run the current page again with the same criteria. The search Promise, incremental message events, and a re-query are three independent paths. After a new login, message changes are synchronized through events.