Как я создал Telegram-бота для поиска сообщений по ID и не сошел с ума
Всем привет! Хочу поделиться историей, как я с нуля собрал Telegram-бота, который умеет искать сообщения по user_id, выгружать их в Excel и при этом не разваливаться на больших объёмах. Было всего: баги, тормоза, таймауты и вишенка на торте — неожиданный переезд на Windows Server, от которого всё вдруг стало работать.
С чего всё началось
Идея была простая: хотелось бота, который умеет искать все сообщения конкретного пользователя в Telegram-группах, где сидит мой userbot. Чтобы по ID выдать Excel-файл со всеми его сообщениями — удобно, просто, красиво.
Плюс в голове крутилась мысль: а почему бы не сделать это более-менее универсальным инструментом, которым можно делиться или даже масштабировать?
Что использовали
Telethon — слушает чаты и собирает сообщения
Aiogram — обычный Telegram-бот для общения с пользователем
PostgreSQL — база, куда всё складывается
asyncpg — чтобы всё работало асинхронно
Pandas + OpenPyXL — формируем Excel-файл по запросу
Первые проблемы: тормоза в базе
Сначала всё было бодро. Пока в базе было 1000–5000 сообщений — запросы летали. Но когда стало 100K и больше — банальный SELECT COUNT(*) FROM events WHERE user_id = ...
начал отвечать секунд по 10.
Добавили индекс:
CREATE INDEX IF NOT EXISTS idx_events_user_id ON events(user_id);
И... всё стало нормально. Мораль: индексы — это не просто «рекомендация», а «обязательная техника безопасности».
Потом начались таймауты
Когда пользователи стали запрашивать выгрузки по user_id с десятками тысяч сообщений, бот начал падать. Просто — TimeoutError
. Причём всё валилось где-то внутри conn.fetch()
.
Решение оказалось несложным: вместо одной огромной выборки — постраничная загрузка. По 1000 сообщений за раз:
async def fetch_pg_events(pool, user_id, batch_size=1000):
offset = 0
all_rows = []
while True:
async with pool.acquire() as conn:
rows = await conn.fetch("SELECT ... OFFSET $1 LIMIT $2", offset, batch_size)
if not rows:
break
all_rows.extend(rows)
offset += batch_size
return all_rows
Работает стабильно, не падает, не тормозит.
Неожиданный баг: Linux не выдержал
Наш userbot слушал около 100 чатов одновременно. Всё работало на VPS с Ubuntu... пока не переставало. Через пару часов бот просто «умирал». Логов ноль. Подключений больше 500. Была догадка, что это связано с epoll, uvloop или чем-то похожим. Пробовали патчить, отключать uvloop, менять ядра — всё впустую.
В какой-то момент решил: а может попробовать на Windows? И внезапно...
Переезд на Windows Server
Да, это может звучать как «антипаттерн», но Windows Server просто взял и заработал:
asyncio ведёт себя стабильно
Telethon не падает
легче дебажить через RDP
В результате бот уже недели две работает без падений, обрабатывает тысячи новых и старых сообщений, формирует Excel-файлы и не требует лишнего внимания.
Что в итоге
На выходе получился Telegram-бот, который:
ищет сообщения по ID пользователя
умеет выгружать их в Excel с ссылками на оригинал
стабильно работает на PostgreSQL
не падает, не зависает и живёт на Windows Server
Telegram бот: https://t.me/message_searcher