From 553125cd76df8c14b12a7c6e90ab52cd64f8f34e Mon Sep 17 00:00:00 2001 From: Valeriy Pavlovich Date: Sun, 12 Oct 2025 07:14:25 +0300 Subject: [PATCH 1/2] Make `list_messages` predictable and efficient for date ranges and search: avoid over-fetch, apply `limit` after filtering, and separate search from date offsets #27 - stream search results via `client.iter_messages()` and apply date bounds in-code so we collect up to `limit` matches - use server-side iteration for date-only queries with inclusive upper bounds to avoid over-fetching - keep the existing `get_messages()` fast path when no filters are provided --- main.py | 49 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/main.py b/main.py index 87cebe9..4a58dc2 100644 --- a/main.py +++ b/main.py @@ -412,20 +412,47 @@ async def list_messages( # Prepare filter parameters params = {} if search_query: + # IMPORTANT: Do not combine offset_date with search. + # Use server-side search alone, then enforce date bounds client-side. params["search"] = search_query - - messages = await client.get_messages(entity, limit=limit, **params) - - # Apply date filters (Telethon doesn't support date filtering in get_messages directly) - if from_date_obj or to_date_obj: - filtered_messages = [] - for msg in messages: - if from_date_obj and msg.date < from_date_obj: - continue + messages = [] + async for msg in client.iter_messages(entity, **params): # newest -> oldest if to_date_obj and msg.date > to_date_obj: continue - filtered_messages.append(msg) - messages = filtered_messages + if from_date_obj and msg.date < from_date_obj: + break + messages.append(msg) + if len(messages) >= limit: + break + + else: + # Use server-side iteration when only date bounds are present + # (no search) to avoid over-fetching. + if from_date_obj or to_date_obj: + messages = [] + if from_date_obj: + # Walk forward from start date (oldest -> newest) + async for msg in client.iter_messages( + entity, offset_date=from_date_obj, reverse=True + ): + if to_date_obj and msg.date > to_date_obj: + break + if msg.date < from_date_obj: + continue + messages.append(msg) + if len(messages) >= limit: + break + else: + # Only upper bound: walk backward from end bound + async for msg in client.iter_messages( + # offset_date is exclusive; +1µs makes to_date inclusive + entity, offset_date=to_date_obj + timedelta(microseconds=1) + ): + messages.append(msg) + if len(messages) >= limit: + break + else: + messages = await client.get_messages(entity, limit=limit, **params) if not messages: return "No messages found matching the criteria." From f08667c47a44f3440429ae548e3825e32262fb95 Mon Sep 17 00:00:00 2001 From: Valeriy Pavlovich Date: Mon, 13 Oct 2025 21:20:24 +0300 Subject: [PATCH 2/2] Format main.py with Black --- main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 4a58dc2..7d18494 100644 --- a/main.py +++ b/main.py @@ -446,7 +446,8 @@ async def list_messages( # Only upper bound: walk backward from end bound async for msg in client.iter_messages( # offset_date is exclusive; +1µs makes to_date inclusive - entity, offset_date=to_date_obj + timedelta(microseconds=1) + entity, + offset_date=to_date_obj + timedelta(microseconds=1), ): messages.append(msg) if len(messages) >= limit: