Skip to content

unlimy-org/unlimy

Repository files navigation

VPN Telegram Bot (MVP)

Телеграм-бот для продажи VPN с inline-сценарием и хранением состояния в PostgreSQL.

Что реализовано

  • Полностью inline UX с чистыми последовательными экранами.
  • Единственная команда пользователя: /start. Дальше вся навигация только inline-кнопками.
  • После /start главное меню: Купить VPN, Личный кабинет, Сменить язык.
  • Личный кабинет: Инфо и помощь, История покупок, Мои конфиги.
  • Раздел Инфо и помощь: документы (ссылки на соглашение/политику) и тикет-система поддержки (создание обращений, история, ответы).
  • После Купить VPN 3 кнопки: Готовые тарифы, Создать свой тариф, Назад.
  • Ветка Готовые тарифы: сначала выбор семейства тарифа, затем длительности, затем оплата.
  • Ветка Создать свой тариф: страна -> сервер (с ping) -> протокол -> длительность -> количество подключений -> оплата.
  • После оплаты бот отправляет задачу на мастер-ноду (localhost:6767) и опрашивает статус каждые 15 секунд до готовности конфига.
  • Есть история заказов (из таблицы оплат) и список конфигов с возможностью обновить конфиг без оплаты.
  • Мультиязычность: ru, en, uz, kk, tg, az, be, hy, ky, uk.
  • Один активный экран: предыдущее сообщение бота удаляется, кроме первого /start у новых пользователей.
  • На ключевых экранах используются изображения (старт, кабинет, смена языка).
  • Платежные ветки:
  • SBP как локальная симуляция (success, failed, cancel).
  • Telegram Stars через send_invoice (валюта XTR).
  • Crypto Bot через API (createInvoice, getInvoices).

Технологии

  • Python 3.12+
  • aiogram 3
  • asyncpg
  • PostgreSQL 16 (через Docker Compose)

Структура проекта

app/
  main.py                 # Точка входа, DI и polling
  config.py               # Загрузка ENV в Settings
  handlers/start.py       # /start, кнопки, платежи, back-навигация
  keyboards/inline.py     # Inline клавиатуры
  locales/translations.py # Словари переводов и tr()
  db/repository.py        # Работа с БД + автосоздание таблиц
  services/
    catalog.py            # Каталог готовых тарифов + формула custom тарифа
    cryptobot.py          # Клиент Crypto Pay API
    master_node.py        # Клиент мастер-ноды (create/poll/renew/servers)
    ui.py                 # replace/delete bot message
docker-compose.yml        # PostgreSQL
requirements.txt

Переменные окружения

Создайте .env из шаблона:

cp .env.example .env

Обязательные:

  • BOT_TOKEN
  • DATABASE_URL

Опциональные:

  • DEFAULT_LANGUAGE=ru
  • MASTER_NODE_URL=http://127.0.0.1:6767
  • CONFIG_POLL_INTERVAL_SEC=15
  • STARS_ENABLED=true
  • CRYPTOBOT_ENABLED=true
  • CRYPTOBOT_TOKEN=...
  • CRYPTOBOT_ASSET=USDT
  • CRYPTOBOT_API_BASE=https://pay.crypt.bot/api
  • SUPPORT_ADMIN_IDS=12345,67890 (Telegram user id администраторов поддержки, через запятую)

Локальный запуск

  1. Поднять PostgreSQL:
docker compose up -d
  1. Создать окружение и поставить зависимости:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
  1. Запустить бота:
python3 -m app.main

Таблицы БД создаются автоматически при старте (Repository._migrate()).

Быстрый гайд (10 минут)

  1. Подготовить .env:
cp .env.example .env
  1. Запустить PostgreSQL:
docker compose up -d
  1. В отдельном терминале запустить mock мастер-ноду:
python3 -m app.mock_master_node
  1. В отдельном терминале запустить бота:
python3 -m app.main
  1. В Telegram открыть бота и отправить только /start.
  2. Пройти сценарий:
  • Купить VPN -> Готовые тарифы или Создать свой тариф
  • выбрать оплату (для локального теста проще всего СБП)
  • в симуляции нажать Успешная оплата
  • дождаться выдачи конфига от mock мастер-ноды
  • проверить История покупок и Мои конфиги в Личном кабинете.
  • открыть Инфо и помощь и создать тестовый тикет.

Тикет-система поддержки

  • Пользователь: Инфо и помощь -> Создать тикет -> отправляет один текстовый месседж.
  • Бот создает тикет и отправляет уведомление администраторам из SUPPORT_ADMIN_IDS.
  • Администратор: Инфо и помощь -> Открытые тикеты (админ) -> открывает тикет -> Ответить.
  • Пользователь видит ответы в том же треде тикета (Инфо и помощь -> Мои тикеты).
  • Доступно закрытие/переоткрытие тикета администратором.

Mock master-node (для локальных тестов)

Можно поднять простой mock API мастер-ноды на 127.0.0.1:6767:

python3 -m app.mock_master_node

Он реализует:

  • GET /servers
  • POST /configs/create
  • GET /tasks/{task_id}
  • POST /configs/renew

Полезные env для mock:

  • MOCK_MASTER_HOST=127.0.0.1
  • MOCK_MASTER_PORT=6767
  • MOCK_TASK_DELAY_SEC=5
  • MOCK_FAIL_RATE=0

Управление ценами без кода

Бот поддерживает overrides цен через таблицу config_kv (напрямую в БД, без изменения кода).

Ключи, которые используются:

  • pricing.usd_to_rub
  • pricing.usd_to_stars
  • pricing.plan.<plan_code>.usd
  • pricing.custom.base_usd_per_month
  • pricing.custom.extra_device_usd_per_month

Примеры plan_code для готовых тарифов:

  • ready:entry:1
  • ready:standard:3
  • ready:premium:12

Примеры SQL:

-- Курс валюты
INSERT INTO config_kv(key, value) VALUES ('pricing.usd_to_rub', '80')
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;

-- Цена конкретного готового тарифа (STANDARD 1 месяц)
INSERT INTO config_kv(key, value) VALUES ('pricing.plan.ready:standard:1.usd', '4.99')
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;

-- Формула custom тарифа
INSERT INTO config_kv(key, value) VALUES ('pricing.custom.base_usd_per_month', '3.50')
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
INSERT INTO config_kv(key, value) VALUES ('pricing.custom.extra_device_usd_per_month', '1.10')
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;

Гайд по БД (что смотреть при тестах)

-- Заказы пользователя
SELECT id, tg_id, plan, server, protocol, payment_method, amount_usd_numeric, status, created_at
FROM vpn_orders
ORDER BY id DESC;

-- События оплат
SELECT id, order_id, payment_method, event_type, details, created_at
FROM payment_events
ORDER BY id DESC;

-- Конфиги пользователя
SELECT id, tg_id, server_id, protocol, status, task_id, expiration_date, updated_at
FROM connections
ORDER BY id DESC;

-- Пинг и статус серверов (приходит с мастер-ноды)
SELECT server_id, country, status, ping_ms, updated_at
FROM server_data
ORDER BY country, server_id;

Бизнес-флоу

  1. /start -> главное меню.
  2. Купить VPN -> Готовые тарифы или Создать свой тариф.
  3. Готовые тарифы: семейство тарифа -> длительность -> оплата -> summary.
  4. Создать свой тариф: страна -> сервер (node + ping) -> протокол -> длительность -> устройства -> оплата -> summary.
  5. pay:start создает заказ в vpn_orders со статусом pending.
  6. Дальше зависит от платежного метода:
  • sbp: локальная эмуляция результата.
  • stars: invoice в Telegram, подтверждение через successful_payment.
  • cryptobot: ссылка на оплату + ручная проверка статуса кнопкой.
  1. При успехе:
  • статус заказа paid
  • запись в payment_events
  • сброс draft_orders
  • создание connection и запуск задачи создания конфига на мастер-ноде

Схема данных (кратко)

  • users: язык и id последнего сообщения бота.
  • draft_orders: незавершенный выбор пользователя.
  • vpn_orders: финальные заказы и статус оплаты.
  • payment_events: аудит платежных событий.
  • connections: созданные VPN-конфиги и их статус/задача на мастер-ноде.

Что важно для разработчиков

  • Любые команды кроме /start игнорируются.
  • Обычные текстовые сообщения игнорируются, кроме режима ввода тикета поддержки (создание/ответ).
  • Навигация "Назад" не откатывает состояние draft_orders, только экран.
  • Для custom тарифа цена считается формулой-заглушкой в app/services/catalog.py.
  • Выдача конфига берется из ответа мастер-ноды, технические детали отправляются в логи.

Ограничения интерфейса

  • Telegram Bot API не поддерживает произвольную раскраску inline-кнопок во всех клиентах.
  • В Bot API 9.4 добавлены style/icon_custom_emoji_id; отображение зависит от клиента Telegram и может отличаться.

Полезные команды

# Проверка контейнера БД
docker compose ps

# Логи PostgreSQL
docker compose logs -f postgres

# Остановка окружения
docker compose down

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors