Бот продажи VPN-подписок: оплата картой / криптой / Telegram Stars / с внутреннего баланса, автопродление, триалы, рефералка, админка прямо в Telegram. Ставится на чистый VPS одной командой. Полностью открытый и бесплатный (AGPL-3.0).
- Подписки через панель Remnawave: выдача, продление, отключение, периодический синк
- Несколько внутренних сквадов новым юзерам (UUID через запятую) и опциональный внешний сквад; сквады, выставленные руками в панели, бот при продлениях не трогает
- Оплата: внутренний баланс, карта (Tribute), крипта (Crypto Pay / @CryptoBot), Telegram Stars
- Автопродление с баланса, страховочный grace-период, напоминания об истечении
- Посуточный «дневной режим» списания с баланса
- Триалы, инвайты, реферальные бонусы
- Режим доступа: открытый для всех или закрытый (вход только по инвайт-ссылкам)
- Админка: Mini App в Telegram + команды — статистика, рассылки, опросы, поиск пользователей, продление, редактор разделов меню
- Rescue-страница восстановления доступа (по Telegram ID, под Cloudflare Turnstile)
- Цены и бонусы правятся из админки на лету, без перезапуска
Обязательны только первые две строки — всё остальное опционально: пропускаешь
вопрос Enter'ом при установке, функция аккуратно выключается, добавить можно
в любой момент через sudo ./install.sh → «Настройки».
| Что | Где взять |
|---|---|
| VPS: Ubuntu 22.04+ / Debian 11+, от 1 ГБ RAM | любой хостинг |
| Токен бота | @BotFather → /newbot |
| Панель Remnawave + её API-ключи (без неё бот не выдаёт VPN) | твоя панель |
| Домен с A-записью на IP VPS (без него — нет Mini App, rescue и платёжных вебхуков) | любой регистратор |
| Tribute: ключ вебхука + ссылки (оплата картой) | кабинет Tribute |
| Токен Crypto Pay (оплата криптой) | @CryptoBot → Crypto Pay → Create App |
| Ключи Turnstile (капча rescue-страницы) | dash.cloudflare.com → Turnstile |
Telegram Stars работают из коробки — без ключей и без домена. Платные здесь только VPS и домен. HTTPS-сертификат Let's Encrypt бот получает и продлевает сам.
git clone https://github.com/SnowDrit/snegir.git
cd snegir
sudo ./install.shПервым делом установщик спросит язык — Русский или English; выбор запоминается и действует и в меню обслуживания. Дальше он проверит сервер, поставит Docker (спросив разрешения) и задаст вопросы, к каждому — подсказка, где взять значение. Обязателен только токен бота — любой другой вопрос пропускается Enter'ом. Спросит он и режим доступа (открытый бот или закрытый, по инвайтам), и ключи Turnstile для rescue-страницы. X-Api-Key панели — это ключ для прохождения её защиты/2FA: если такую защиту в Remnawave не включал, просто жми Enter. Токены проверяются онлайн, пароль БД и секретные пути вебхуков генерируются сами, стек (бот + Postgres + Caddy; без домена — без Caddy) запускается автоматически.
Если подключил Tribute / Crypto Pay — в конце установщик напечатает URL вебхуков. Эти URL нужно вставить в кабинет Tribute и в @CryptoBot — единственный ручной шаг после установки.
Настройки потом: sudo ./install.sh → «Настройки» — показывает текущие
значения (секреты — маской), правит с валидацией и сам перезапускает бота.
Руками тоже можно: файл .env, после правки — docker compose up -d.
Повторный sudo ./install.sh на установленном боте открывает меню:
1) Обновить бота до свежей версии git pull + пересборка
2) Пересобрать и перезапустить починка после сбоя
3) Откатиться на предыдущую версию по git-тегам
4) Статус и логи
5) Сделать бэкап БД сейчас
6) Ежедневный автобэкап в 04:00 вкл/выкл
7) Настройки токены, домен, панель, режим доступа
Бэкап (./backup.sh) кладёт дамп БД в ./backups/, хранится 7 свежих копий.
Команды восстановления — в шапке backup.sh. Перед пунктами 1 и 3 (обновление
и откат) установщик сам делает бэкап БД — если не выйдет, спросит, продолжать ли.
Два честных предупреждения:
./backups/лежит на том же сервере — от смерти диска не спасёт. Выгрузку копий наружу (scp/rclone) настрой сам.- Один раз после установки сохрани копию
.envв надёжном месте: там все секреты.
Браузер ругается на сертификат сразу после установки. Caddy получает сертификат Let's Encrypt 1–2 минуты. Подожди и обнови страницу.
Платёж прошёл, а бот молчит.
Почти всегда — URL вебхуков не вставлены в кабинет Tribute / @CryptoBot.
Возьми их из .env (TRIBUTE_WEBHOOK_PATH, CRYPTO_WEBHOOK_PATH):
https://ТВОЙ_ДОМЕН + путь. Логи: docker compose logs -f bot.
«Порты 80/443 заняты».
На VPS уже живёт nginx/apache. Нужен чистый сервер — либо удали их
(apt remove nginx apache2), либо возьми другой VPS.
Кнопки «Картой» / «Криптой» нет.
Не заданы соответствующие ключи или ссылки (TRIBUTE_API_KEY,
TRIBUTE_APP_URL / DONATE_URL, CRYPTO_API_KEY) — способ оплаты скрыт,
пока не настроен: sudo ./install.sh → «Настройки».
Что за X-Api-Key у панели? Ключ для прохождения защиты/2FA API Remnawave. Если такая защита в панели не включена — оставь поле пустым, бот не будет отправлять этот заголовок.
Где поменять цену месяца. В админке бота → «Оплата и бонусы». Цена живёт в БД, конфиг трогать не надо.
Дальше внутренности; для установки и использования это читать не нужно.
Однопроцессный asyncio (python -m app): aiogram 3 (long polling), asyncpg,
aiohttp. Внутри процесса:
- три локальных HTTP-сервера: вебхук Tribute (
:8000), вебхук Crypto Pay (:9000), Mini App + rescue (:8100); - 8 фоновых воркеров: чистка БД, напоминания об истечении, синк с панелью, grace-продление, ретраи зависших платежей, посуточное списание, автопродление с баланса, закрытие опросов.
Снаружи всё прикрывает Caddy: HTTPS, секретные пути вебхуков (генерируются
установщиком), /admin*, /rescue*, остальное — 404.
Telegram ──polling──▶ bot ◀──SQL──▶ Postgres
Tribute ───▶ Caddy:443 ──▶ bot:8000 bot ──REST──▶ панель Remnawave
CryptoBot ─▶ Caddy:443 ──▶ bot:9000
Браузер ───▶ Caddy:443 ──▶ bot:8100 (Mini App, rescue)
app/
config.py # .env и константы
db.py # asyncpg-пул, схема (создаётся сама), запросы
loader.py # bot, dp, router
middlewares.py # username-синк, троттлинг
panel_client.py # клиент API Remnawave
sections.py # кастомные разделы меню
services/ # balance, cryptopay, notify, payments, provisioning
handlers/user/ # base, balance, pay, social
handlers/admin/ # menu, stats, broadcast, polls, …
web/webhooks.py # Tribute + CryptoBot (идемпотентность платежей)
web/miniapp.py # админ Mini App + rescue + catch-all разделов
workers.py # 8 фоновых циклов
main.py # сборка и запуск
static/ # admin.html, rescue.html (Mini App)
tests/ # test_pure.py (без зависимостей), test_smoke.py (venv)
Порядок регистрации хендлеров жёсткий: мидлвари → все хендлеры → catch-all
кастомных разделов строго последним. test_smoke.py это проверяет.
9 таблиц, бот создаёт их сам при старте (init_asyncpg): users, sections,
invites, polls, votes, payments, sent_reminders, bot_settings,
balance_ops.
Железное правило: миграции только аддитивные. Новые таблицы —
CREATE TABLE IF NOT EXISTS, новые колонки — ADD COLUMN IF NOT EXISTS,
выполняются самим ботом при старте. Переименования, удаления и смена типов
запрещены (только «добавь новое поле, читай оба»). Поэтому обновление работает
с любой версии сразу на последнюю, а откат на старый тег не требует миграций
вниз. PR, нарушающий правило, не принимается.
python3 tests/test_pure.py # чистая логика, голый python
venv/bin/python tests/test_smoke.py # импорт пакета, ~126 хендлеров, порядок catch-allКлассический venv + systemd — см. DEPLOY.md (роль и базу Postgres при этом
создаёшь руками, там же SQL).
main — только стабильное; каждое значимое обновление получает тег vX.Y.
Пользователи обновляются через меню install.sh, откатываются по тегам.
Автообновлений нет и не будет: чужой продакшен обновляет только его владелец.
Snegir — ПО для самостоятельного хостинга: инструмент управления подписками панели Remnawave. Распространяется «как есть», без каких-либо гарантий (см. LICENSE). Разворачивая бота, ты сам отвечаешь за соответствие своего сервиса законодательству юрисдикции, в которой он работает: правилам оказания VPN-услуг, приёма платежей (включая криптовалюту) и обработки персональных данных пользователей.
AGPL-3.0: свободно используй, изучай и форкай. Если запускаешь изменённую версию как сервис для других — обязан открыть свои изменения. Продажа закрытых копий запрещена.