Привет, Хабр! Первая моя первая прикладная статья с конкретным опытом по проекту.
TL;DR: Собрал систему на Python + LLM, которая парсит Telegram-чаты, находит людей с конкретными болями и генерирует персонализированные сообщения для аутрича. 7 чатов по 1000 сообщений — стоимость анализа $0.11.
1. Проблема одного канал продаж
Два года я зарабатываю на фрилансе — делаю Telegram-ботов, Mini Apps и автоматизации для бизнеса. За это время вырос с 40 до 270 тысяч в месяц. Неплохо, но была проблема, которая не давала масштабироваться.
Все заказы приходили с одной фриланс площадки.
Это работало, пока работало. Но возникали независящие от меня проблемы - у клиентов замораживались счета или откладывались проекты — я оставался без денег и без понимания, где брать новых заказчиков. Конечно, тут есть мои ошибки - например не защитил себя от подобных рисков договорами/контрактами. Классическая зависимость от одного канала.
Я пробовал диверсифицироваться:
Fiverr — 4 gig, ноль откликов за полгода (только мошенники писали). Хотя даже заграничную симку приобрел для регистрации. Там неадекватная конкуренция с индусами и пакистанцами.
Telegram-канал — 9 подписчиков (привет, мама. а не, мамы даже там нет)
Проблема была системной: мне нужен стабильный поток лидов, которых можно обрабатывать, передавать стажёрам, масштабировать. Конечно можно начать руками искать по чатам и каналам народ с болью, однако - ручной поиск в чатах — не масштабируется.
2. Идея: автоматизировать то, что делаю руками
Я и раньше находил клиентов в Telegram‑чатах. Заходил в чаты селлеров, логистов, инфобиз. Искал сообщения типа «посоветуйте бота для...» или «как автоматизировать...».
Но это занимало часы, это реально нужно анализировать, думать, вчитываться, смотреть что за пользователь - было непредсказуемо и не масштабировалось.
Я играл в Factorio - и оттуда вновь вдохновился идеей тотальной автоматизации. В игре ты не таскаешь руду руками - строишь конвейеры, которые делают это за тебя. Потом автоматизируешь производство конвейеров. Потом - производство фабрик, которые производят уже сами конвейеры :-)
В разработке я стараюсь делать то же самое. Автоматизирую документацию, скиллы для LLM, пайплайны контейнеров, деплой. Поэтому - каждый повторяющийся шаг - отличный кандидат на автоматизацию!
И тогда пришла такая мысль: а почему бы не автоматизировать основной входящий ресурс - потенциальных заказчиков?
Нужен был конвейер.
Так родилась концепция Lead Finder.
3. Архитектура v1: Web Search (спойлер: не сработало)
Первая идея была очевидной (ну для меня...):
[Описание ниши: "селлеры wildberries"] ↓ [GPT + Web Search ищет Telegram-каналы] ↓ [Telethon парсит найденные каналы] ↓ [GPT квалифицирует: это владелец бизнеса? активен? есть боли?] ↓ [Карточка лида с контактом и готовым сообщением]
Посидел, помыслил как я это хочу видеть - ТЗ на 442 строчки. Расписал каждый модуль. Закинул в Claude Code, и спустя день итераций получил кое какой MVP.
Результат первого запуска
Входная ниша: "селлеры wildberries" Сгенерировано запросов: 5 Найдено каналов: 2 Успешно распарсено: 1 Квалифицировано: 0
Ноль лидов.
Почему не сработало
Web Search находил статьи ПРО каналы ("Топ-10 каналов для селлеров"), а не сами каналы. Google плохо индексирует Telegram и весь его контент. Ну а личные каналы мелких предпринимателей вообще не в поиске - у них там 500 подписчиков...
Можно было бы интегрировать TGStat API, но это усложнение, траты на стадии MVP. Да и главно: даже если найти канал, это ещё не лид с болью. Это просто канал. Поэтому нуно было придумать альтернативу такому поиску.
4. Архитектура v2: Парсинг участников чатов
Тут вспомнил - ведь в начальном ручном методе поиска лидов работа в основном была не с каналами а с Чатами! Поиск по их содержанию, по участникам чата - для самой простой ниши (селлеры маркетплейсов) - это иногда по 10к участников и тысячи сообщений за короткий срез времени.
Короче, мысль: один чат = сотни потенциальных лидов.
Поэтому решил переписать архитектуру:
[Список seed-чатов: @marketplace_pro, @wb_sellers, ...] ↓ [Парсинг 1000 сообщений → кто что писал] ↓ [Фильтрация по времени: только последние 10 дней] ↓ [LLM ищет болевые сообщения в пачке] ↓ [Квалификация авторов болевых сообщений] ↓ [Карточки лидов со ссылками на оригинальные сообщения]
Что изменилось концептуально
v1 | v2 |
|---|---|
Ищем каналы через интернет | Парсим людей из известных чатов |
Надеемся найти владельца бизнеса | Видим реальные сообщения с болями |
Холодный контакт в личку | Можем ответить на конкретное сообщение в чате |
Масштаб: единицы каналов | Масштаб: сотни участников |
Результат
7 чатов по 1000 сообщений. Стоимость анализа — $0.11. На выходе — список людей с конкретными болями, которые они сами написали за последние 10 дней.
5. Как выглядит результат
Карточка лида в Markdown-отчёте:
## Лид #1 — Оценка: 4/5 **Контакт:** @maxsmek **Канал:** @max_seller_wb (1,240 подписчиков) ### Бизнес Селлер Wildberries, ниша — товары для дома. Судя по каналу, оборот 2-5 млн/мес. Ведёт канал сам, делится опытом. ### 💬 Болевые сообщения 🔥 **[2 дня назад]** в @marketplace_pro: "Подскажите тг бота чтобы отслеживать остатки фактические по складам... хоть как-нибудь, даже косвенно, чтобы успевать" [Открыть сообщение →](https://t.me/marketplace_pro/8934) **[5 дней назад]** в @wb_sellers: "Кто автоматизировал ответы на отзывы? Трачу по 2 часа в день" [Открыть сообщение →](https://t.me/wb_sellers/12847) ### Что предложить Telegram-бот для мониторинга остатков по складам WB с алертами при падении ниже порога. ### Готовое сообщение "Макс, привет! Видел твой вопрос в чате про отслеживание остатков по складам. Делаем как раз такие боты — мониторинг в реальном времени + уведомления. Показать как работает?"
Ключевая фича — ссылки на сообщения
По итогу можно кликнуть на ссылку, перейти в чат и ответить прямо на вопрос человека. Это уже не холодный спам, а релевантный ответ на его публичный запрос. Так намного безопаснее, можно не так париться за блок аккаунта. Хотя все равно я создал отдельный для данного дела.
Конверсия второго варианта выше на порядок. Ну, по идее — на практике пока только 1 из 6 ответил нормально, остальные просто проигнорили. Но хотя бы не пожаловались)
6. Технические детали
Стек
Python 3.11 — основа
Telethon — Telegram API для парсинга
gpt-5.1 — для квалификации (через CometAPI — прокси-площадка, доступная в России)
Docker — для изоляции и Telegram-сессий
Claude Code — для разработки (раньше сидел на Cursor, но понял что каждый раз в восторге когда выбираю Claude - поэтому переехал полностью)
Как основная IDE — NeoVim, привык со времён Arch (сейчас на Mac переехал). Cursor иногда использую, но только для быстрого чтения и редактирования файлов.
Почему gpt-5.1 через CometAPI
Для квалификации использую gpt-5.1 через CometAPI — это прокси для OpenAI API, доступный в России. Оптимально по соотношению цена/качество. Сначала ехал на gpt-4.1 - но посмотрел что input у обеих моделей одинаковый, output у 5.1 дороже - но он меня не интересует - мне надо именно загружать в него большое количество сообщений для анализа. Пробовал Claude Sonnet — дороже при сопоставимом качестве для этой задачи. Экономия на масштабе ощутимая.
ЭТО НЕ РЕКЛАМА!
Telethon и авторизация
Как уже говорил - для Telethon использую дополнительный аккаунт - с него же потом и пишу лидам.
Сначала хотел сделать бота более общедоступным - авторизацию Telethon пропустить через самого бота. Но Telegram заметил подмену и запретил так делать. Поэтому пока использую только для себя - код ввожу в терминале вручную при создании файла сессии.
Сессии храню просто: локальный файл, который Docker забирает себе. Создаётся изолированно при помощи отдельного скрипта вне контейнера.
Логика обработки сообщений
Берём 1000 сообщений из чата
Отсекаем всё старше 10 дней
Отправляем пачку в LLM для поиска болевых сообщений
Запоминаем авторов болевых сообщений
Квалифицируем каждого автора отдельно
Люди без личного канала тоже анализируются - просто у них ниже оценка, меньше гарантий что это реально владелец бизнеса. Не отсекаю сразу.
Система оценок
Изначально делал 0-10, потом упростил до 0-5. Где 1 — уже потенциальный лид, но я работаю с оценкой от 2. Так проще фильтровать и меньше шума.
Web Search для обогащения
Изначально добавил поиск упоминаний в сети — username + ниша, имя + "отзывы". Но честно — пока не заметил конкретного буста в качестве квалификации. Траты есть, а выхлопа особого нет. Держу отключённым, может потом докручу.
Защита от бана
Telegram банит за агрессивный парсинг. Реализовал три режима:
Режим | Задержка между чатами | Между запросами |
|---|---|---|
fast | 15-30 сек | 1-2 сек |
normal | 30-60 сек | 2-3 сек |
careful | 60-120 сек | 3-5 сек |
Плюс:
Рандомизация всех интервалов (не ровно 3 сек, а 2.3-3.7)
Лимит чатов за сессию
Обработка
FloodWaitError— ждём сколько сказали + буфер
За месяц использования — ни одного бана.
Структура проекта (v2)
lead_finder/ ├── config.py # Конфигурация и режимы безопасности ├── modules/ # Core-логика (используется и CLI, и ботом) │ ├── input_handler.py # Валидация входных данных │ ├── members_parser.py # Парсинг участников чатов │ ├── qualifier.py # LLM квалификация │ ├── output.py # Форматирование результатов │ └── enrichment/ │ ├── telegram.py # Парсинг каналов лидов │ └── web_search.py # Обогащение через поиск ├── bot/ # Telegram-бот (v3, добавлен позже) │ ├── main.py # Точка входа бота │ ├── handlers/ # Обработчики команд и кнопок │ ├── models/ # SQLAlchemy модели │ ├── services/ # Бизнес-логика (runner, scheduler) │ └── ui/ # Форматирование сообщений ├── generate_session.py # Создание Telethon сессии └── docker-compose.yml
7. Грабли и факапы
v1 с Web Search — главный провал
Потратил день на начальную архитектуру, которая не взлетела. Но это нормально - быстрые итерации важнее идеального плана. Переделал за день.
Claude Code уходит не туда
Конечно, это происходит постоянно. Самая частая проблема - забываешь прописать в инструкции, что нельзя трогать старый функционал. Начинает улучшать старые функции, которые работали. Откатываю через git, добавляю ограничение в промпт, еду дальше.
Ложноположительные
Система дала 4/5, а человек оказался не тем - конечно бывает. Поэтому читаю карточки внимательно, а не спамлю всем подряд. LLM квалифицирует, но финальное решение — моё.
Авторизация через бота
Хотел красиво — чтобы пользователь авторизовывался прямо в боте. Telegram такое не пропустил. Пришлось откатиться к ручному вводу кода в терминале. Не масштабируется, но работает для личного использования.
8. Честные цифры
v2 (CLI)
Метрика | Значение |
|---|---|
Время разработки v2 | ~8 часов чистого времени |
Строк кода (core модули) | ~1000 сток мы выдал Claude |
Стоимость анализа 7 чатов | $0.11 |
v3 (Telegram-бот)
Метрика | Значение |
|---|---|
Время разработки v3 | ~1 неделя (поверх v2) |
Строк кода (бот + БД) | ~1500 дополнительно |
Стек | aiogram 3.x, SQLAlchemy, APScheduler, PostgreSQL |
Использование
Метрика | Значение |
|---|---|
Seed-чатов в базе | ~30 (5 категорий по 4-8 чатов) |
Активных программ в боте | 3 (селлеры, edtech, smm) |
Написал лидам | 6 |
Ответили | 1 (сказал "если потребуется — напишет") |
Конверсия в заказ | пока 0, но и выборка маленькая |
Категории чатов: маркетплейсы, предприниматели, edtech, smm, риэлторы.
Честно — конверсия пока не впечатляет. Но система работает меньше месяца, выборка маленькая. Главное — процесс автоматизирован, я трачу минуты вместо часов на поиск.
9. v3: Telegram-бот (реализовано после CLI)
После того как CLI-версия заработала, захотелось полной автоматизации. Тратить время на ручные запуски — не масштабируется.
За следующие несколько дней собрал полноценный Telegram-бот на aiogram 3.x.
Что получилось
Программы поиска — сохранённые конфигурации:
Название + ниша ("Селлеры WB", "Инфобизнес")
Список чатов для парсинга
Настройки (min_score, max_leads, обогащение)
Расписание автозапуска
Автозапуск по расписанию:
APScheduler интегрирован в бота
Каждая программа запускается в своё время
После завершения — бот присылает уведомление с результатами
Дедупликация:
SQLAlchemy + PostgreSQL
Лиды с одним username не дублируются
История сохраняется, можно вернуться к старым
Интерфейс через inline-кнопки:
Никаких команд — только кнопки
Создание программы — пошаговый диалог (FSM)
Карточки лидов приходят прямо в бот
Пример работы
Утром в 09:00:
🔔 Автозапуск завершён 📁 Селлеры WB ⏰ Запуск в 09:00 📊 Результаты: • Новых лидов: 5 [👀 Посмотреть лидов]
Нажимаю кнопку — получаю карточки:
🎯 Лид #1 из 5 Программа: Селлеры WB ━━━━━━━━━━━━━ 👤 @username ⭐ Оценка: 4/5 💼 Бизнес: Селлер на WB... 😤 Боли: Теряет заявки между Excel и мессенджерами 💡 Что предложить: Бот для сбора заявок... 📝 Сообщение для @username: ━━━━━━━━━━━━━ Привет! Видел твой вопрос про потерю заявок. У нас есть готовое решение... [⏭ Следующий лид]
Стек бота
aiogram 3.5 — асинхронный фреймворк для Telegram
SQLAlchemy 2.0 — ORM для БД
PostgreSQL — основная база (на продакшене), SQLite для локальной разработки
APScheduler — планировщик задач
Docker — всё работает в контейнере
Что изменилось архитектурно
CLI-модули (members_parser, qualifier, enrichment) стали библиотекой — бот их импортирует и использует как есть. Не пришлось переписывать логику.
Разделение на CLI и бот позволило оставить оба интерфейса:
CLI — для отладки, тестов, ручных прогонов
Бот — для ежедневного использования
Грабли с ботом
APScheduler и asyncio:
Scheduler хотел синхронные job-функции, а весь код — async. Решение: обернул async-функции в asyncio.create_task().
База заблокирована (SQLite):
Несколько одновременных запусов программ — database locked. Перешёл на PostgreSQL для проды, проблема ушла.
FSM состояния терялись:
Использовал MemoryStorage — при перезапуске бота состояния сбрасывались. Для продакшена можно RedisStorage, но пока живу с этим.
Ошибка .get() на None:
LLM иногда возвращал product_idea: None вместо {}. Код падал с AttributeError. Исправил все места на .get(key) or {} вместо .get(key, {}).
10. Что дальше
v3 работает, но есть что улучшить:
Следующие шаги:
Парсинг комментариев в каналах (сейчас только чаты)
Мониторинг новых сообщений в чатах в реальном времени
Скраппинг фриланс-площадок - Kwork, FL.ru
A/B тестирование сообщений аутрича
Про сервис для других:
Хотелось бы открыть как сервис. Проблема - авторизация Telethon. Каждому пользователю нужна своя сессия, а Telegram не пропускает автоматизацию через ботов. Варианты:
Генерировать сессию вручную для каждого (не масштабируется)
Использовать Telegram Login Widget (пока не разобрался как подружить с Telethon)
Ограничиться self-hosted версией с инструкцией
Пока использую только для себя. Если у кого есть идеи — пишите
Реальный пример сообщений
🎯 Лид #14 из ?? Программа: Маркетплейсы 👤 @скроююзернейм ⭐ Оценка: 2/5 💭 С высокой вероятностью владелец или самостоятельно управляющий продавец на маркетплейсах. Есть явный запрос: отслеживать отзывы по кластерам на Ozon и WB. Боль формулируется как вопрос, без деталей объёма и последствий, поэтому глубина боли и формат решения пока неочевидны. Потенциально можно закрыть задачей по сбору и структурированию отзывов через парсер и дашборд но нужно уточнение, что именно она хочет видеть под «кластерами». 💼 Бизнес: Селлер на маркетплейсах Ozon и Wildberries (Малый бизнес) 😤 Боли: • «Подскажите, можно ли через какие либо программы отследить отзывы по кластерам ? На озон и вб» 💡 Что предложить: Сервис/скрипт-парсер отзывов с Ozon и Wildberries с кластеризацией по темам и визуализацией в дашборде ✅ Решает: Автоматический сбор и группировка отзывов по темам вместо ручного просмотра, что позволяет быстрее видеть типовые проблемы и запросы покупателей 💰 Ценность: Экономия времени на ручной разбор отзывов, возможность оперативно видеть повторяющиеся проблемы и улучшать карточки/продукт по данным 📝 Сообщение для @тутимяпользователя: ИМЯ, вы спрашивали в чате, можно ли отслеживать отзывы по кластерам на Ozon и WB. Это как раз можно сделать через парсер + небольшой дашборд: отзывы автоматически подтягиваются и группируются по темам (качество, доставка, размер и т.п.). Если интересно, могу показать, как это технически реализуется и что вы сможете видеть в отчётах, а вы поймёте, подходит ли это под ваши задачи.
11. Выводы
1. Автоматизируй свои процессы, а не только клиентские.
Вместо очередного бота для заказчика потратил 15 часов (8 на CLI + 7 на бот) на инструмент, который приносит заказчиков. ROI потенциально бесконечный.
2. LLM-first разработка работает.
Я не написал ни строчки кода руками - всё через Claude Code. От идеи до работающего MVP за 8 часов. От CLI до полноценног бота с БД и работы п расписанию - ещё неделя. Всем рекомендую! Кто читал мои прошлые статьи — знает методологию.
3. Провалы — часть процесса.
v1 с Web Search не сработала. Вместо того чтобы упираться, переделал архитектуру. v2 взлетела. Быстрые итерации важнее идеального плана. Провал — это информация, не приговор.
4. Документация — это контекст.
Каждую версию начинал с детального ТЗ. Это позволяло передавать контекст между сессиями Claude и не терять фокус. ТЗ - это не бюрократия, это инструмент мышления. Особенно критично когда разрабатываешь с LLM. Фиксирую все ошибки, в отдельные ISSUES.md, каждая новая фича - новая документация, которая не должна конфликтовать с текущей реализаций. Каждый успешный запуск нового этапа - RESULT.md в котоом задокументирован пруф успеха.
5. Модульная архитектура окупается.
CLI-модули стали библиотекой для бота без переписывания. Разделение интерфейса (CLI/bot) и логики (парсинг/квалификация) позволило эволюционировать систему без заметных проблем (на возможно есть незаметные).
Если интересна методология LLM-разработки — в прошлой статье подробно разобрал работу с документацией, TDD и управление контекстом. А еще нагло тут прицеплю ссылку на канал нашей команды.
Готов к гнилым помидорам. Как показывает практика — это только добавляет просмотров)
