# Telegram Shop Bot Телеграм-бот для организации онлайн-продаж через Telegram с поддержкой криптовалют, WireGuard VPN и Tor-прокси для доступа к админ-панели через onion-адрес. ## Возможности - Каталог товаров с категориями и фильтрацией по локациям - Покупки с оплатой криптовалютами (BTC, ETH, LTC, USDT, USDC) - Управление криптокошельками (создание, пополнение, баланс) - История транзакций и покупок - SaaS-система с автоматическим расчётом комиссий - **Мультиязычность (i18n)** — английский, испанский, немецкий с переключением в боте - **Новая админ-панель** (Next.js 16 + Prisma + shadcn/ui) на порту 3000: дашборд, каталог, заказы, кошельки, лиды, ИИ-чатбот, аудит, настройки - Tor-прокси с двумя onion-сервисами (SSH + админка) - WireGuard VPN для безопасных транзакций ## Быстрый старт (одна команда) ### Требования - Любое устройство с Docker: x86_64 (PC, сервер) или ARM64 (Orange Pi, Raspberry Pi) - 512 МБ RAM минимум (Orange Pi Zero 2 поддерживается) ### Установка ```bash git clone && cd telegram-shop bash install.sh ``` Скрипт автоматически: 1. Определит архитектуру (x86_64 / ARM64 / ARMv7) 2. Установит Docker если не установлен 3. Создаст `.env` из шаблона 4. Интерактивно запросит недостающие переменные (BOT_TOKEN, ADMIN_IDS) и сгенерирует ключи (ENCRYPTION_KEY, ADMIN_SECRET, SUPER_ADMIN_SECRET) если они не заданы 5. Установит SHOP_ACTIVATED=false для нового магазина (стартует заблокированным) 6. Автоматически определит LAN IP и установит ADMIN_URL 7. Соберёт Docker-образ под текущую архитектуру 8. Запустит контейнер и проверит health-check #### Активация магазина После установки магазин стартует заблокированным (SHOP_ACTIVATED=false). Оператор получает onion-адрес от клиента, заходит в админку по onion/LAN, входит с SUPER_ADMIN_SECRET, добавляет комиссионные кошельки (Кошельки → Edit Wallets), настраивает бота, нажимает "Activate Shop" в Настройках. ### Ручная установка ```bash # 1. Клонировать git clone && cd telegram-shop # 2. Создать .env из шаблона cp .env.example .env nano .env # заполнить BOT_TOKEN, ADMIN_IDS, ENCRYPTION_KEY # 3. Запустить (образы тянутся из Gitea Container Registry, сборка не нужна) docker compose up -d # 4. Проверить статус docker compose ps curl http://localhost:3001/health # бот (health-сервер) curl -o /dev/null -w "%{http_code}\n" http://localhost:3000/login # новая админка ``` > Образы бота и админки собираются в CI (Gitea Actions, buildx multi-arch) и публикуются в Gitea Container Registry. На сервере ничего не компилируется — только `docker compose pull`. Для пиннинга версии: `IMAGE_TAG=1.2.9 docker compose up -d`. Локальная сборка (dev): `docker compose up -d --build`. ## Настройка .env Скопируйте `.env.example` в `.env` и заполните: | Переменная | Обязательно | Описание | |---|---|---| | `BOT_TOKEN` | ✅ | Токен Telegram бота (@BotFather) | | `ADMIN_IDS` | ✅ | ID администраторов через запятую | | `ENCRYPTION_KEY` | ✅ | Ключ шифрования (32 байта hex) | | `ADMIN_SECRET` | ✅ | Секрет админки (вход в Next.js админку) | | `SUPER_ADMIN_SECRET` | — | Секрет супер-админа (роль super_admin в админке) | | `ADMIN_URL` | — | Полный URL админ-панели (для фото товаров) | | `SUPER_ADMIN_IDS` | — | ID супер-админов | | `SUPPORT_LINK` | — | Ссылка на поддержку | | `DEFAULT_LANGUAGE` | — | Язык по умолчанию (`en`, `es`, `de`; по умолчанию `en`) | | `HEALTH_PORT` | — | Порт health-сервера бота (по умолчанию 3001) | | `SSH_HOST_IP` | — | Куда Tor перенаправляет SSH (по умолчанию host.docker.internal) | | `SHOP_CONTAINER` | — | Имя контейнера админки (onion target; по умолчанию tg_shop_admin) | | `CHATBOT_API_ENDPOINT` | — | OpenAI-совместимый endpoint чатбота (fallback) | | `CHATBOT_API_KEY` | — | API-ключ чатбота (fallback) | | `WG_ENABLED` | — | `true` / `false` (по умолчанию `false`) | | `WG_PRIVATE_KEY` | — | Приватный ключ WireGuard | | `WG_PUBLIC_KEY` | — | Публичный ключ WireGuard | | `WG_PRESHARED_KEY` | — | Pre-shared ключ WireGuard | | `WG_ENDPOINT` | — | Адрес сервера WireGuard | | `WG_ADDRESS` | — | Адрес интерфейса WireGuard | | `WG_DNS` | — | DNS для WireGuard | | `SHOP_ACTIVATED` | — | Флаг активации магазина. false = магазин заблокирован до активации супер-админом в админке (Настройки → Shop Activation). | Генерация ключа шифрования: ```bash node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" ``` ## Tor Proxy Проект включает Tor-прокси для доступа к SSH и админ-панели через onion-адреса. ### Архитектура ``` Internet → Tor Network → tor-proxy контейнер ├── Onion #1 :22 → хост SSH └── Onion #2 :80 → tg_shop_admin:3000 (новая Next.js админка, через Docker сеть tor_proxy_net) ``` Новая админ-панель (`admin-next/`, Next.js 16 + Prisma + shadcn/ui): - Работает на порту 3000 (контейнер `tg_shop_admin`) - Использует **ту же SQLite БД**, что и бот (`db/shop.db`) — любые изменения мгновенно видны боту и наоборот - Вход по токену `ADMIN_SECRET` / `SUPER_ADMIN_SECRET` (из `.env`) - ИИ-чатбот: настройки в БД (`site_settings` ключи `chatbot_*`), бот обращается к `/api/chat` контейнера админки ### Файлы Tor-прокси | Файл | Назначение | |---|---| | `tor-proxy/Dockerfile` | Alpine + Tor образ | | `tor-proxy/entrypoint.sh` | Генерация torrc из env vars, валидация, запись onion-адресов | | `tor-proxy/get-onions.sh` | Скрипт чтения onion-адресов и обновления .env | | `tor-proxy/hosts/` | Директория для onion-hosts.txt (bind mount) | ### После запуска Onion-адреса автоматически сохраняются в `tor-proxy/hosts/onion-hosts.txt`. Обновить `.env`: ```bash ./tor-proxy/get-onions.sh ``` Вывод: ``` ============================================================ Onion services ============================================================ SSH : xxxxx.onion (port 22 -> host SSH) Admin : yyyyy.onion (port 80 -> tg_shop_admin:3000) ============================================================ Usage: SSH : torify ssh user@xxxxx.onion Admin : open http://yyyyy.onion in Tor Browser ``` ### Переменные Tor | Переменная | По умолчанию | Описание | |---|---|---| | `SSH_HOST_IP` | `host.docker.internal` | Куда Tor перенаправляет SSH | | `SHOP_CONTAINER` | `tg_shop_admin` | Контейнер админки (onion target) | | `ADMIN_PORT` | `3000` | Порт админки | ## Поддерживаемые устройства | Устройство | Архитектура | RAM | Статус | |---|---|---|---| | PC / Сервер | x86_64 | ≥ 512 МБ | ✅ | | Orange Pi Zero 2 | ARM64 (H616) | 512 МБ | ✅ | | Raspberry Pi 4 | ARM64 | ≥ 1 ГБ | ✅ | | Raspberry Pi 3 | ARM64 | 1 ГБ | ✅ | | Raspberry Pi 2 | ARMv7 | 1 ГБ | ✅ | Docker автоматически собирает нативные модули (`better-sqlite3`, `tiny-secp256k1`) под архитектуру хоста. ## Архитектура Docker ``` ┌──────────────────────────────────────────────────────────┐ │ docker-compose │ │ │ │ ┌────────────────────────┐ ┌─────────────────────────┐ │ │ │ telegram_shop_prod │ │ tor-proxy │ │ │ │ (node:22-alpine) │ │ (alpine:3.18 + tor) │ │ │ │ │ │ │ │ │ │ Port 3001 ──────────────┼── Бот (health-сервер) │ │ │ │ Bot + Health Server │ HiddenService :80 → админка 3000│ │ │ │ HiddenService :22 → SSH │ │ │ │ │ │ │ │ │ Net: default │ │ Net: default + proxy_net │ │ │ │ + tor_proxy_net │ │ │ │ │ └────────────────────────┘ └─────────────────────────┘ │ │ │ │ │ │ Volumes: Volumes: │ │ db/, uploads/, .env tor_data, hosts/ │ └──────────────────────────────────────────────────────────┘ ``` ### Сети Docker | Сеть | Назначение | |---|---| | `default` | Внутренняя связь между контейнерами | | `tor_proxy_net` | Связь tor-proxy ↔ telegram_shop_prod | ## Команды управления ```bash # Запуск docker compose up -d # Пересборка (dev-сборка локально) или обновление до новой версии из registry docker compose up -d --build # dev: собрать локально IMAGE_TAG=1.2.9 docker compose up -d # prod: взять конкретную версию из registry # Логи docker compose logs -f # Логи конкретного сервиса docker compose logs -f tor-proxy docker compose logs -f telegram_shop_prod # Стоп docker compose down # Рестарт docker compose restart # Статус docker compose ps # Health-check curl http://localhost:3001/health # Onion-адреса docker exec tor-proxy cat /var/lib/tor/ssh/hostname docker exec tor-proxy cat /var/lib/tor/admin/hostname # Обновить .env с onion-адресами ./tor-proxy/get-onions.sh ``` ## WireGuard WireGuard по умолчанию отключен (`WG_ENABLED=false`). Для включения: 1. Установите `WG_ENABLED=true` в `.env` 2. Заполните ключи WireGuard в `.env` 3. Перезапустите: `docker compose restart` Контейнер требует `NET_ADMIN` и `sysctl net.ipv4.conf.all.src_valid_mark=1` для WireGuard. Эти привилегии заданы в `docker-compose.yml`. ## Мультиязычность (i18n) Бот поддерживает 3 языка: **🇬🇧 English**, **🇪🇸 Español**, **🇩🇪 Deutsch**. ### Как это работает - **`/start`** — всегда показывает выбор языка с флагами - **`/language`** — команда для смены языка в любой момент - **Профиль** — кнопка «🌐 Change Language» рядом с «Set Location» - Выбранный язык сохраняется в БД (`users.language`) и используется во всех сообщениях - Интерполяция: `t('key', { param: value })` → `{{param}}` в строках - Fallback: запрошенный язык → English → ключ ### Структура i18n ``` src/i18n/ ├── index.js # tForUser(), tForLang(), LANGUAGE_NAMES, AVAILABLE_LANGUAGES └── locales/ ├── en.json # 201 ключ, английский ├── es.json # 201 ключ, испанский └── de.json # 201 ключ, немецкий ``` ### Админ-панель локализации Вкладка «Локализация» в админ-панели (`/locales`) позволяет просматривать и редактировать все ключи перевода в таблице с сохранением в JSON-файлы. ### Добавление нового языка 1. Создать `src/i18n/locales/.json` по шаблону `en.json` 2. Добавить код в `AVAILABLE_LANGUAGES` и `LANGUAGE_NAMES` в `src/i18n/index.js` 3. Язык автоматически появится в выборе при `/start` и `/language` ## Безопасность - `.env` монтируется только для чтения (`:ro`) - Порт 3001 (бот, health-сервер) и 3000 (админка) доступны из LAN и через Tor onion - Onion-адреса сохраняются в volume (персистентность при перезапуске) - Tor hidden services с валидацией env vars - Новая админка (`admin-next/`): вход по токену, `ADMIN_SECRET`/`SUPER_ADMIN_SECRET` из `.env` - Секреты админки (`admin-next/.env`) исключены из git (`.gitignore`) - Нативные модули компилируются в builder-стейдже - `devDependencies` не попадают в production-образ - Тестовые файлы исключены из Docker-образа (`.dockerignore`) - `node_modules` хоста не попадают в образ (`.dockerignore`) ## Устойчивость к ошибкам - Бот не крашит контейнер при невалидном `BOT_TOKEN`: 5 попыток с задержкой 5с, затем бот отключается, админка продолжает работать - Комиссионные кошельки не обязательны для старта: при отсутствии логируется предупреждение - При потере связи с Telegram API: polling ошибки логируются, процесс продолжает работать ## Структура проекта ``` ├── src/ # Telegram-бот (Node.js) │ ├── config/ # Конфигурация (БД, крипто) │ ├── context/ # Контекст и состояния бота │ ├── handlers/ # Обработчики команд │ │ ├── adminHandlers/ # Обработчики админа (Telegram) │ │ └── userHandlers/ # Обработчики пользователя │ ├── i18n/ # Интернационализация │ │ ├── index.js # tForUser(), tForLang(), LANGUAGE_NAMES │ │ └── locales/ # en.json, es.json, de.json │ ├── middleware/ # Промежуточные обработчики │ ├── migrations/ # Миграции БД (001–014) │ ├── models/ # Модели данных │ ├── router/ # Роутинг callback/text бота │ ├── services/ # Бизнес-логика (вкл. chatbotService, leadService) │ ├── utils/ # Утилиты (логирование, валидация, ошибки) │ ├── __tests__/ # Юнит-тесты (vitest) │ ├── healthServer.js # Минимальный HTTP /health (Docker healthcheck) │ └── index.js # Точка входа ├── admin-next/ # Админ-панель (Next.js 16 + Prisma + shadcn/ui) │ ├── prisma/schema.prisma # Схема БД (та же SQLite, что у бота) │ ├── src/app/api/ # 45 API-роутов (см. docs/API.md) │ ├── src/components/ # UI-компоненты (dashboard, wallets, leads...) │ └── Dockerfile # Multi-stage Next.js standalone ├── docs/ # Документация │ ├── API.md # Справочник REST API админки │ └── DATABASE.md # Структура БД (схема, связи, примечания) ├── tor-proxy/ # Tor прокси для SSH и админки │ ├── Dockerfile # Alpine + Tor образ │ ├── entrypoint.sh # Генерация torrc, валидация env vars │ ├── get-onions.sh # Скрипт обновления .env с onion-адресами │ └── hosts/ # Директория для onion-hosts.txt ├── wg/ # WireGuard конфигурация │ └── start.sh # Скрипт запуска контейнера ├── tests/ # Web-тестирование (visual regression, E2E) │ ├── scripts/ # Скрипты тестов (Playwright, pixelmatch) │ └── visual/ # baseline/current/diff скриншоты ├── docker/ # Дополнительные compose-конфиги (web-testing) ├── db/ # SQLite база данных (volume) ├── uploads/ # Загруженные фото (volume) ├── Dockerfile # Multi-stage сборка магазина ├── docker-compose.yml # Конфигурация трёх контейнеров (бот, админка, tor) ├── install.sh # Установщик (POSIX sh) ├── .dockerignore # Исключения из образа ├── .env.example # Шаблон переменных └── package.json ``` ## Документация | Документ | Содержание | |---|---| | [`docs/API.md`](docs/API.md) | Справочник REST API админ-панели: все эндпоинты, методы, query-параметры, коды ошибок | | [`docs/DATABASE.md`](docs/DATABASE.md) | Структура БД: таблицы, колонки, связи, примечания | | [`VERSION.md`](VERSION.md) | История версий и changelog | ## Разработка ```bash # Установка зависимостей npm install # Запуск в режиме разработки npm run dev # Тесты npm test ``` ## Лицензия MIT