Как я создал Telegram-бота для автоматизации Wildberries
Привет! Расскажу о проекте, который сэкономил сотням селлеров Wildberries часы рутинной работы — Telegram-боте wb_bot_pro для полной автоматизации работы с маркетплейсом.
Проблема
Исходная ситуация:
- Селлеры тратили 2-3 часа в день на ручную выгрузку данных из личного кабинета WB
- Отчёты по продажам собирались вручную в Excel
- Новые заказы FBS пропускались, потому что не было уведомлений
- Аналитика велась «на глазок», без точных метрик
- Синхронизация данных ломалась при каждом изменении API
Решение
Разработал полнофункционального Telegram-бота с микросервисной архитектурой:
📦 Основные модули
1. Автоматическая синхронизация данных (auto_data_sync.py)
- При добавлении магазина загружает историю за 365 дней (продажи, заказы) и 90 дней (отчёты реализации)
- Непрерывное обновление каждые 30 минут в рабочее время
- Чанковая загрузка с обходом лимитов API (1 запрос в минуту)
- Сохранение прогресса в SQLite для восстановления после перезапуска
2. FBS-заказы и поставки (supplies.py)
- Получение новых сборочных заданий через
/api/v3/orders - Генерация PDF со стикерами Wildberries + баркодами Code128
- Поддержка принтеров этикеток 58x40 мм
- Автоматическая пагинация: 2 элемента на страницу
3. Аналитика и отчёты (analytics/)
- data_loader.py — загрузка данных из 7 таблиц SQLite
- status_enricher.py — обогащение статусов (realized, returned, canceled, sold, pending)
- metrics_calculator.py — расчёт выручки, прибыли, логистики, штрафов, уровня возвратов
- reports_xlsx.py — Excel с 6 листами (сводка, детализация, ТОП-10, диагностика)
- reports_images.py — 4 графика (статусы, динамика, ТОП-товаров, сводка)
4. Уведомления (notifications.py)
- Мгновенные алерты о новых FBS-заказах
- Фото товара + артикул + размер + цена + баркод
- Поддержка нескольких пользователей на один магазин
- Дедупликация через таблицу
order_notifications
5. Управление ценами (prices.py)
- Выгрузка Excel-шаблона с товарами
- Массовое обновление закупочных цен
- Валидация структуры файла
- Привязка к магазину через chat_id
🛠️ Технический стек
- Язык: Python 3.10+
- Telegram Bot Framework: aiogram 3.x (асинхронный)
- HTTP Client: aiohttp + pydantic для валидации
- База данных: SQLite с потокобезопасными контекстными менеджерами
- PDF: ReportLab + PIL для генерации этикеток
- Excel: openpyxl для отчётов и шаблонов
- Графики: matplotlib с кастомными стилями
- Логирование: кастомный logger с фильтрацией Unicode
📊 Архитектура базы данных
shops -- Магазины (api_token, name)
users -- Пользователи Telegram (chat_id, channel_id)
user_shops -- Связь пользователей и магазинов
orders -- FBS сборочные задания
sales -- Продажи и возвраты (90 дней)
realization_reports -- Отчёты реализации (с 29.01.2024)
prices -- Закупочные цены и скидки
stocks -- Остатки по складам
order_notifications -- Уведомлённые заказы
products -- Карточки товаров
seller_warehouses -- Склады продавца
seller_stocks -- Остатки по складам
🔁 Как работает синхронизация
# Историческая загрузка при добавлении магазина
async def start_initial_sync(shop_id: int, api_token: str):
# 1. Загружаем продажи за 365 дней (чанками по 30 дней)
await _load_historical_chunk("sales")
# 2. Загружаем заказы за 365 дней
await _load_historical_chunk("supplier_orders")
# 3. Загружаем отчёты реализации за 90 дней (по неделям)
await _load_historical_chunk("realization_reports")
# 4. Загружаем FBS заказы за 120 дней
await _load_historical_chunk("orders")
# 5. Синхронизируем товары и остатки
await _sync_products()
await _sync_warehouses_and_stocks()
# Непрерывное обновление в фоне
async def _continuous_sync_loop():
while True:
if _should_sync_now(): # Не синхронизируем 23:00-06:00 МСК
await _sync_recent_data(days=7)
await asyncio.sleep(3600) # Проверка каждый час
🎯 Ключевые фичи
Обработка лимитов API:
- Statistics API: 1 запрос в минуту → очередь запросов с asyncio.sleep(60)
- Marketplace API: 300 запросов в минуту, всплеск 20 → троттлинг
- Пагинация через rrd_id для отчётов реализации
- Курсорная пагинация для товаров (updated_at + nmID)
Работа с датами:
- Все даты в часовом поясе Москва (UTC+3)
- Формат RFC3339 для API:
2024-03-15T23:59:59 - Unix timestamp для Marketplace API
- Автоматическое определение периода для отчётов
Целостность данных:
- DataHealthChecker проверяет дубликаты и актуальность
- Автоматическое исправление расхождений между таблицами
- Таблица
order_notificationsпредотвращает дублирование уведомлений - Soft delete для устаревших товаров
📈 Результат
Метрики после внедрения:
- Время на сбор отчётов: 3 часа → 3 минуты
- Количество пропущенных заказов: 15% → 0%
- Актуальность данных: 1 раз в неделю → каждые 30 минут
- Онбординг новых селлеров: 2 дня → 15 минут
Количество магазинов на одном боте: до 50 одновременно Средний объём данных: ~100k строк продаж + 50k заказов на магазин
Выводы
Главный урок: не экономь на обработке ошибок API. Wildberries API может вернуть 500 ошибку в любой момент, особенно при загрузке больших отчётов. Всегда делай retry с экспоненциальной задержкой и логируй каждый запрос.
Второй важный момент: SQLite достаточно для 95% случаев. При правильной индексации и использовании контекстных менеджеров он легко тянет 50 магазинов с миллионами строк данных.
Если делаешь бота для маркетплейса — сразу закладывай поддержку нескольких API (Statistics + Marketplace), потому что данные в них пересекаются, но не дублируют друг друга полностью.
P.S. Исходный код проекта доступен в репозитории. Если ты селлер на Wildberries и хочешь автоматизировать рутину — пиши, помогу настроить!