Pull to refresh

Как я создал Telegram-бота для поиска сообщений по ID и не сошел с ума

Level of difficultyEasy

Всем привет! Хочу поделиться историей, как я с нуля собрал 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

Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.