搜索和筛选

Telegram 允许在聊天中查找消息时应用详细的消息筛选条件。

搜索筛选器

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#762b263d flags:# inexact:flags.1?true count:int next_rate:flags.0?int offset_id_offset:flags.2?int search_flood:flags.3?SearchPostsFlood 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 groups_only:flags.2?true users_only:flags.3?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;

使用messages.search或messages.searchGlobal时,可以应用特定的消息过滤器。
这允许服务器根据文本查询甚至消息类型来过滤消息,图形客户端通常使用此功能来实现聊天记录、聊天头像等功能。可用过滤器:

返回的messages.Messages构造函数包含分页参数、消息本身以及两个可用于显示计数器的offset_id_offset/参数。例如,在显示聊天照片库时,我们可以在顶部显示一个计数器。countprogress/totalphoto 134 of 200
photo ${offset_id_offset} of ${count}

搜索计数器

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>;

如上图所示,无需获取实际消息即可返回带有过滤器的聊天计数器。

全球搜索

全局搜索视图应该拆分成多个标签页:

聊天标签页

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#762b263d flags:# inexact:flags.1?true count:int next_rate:flags.0?int offset_id_offset:flags.2?int search_flood:flags.3?SearchPostsFlood 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 groups_only:flags.2?true users_only:flags.3?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;

包含所有私人/秘密聊天、私人/公共群组、私人/公共频道的结果(用户和消息),分为以下几个部分:

在“聊天”选项卡中进行搜索时,应调用messages.searchGlobal,将前面提到的部分替换为同伴(头像+名称)和消息(每个同伴最多一条消息)的列表。

频道选项卡

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#762b263d flags:# inexact:flags.1?true count:int next_rate:flags.0?int offset_id_offset:flags.2?int search_flood:flags.3?SearchPostsFlood 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 groups_only:flags.2?true users_only:flags.3?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;

仅包含来自私有/公共频道的结果,分为以下几个部分:

在“频道”选项卡中进行搜索时,应调用messages.searchGlobal并broadcasts_only设置标志,将前面提到的部分替换为对等节点列表(头像+名称+返回的消息,每个对等节点最多一行)。

应用选项卡

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#762b263d flags:# inexact:flags.1?true count:int next_rate:flags.0?int offset_id_offset:flags.2?int search_flood:flags.3?SearchPostsFlood 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 groups_only:flags.2?true users_only:flags.3?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;

用于实现迷你应用商店。

仅包含具有关联主小程序(即设置了用户标志bot_has_main_app)的机器人,分为以下几个部分:

在“应用”选项卡中进行搜索时,应调用messages.searchGlobal,将前面提到的部分替换为返回的机器人主小应用的头像、名称和 MAU 计数器(来自user.bot_active_users)列表(客户端应仅使用返回的字段,筛选设置了user.标志的机器人)。usersbot_has_main_app

帖子选项卡

searchPostsFlood#3e0b5b6a flags:# query_is_free:flags.0?true total_daily:int remains:int wait_till:flags.1?int stars_amount:long = SearchPostsFlood;messages.messagesSlice#762b263d flags:# inexact:flags.1?true count:int next_rate:flags.0?int offset_id_offset:flags.2?int search_flood:flags.3?SearchPostsFlood messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;---functions---channels.checkSearchPostsFlood#22567115 flags:# query:flags.0?string = SearchPostsFlood;channels.searchPosts#f2c4f24d flags:# hashtag:flags.0?string query:flags.1?string offset_rate:int offset_peer:InputPeer offset_id:int limit:int allow_paid_stars:flags.2?long = messages.Messages;

channels.searchPosts在使用设置标志调用时query,会在所有公共频道中全局搜索指定的查询字符串。

全球帖子搜索是付费的:高级用户可获得一定数量的免费搜索次数,超出部分每次搜索需要消耗一定数量的星星。
这意味着用户需要手动发起搜索,在输入框中输入查询内容后,再点击单独的按钮即可,这与其他搜索不同,其他搜索几乎是实时进行的(虽然有一定的防抖功能),用户在输入框中输入查询内容后即可立即进行搜索。

在调用channels.searchPosts方法之前,调用channels.checkSearchPostsFlood获取每日免费搜索槽总数 (searchPostsFlood.total_daily) 和剩余 (searchPostsFlood.remains) 数量,以及何时会有更多免费搜索槽可供用户使用 (searchPostsFlood.wait_till)。

此外,如果指定的搜索是空闲的,并且不会占用空闲的搜索槽位(即服务器已缓存该搜索,或者由于其他服务器端的原因),则会为某些查询设置searchPostsFlood标志。query_is_free

channels.searchPosts总是会返回messages.messagesSlice,其中search_flood可能设置了标志(如果标志没有更改,则可能不存在),其中包含searchPostsFlood的新值(query_is_free仅与当前调用相关,与下一次分页调用无关,所有后续分页调用都将始终是免费的)。

如果用户已用完所有免费搜索槽位,并且用户决定支付searchPostsFlood.stars来stars_amount进行搜索,而不是等待searchPostsFlood.wait_till,则将参数传递stars_amount给allow_paid_starschannels.searchPosts,以授权支付指定数量的Telegram Stars来执行搜索。

媒体选项卡

搜索照片+视频消息。

搜索应该调用messages.searchGlobal并传入inputMessagesFilterPhotoVideo过滤器,按照聊天选项卡中指定的方式呈现结果。

最初,该选项卡应填充通过传入空字符串返回的结果q。

下载选项卡

包含本地生成的从所有对等节点下载的媒体(任何类型的)列表。

搜索应在此列表内进行本地搜索。

链接选项卡

搜索包含链接的消息。

搜索应该调用messages.searchGlobal并使用inputMessagesFilterUrl过滤器,并按照聊天选项卡中指定的方式呈现结果。

最初,该选项卡应填充通过传入空字符串返回的结果q。

文件选项卡

搜索包含文件的邮件。

搜索应该调用messages.searchGlobal并使用inputMessagesFilterDocument过滤器,并按照聊天选项卡中指定的方式呈现结果。

最初,该选项卡应填充通过传入空字符串返回的结果q。

乐谱

搜索音乐文件。

搜索应该调用messages.searchGlobal并传入inputMessagesFilterMusic过滤器,并按照聊天选项卡中指定的方式呈现结果。

最初,该选项卡应填充通过传入空字符串返回的结果q。

语音留言选项卡

搜索语音留言。

搜索应该调用messages.searchGlobal并传入inputMessagesFilterVoice过滤器,并按照聊天选项卡中指定的规则呈现结果。

最初,该选项卡应填充通过传入空字符串返回的结果q。

全球话题标签搜索

---functions---channels.searchPosts#f2c4f24d flags:# hashtag:flags.0?string query:flags.1?string offset_rate:int offset_peer:InputPeer offset_id:int limit:int allow_paid_stars:flags.2?long = messages.Messages;

可以使用特殊的channels.searchPosts方法全局搜索公共频道(包括我们不是成员的频道)中的帖子以及公共用户、频道和群组(包括我们从未见过的非联系人和同行)中的故事,这些帖子包含特定的标签(该标签应在字段中传递,不hashtag带#):在这种情况下,query不得设置标志(此标志用于全局帖子搜索,而是 »)。

另外,请参阅此处 »以了解有关故事全局搜索的更多信息(使用全局搜索栏时不应触发此功能,而应仅在点击故事标签和位置标签时触发)。