Search

Telegram allows applying detailed message filters while looking for messages in chats.

Search filters

inputMessagesFilterEmpty#57e2f66c = MessagesFilter;
inputMessagesFilterPhotos#9609a51c = MessagesFilter;
inputMessagesFilterVideo#9fc00e65 = MessagesFilter;
inputMessagesFilterPhotoVideo#56e9f0e4 = MessagesFilter;
inputMessagesFilterDocument#9eddf188 = MessagesFilter;
inputMessagesFilterUrl#7ef0dd87 = MessagesFilter;
inputMessagesFilterGif#ffc86587 = MessagesFilter;
inputMessagesFilterVoice#50f5c392 = MessagesFilter;
inputMessagesFilterMusic#3751b49e = MessagesFilter;
inputMessagesFilterChatPhotos#3a20ecb8 = MessagesFilter;
inputMessagesFilterPhoneCalls#80c99768 flags:# missed:flags.0?true = MessagesFilter;
inputMessagesFilterRoundVoice#7a7c17a4 = MessagesFilter;
inputMessagesFilterRoundVideo#b549da53 = MessagesFilter;
inputMessagesFilterMyMentions#c1f8e69a = MessagesFilter;
inputMessagesFilterGeo#e7026d0d = MessagesFilter;
inputMessagesFilterContacts#e062db83 = MessagesFilter;
inputMessagesFilterPinned#1bb00451 = MessagesFilter;

messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messagesSlice#3a54685e flags:# inexact:flags.1?true count:int next_rate:flags.0?int offset_id_offset:flags.2?int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.channelMessages#c776ba4e flags:# inexact:flags.1?true pts:int count:int offset_id_offset:flags.2?int messages:Vector<Message> topics:Vector<ForumTopic> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messagesNotModified#74535f21 count:int = messages.Messages;

---functions---

messages.search#29ee847a flags:# peer:InputPeer q:string from_id:flags.0?InputPeer saved_peer_id:flags.2?InputPeer saved_reaction:flags.3?Vector<Reaction> top_msg_id:flags.1?int filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int hash:long = messages.Messages;

messages.searchGlobal#4bc6589a flags:# broadcasts_only:flags.1?true folder_id:flags.0?int q:string filter:MessagesFilter min_date:int max_date:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;

When using messages.search or messages.searchGlobal, a certain message filter may be applied.
This allows the server to filter messages based on a text query, and even on their type, and this feature is often used by graphical clients to implement features like the chat gallery, chat profile pictures and more. Available filters:

The returned messages.Messages constructors contain parameters for pagination, the messages themselves and two offset_id_offset/count parameters that can be used to display a progress/total counter like photo 134 of 200.
For example, when displaying the chat photo gallery, we could display a photo ${offset_id_offset} of ${count} indicator on top.

Search counters

messages.searchCounter#e844ebff flags:# inexact:flags.1?true filter:MessagesFilter count:int = messages.SearchCounter;

---functions---

messages.getSearchCounters#1bbcf300 flags:# peer:InputPeer saved_peer_id:flags.2?InputPeer top_msg_id:flags.0?int filters:Vector<MessagesFilter> = Vector<messages.SearchCounter>;

Chat counters with filters can also be returned without fetching the actual messages, as seen in the schema above.

Global search

The global search view should be split into multiple tabs:

Chats tab

topPeerCategoryCorrespondents#637b7ed = TopPeerCategory;
topPeerCategoryBotsPM#ab661b5b = TopPeerCategory;
topPeerCategoryGroups#bd17a14a = TopPeerCategory;
topPeerCategoryChannels#161d9628 = TopPeerCategory;

contacts.topPeers#70b772a8 categories:Vector<TopPeerCategoryPeers> chats:Vector<Chat> users:Vector<User> = contacts.TopPeers;

messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messagesSlice#3a54685e flags:# inexact:flags.1?true count:int next_rate:flags.0?int offset_id_offset:flags.2?int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.channelMessages#c776ba4e flags:# inexact:flags.1?true pts:int count:int offset_id_offset:flags.2?int messages:Vector<Message> topics:Vector<ForumTopic> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messagesNotModified#74535f21 count:int = messages.Messages;

---functions---

contacts.getTopPeers#973478b6 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true forward_users:flags.4?true forward_chats:flags.5?true groups:flags.10?true channels:flags.15?true bots_app:flags.16?true offset:int limit:int hash:long = contacts.TopPeers;

messages.searchGlobal#4bc6589a flags:# broadcasts_only:flags.1?true folder_id:flags.0?int q:string filter:MessagesFilter min_date:int max_date:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;

Contains results (peers and messages) from all private/secret chats, private/public groups, private/public channels, split in the following sections:

Searching when in the "Chats" tab should invoke messages.searchGlobal, replacing the previously mentioned sections with a list of peers (avatar+name) and messages (max one message per peer).

Channels tab

topPeerCategoryChannels#161d9628 = TopPeerCategory;

contacts.topPeers#70b772a8 categories:Vector<TopPeerCategoryPeers> chats:Vector<Chat> users:Vector<User> = contacts.TopPeers;

messages.chats#64ff9fd5 chats:Vector<Chat> = messages.Chats;

messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messagesSlice#3a54685e flags:# inexact:flags.1?true count:int next_rate:flags.0?int offset_id_offset:flags.2?int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.channelMessages#c776ba4e flags:# inexact:flags.1?true pts:int count:int offset_id_offset:flags.2?int messages:Vector<Message> topics:Vector<ForumTopic> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messagesNotModified#74535f21 count:int = messages.Messages;

---functions---

contacts.getTopPeers#973478b6 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true forward_users:flags.4?true forward_chats:flags.5?true groups:flags.10?true channels:flags.15?true bots_app:flags.16?true offset:int limit:int hash:long = contacts.TopPeers;

channels.getChannelRecommendations#25a71742 flags:# channel:flags.0?InputChannel = messages.Chats;

messages.searchGlobal#4bc6589a flags:# broadcasts_only:flags.1?true folder_id:flags.0?int q:string filter:MessagesFilter min_date:int max_date:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;

bots.getPopularAppBots#c2510192 offset:string limit:int = bots.PopularAppBots;

Contains results from private/public channels only, split in the following sections:

Searching when in the "Channels" tab should invoke messages.searchGlobal with the broadcasts_only flag set, replacing the previously mentioned sections with a list of peers (avatar+name+returned message, max one row per peer).

Apps tab

topPeerCategoryBotsApp#fd9e7bec = TopPeerCategory;

contacts.topPeers#70b772a8 categories:Vector<TopPeerCategoryPeers> chats:Vector<Chat> users:Vector<User> = contacts.TopPeers;

bots.popularAppBots#1991b13b flags:# next_offset:flags.0?string users:Vector<User> = bots.PopularAppBots;

// Parse only the `users` field of the following constructors (ignoring messages.channelMessages)
messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messagesSlice#3a54685e flags:# inexact:flags.1?true count:int next_rate:flags.0?int offset_id_offset:flags.2?int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messagesNotModified#74535f21 count:int = messages.Messages;
messages.channelMessages#c776ba4e flags:# inexact:flags.1?true pts:int count:int offset_id_offset:flags.2?int messages:Vector<Message> topics:Vector<ForumTopic> chats:Vector<Chat> users:Vector<User> = messages.Messages;

---functions---

contacts.getTopPeers#973478b6 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true forward_users:flags.4?true forward_chats:flags.5?true groups:flags.10?true channels:flags.15?true bots_app:flags.16?true offset:int limit:int hash:long = contacts.TopPeers;

bots.getPopularAppBots#c2510192 offset:string limit:int = bots.PopularAppBots;

messages.searchGlobal#4bc6589a flags:# broadcasts_only:flags.1?true folder_id:flags.0?int q:string filter:MessagesFilter min_date:int max_date:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;

Used to implement the Mini App Store.

Only contains bots with an associated Main Mini App (i.e. those with the user.bot_has_main_app flag set), split in the following sections:

Searching when in the "Apps" tab should invoke messages.searchGlobal, replacing the previously mentioned sections with a list of avatars, names and MAU counters (from user.bot_active_users) for Main Mini Apps of the returned bots (clients should only use the returned users field, filtering for bots with the user.bot_has_main_app flag set).

Media tab

Searches for photo+video messages.

Searching should invoke messages.searchGlobal with the inputMessagesFilterPhotoVideo filter, rendering the results as specified in the chats tab.

Initially, the tab should be populated with the results returned by passing an empty string in q.

Downloads tab

Contains a locally generated list of recently downloaded media (of any kind) from all peers.

Searching should locally search within this list.

Links tab

Searches for messages with links.

Searching should invoke messages.searchGlobal with the inputMessagesFilterUrl filter, rendering the results as specified in the chats tab.

Initially, the tab should be populated with the results returned by passing an empty string in q.

Files tab

Searches for messages with files.

Searching should invoke messages.searchGlobal with the inputMessagesFilterDocument filter, rendering the results as specified in the chats tab.

Initially, the tab should be populated with the results returned by passing an empty string in q.

Music tab

Searches for music files.

Searching should invoke messages.searchGlobal with the inputMessagesFilterMusic filter, rendering the results as specified in the chats tab.

Initially, the tab should be populated with the results returned by passing an empty string in q.

Voice messages tab

Searches for voice messages.

Searching should invoke messages.searchGlobal with the inputMessagesFilterVoice filter, rendering the results as specified in the chats tab.

Initially, the tab should be populated with the results returned by passing an empty string in q.

Global hashtag search

---functions---

channels.searchPosts#d19f987b hashtag:string offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;

The special channels.searchPosts method may be used to globally search for posts from public channels (including those we aren't a member of) and stories from public users, channels and groups (including non-contacts and peers we've never seen before), containing a specific hashtag (which should be passed in the hashtag field without the #).

See here » for more info on global search for stories (which should not be triggered when using the global search bar, but rather only when clicking on story hashtags and location tags).