Telegram-бот для подбора компьютерных комплектующих и периферии. Проект хранит каталог в PostgreSQL, показывает древовидное меню через inline-кнопки и даёт администратору пошаговые сценарии добавления категорий, карточек и характеристик.
- Главное меню с категориями из базы данных.
- Вложенное дерево категорий: периферия, комплектующие ПК, звук, мониторы, накопители, питание, корпуса и другие разделы.
- Кнопка
ℹ️ Информацияпервой в каждой категории. - Встроенные кнопки категорий и карточек выводятся по 5 элементов на страницу.
- Шестая строка при необходимости содержит стрелки
⬅️и➡️. - В каждой вложенной категории и списке карточек есть строка
⬅️ Назади🏠 Главная. - Карточки товаров сортируются по цене по возрастанию.
- Карточка содержит цену, характеристики, подробное описание, страну/рынок и ссылки, если они заполнены.
- Поле
Где купитьхранится отдельно как свободный текст (buy_text), поэтому можно писатьOZON, AliExpress, DNS, а не только URL. - Поиск
/find <запрос>ищет по названию, описанию и характеристикам. - Админ-панель
/adminподдерживает управление категориями, товарами, характеристиками, JSON-импортом и администраторами. - Добавление категории и товара работает пошагово: бот спрашивает поля по одному, поэтому администратору не нужно присылать заранее собранный JSON или “красивое” сообщение.
app/
bot/
handlers/ # Telegram-сценарии: старт, навигация, поиск, админка
keyboards/ # Встроенные клавиатуры
middlewares/ # Логирование, обработка ошибок, задел под rate limit
states/ # Состояния сценариев админ-панели
core/
config.py # Настройки из .env
database.py # Асинхронный движок SQLAlchemy и сессии
seed.py # Наполнение каталога категориями и карточками
migrations/ # Alembic-миграции
models/ # ORM-модели категорий, товаров и характеристик
navigation/ # Разбор callback, стек экранов и рендереры
repositories/ # SQL-запросы
services/ # Бизнес-логика
utils/ # Форматирование сообщений
Основные таблицы:
categories— дерево категорий. Поля:id,parent_id,title,slug,info_text,sort_order.products— карточки товаров. Поля:id,category_id,title,price_rub,price_usd,description,country,youtube_url,buy_url,buy_text.product_specs— характеристики карточек. Поля:id,product_id,spec_key,spec_value.
Связи:
- категория может иметь родительскую категорию;
- категория содержит много товаров;
- товар содержит много характеристик;
- удаление категории каскадно удаляет вложенные товары и характеристики.
Callback-данные короткие и не хранят всё состояние экрана:
main_menu— главная страница;cat:<id>— переход в категорию или список товаров;catinfo:<id>— справка категории;catpage:<id|root>:<page>— страницы категорий;product:<id>— карточка товара;next/prev— страницы списка товаров;back— возврат по стеку экранов.
Стек пользователя хранится в app/navigation/storage.py, поэтому кнопка “Назад” возвращает к предыдущему экрану, а не просто пересобирает меню наугад.
Вход: /admin. Доступ задаётся через ADMIN_IDS в .env.
Категории:
- создать категорию;
- удалить категорию;
- вывести дерево с
idиslug; - при создании бот спрашивает название, slug или автозаполнение,
parent_id, текст для кнопкиИнформация.
Товары:
- создать карточку;
- посмотреть карточку по
product_id; - отредактировать поле;
- удалить карточку;
- добавить, изменить или удалить характеристику.
Пошаговое добавление товара:
- Администратор выбирает конечную категорию из списка.
- Бот спрашивает название.
- Бот спрашивает цену в рублях.
- Бот спрашивает цену в долларах.
- Бот автоматически берёт шаблон характеристик из уже существующих карточек этой категории и спрашивает каждое поле по очереди.
- Бот спрашивает описание.
- Бот спрашивает страну.
- Бот спрашивает ссылку на обзор.
- Бот спрашивает ссылку на покупку.
- Бот спрашивает свободный текст
Где купить. - При необходимости бот позволяет добавить дополнительные характеристики.
Пример: если выбрать Периферия → Звук → Наушники → IEM, бот будет спрашивать поля по шаблону IEM-карточек: драйверы, частоты, импеданс, чувствительность и другие характеристики, уже встречающиеся в этой категории.
Каталог перенесён из папки C:\Users\LaskaMEOW\Downloads\Telegram Desktop\Дерево.
generate_tree_data.py читает вложенные папки и конечные .txt файлы, затем формирует app/core/tree_data.py. В текущем дереве распознано:
- 64 категории;
- 323 карточки товаров;
Информация.txtкак справочный текст категории;- обычные
.txtкак карточки товара.
Каждая карточка разбирается на структурированные поля:
title;price_rub;price_usd;description;country;buy_text;specs.
app/core/seed.py создаёт дерево категорий и заполняет базу этими карточками. Название файла становится названием inline-кнопки, а содержимое файла превращается в карточку товара с характеристиками.
Если база уже содержит корневые категории, seed не перезаписывает данные. Для полного пересоздания каталога используется reset_and_seed_catalog().
Создать .env:
BOT_TOKEN=123456:telegram-token
DB_HOST=postgres
DB_PORT=5432
DB_NAME=pc_helper
DB_USER=pc_helper
DB_PASSWORD=pc_helper_password
ADMIN_IDS=123456789
APP_ENV=development
LOG_LEVEL=INFOЗапуск через Docker:
docker compose up -d --build
docker compose logs -f botМиграции выполняются при старте. Вручную:
docker compose run --rm bot alembic upgrade headЛокально выполнена синтаксическая проверка:
python -m compileall appДополнительно есть офлайн-проверка релизного наполнения:
python release_check.pyОжидаемый результат:
release_check ok: 64 categories, 323 products, Hisenior template verified
Полный запуск бота требует установленных зависимостей из pyproject.toml, настроенной PostgreSQL и реального BOT_TOKEN.
Большой список источников вынесен в CARD_SOURCES.md. Там собраны официальные страницы производителей, базы характеристик, русскоязычные и международные обзорные сайты, PSU-лаборатории, источники по мониторам и аудио.