Expose a lightweight /healthz route on the main aiohttp server and wire docker-compose healthcheck so orchestrators can detect failures.
Telegram-бот для продажи подписок Remnawave
Этот Telegram-бот предназначен для автоматизации продажи и управления подписками для панели Remnawave. Он интегрируется с API Remnawave для управления пользователями и подписками, а также использует различные платежные системы для приема платежей.
✨ Ключевые возможности
Для пользователей:
- Регистрация и выбор языка: Поддержка русского и английского языков.
- Просмотр подписки: Пользователи могут видеть статус своей подписки, дату окончания и ссылку на конфигурацию.
- Web App (Mini App): отдельный веб-интерфейс для просмотра ссылки подключения, остатка времени и оплаты подписки.
- Вход по email: вход и регистрация в Web App по коду из письма, а также привязка email и Telegram к одному аккаунту.
- Мои устройства: Опциональный раздел для просмотра и отключения подключенных устройств (активируется через переменную
MY_DEVICES_SECTION_ENABLED). - Пробная подписка: Система пробных подписок для новых пользователей (активируется вручную по кнопке).
- Промокоды: Возможность применять промокоды для получения скидок или бонусных дней.
- Реферальная программа: Пользователи могут приглашать друзей и получать за это бонусные дни подписки.
- Оплата: Поддержка оплаты через YooKassa, FreeKassa (REST API), Platega, SeverPay, CryptoPay и Telegram Stars.
Для администраторов:
- Защищенная админ-панель: Доступ только для администраторов, указанных в
ADMIN_IDS. - Статистика: Просмотр статистики использования бота (общее количество пользователей, забаненные, активные подписки), недавние платежи и статус синхронизации с панелью.
- Управление пользователями: Блокировка/разблокировка пользователей, просмотр списка забаненных и детальной информации о пользователе.
- Рассылка: Отправка сообщений всем пользователям, пользователям с активной или истекшей подпиской.
- Управление промокодами: Создание и просмотр промокодов.
- Синхронизация с панелью: Ручной запуск синхронизации пользователей и подписок с панелью Remnawave.
- Логи действий: Просмотр логов всех действий пользователей.
🚀 Технологии
- Python 3.12
- Aiogram 3.x: Асинхронный фреймворк для Telegram ботов.
- aiohttp: Для запуска веб-сервера (вебхуки).
- SQLAlchemy 2.x & asyncpg: Асинхронная работа с базой данных PostgreSQL.
- YooKassa, FreeKassa API, Platega, SeverPay, aiocryptopay: Интеграции с платежными системами.
- Pydantic: Для управления настройками из
.envфайла. - Docker & Docker Compose: Для контейнеризации и развертывания.
⚙️ Установка и запуск
Предварительные требования
- Установленные Docker и Docker Compose.
- Рабочая панель Remnawave.
- Токен Telegram-бота.
- Данные для подключения к платежным системам (YooKassa, CryptoPay и т.д.).
Шаги установки
-
Клонируйте репозиторий:
git clone https://github.com/3252a8/remnawave-tg-shop cd remnawave-tg-shop -
Создайте и настройте файл
.env: Скопируйтеenv.exampleв.envи заполните своими данными.cp .env.example .env nano .envНиже перечислены ключевые переменные.
Основные настройки
Переменная Описание Пример BOT_TOKENОбязательно. Токен вашего Telegram-бота. 1234567890:ABC-DEF1234ghIkl-zyx57W2v1u123ew11ADMIN_IDSОбязательно. ID администраторов в Telegram через запятую. 12345678,98765432DEFAULT_LANGUAGEЯзык по умолчанию для новых пользователей. ruSUPPORT_LINK(Опционально) Ссылка на поддержку. https://t.me/your_supportPRIVACY_POLICY_URL(Опционально) Ссылка на политику конфиденциальности, показывается внизу Web App. https://example.com/privacyUSER_AGREEMENT_URL(Опционально) Ссылка на пользовательское соглашение, показывается внизу Web App. https://example.com/agreementSUBSCRIPTION_MINI_APP_URL(Опционально) Публичный URL Mini App для показа подписки. Если задан, кнопка «Моя подписка» откроет Web App. https://app.domain.com/WEBAPP_ENABLEDВключить Web App в том же контейнере, но на отдельном порту. trueWEBAPP_SERVER_PORTВнутренний порт Web App. 8081WEBAPP_TITLEЗаголовок Web App. Моя подпискаWEBAPP_PRIMARY_COLORОсновной цвет Web App. #00fe7aWEBAPP_LOGO_URL(Опционально) URL логотипа Web App. Если значение пустое, логотип не показывается вообще; если задано, он отображается в шапке и на экране логина. https://domain.com/logo.pngSMTP_HOSTSMTP-сервер для кодов входа по email. Для Brevo: smtp-relay.brevo.com.smtp-relay.brevo.comSMTP_PORTSMTP-порт. Для Brevo обычно используется 587 с STARTTLS. 587SMTP_FALLBACK_PORTSДополнительные SMTP-порты через запятую. Пробуются после SMTP_PORT; порт465автоматически используется через SSL. Для Brevo удобно оставить2525,465.2525,465SMTP_TIMEOUT_SECONDSTimeout для каждой SMTP-попытки подключения и отправки. 30SMTP_USERNAME/SMTP_PASSWORDЛогин и SMTP key/password из Brevo. Если не заданы вместе с SMTP_FROM_EMAIL, вход по email скрывается.user@smtp-brevo.comSMTP_FROM_EMAIL/SMTP_FROM_NAMEПодтвержденный отправитель и отображаемое имя отправителя для писем с кодом. no-reply@example.comEMAIL_CODE_TTL_SECONDSСрок действия кода подтверждения email. 600EMAIL_CODE_RESEND_SECONDSМинимальная пауза между отправками кода на один email. 60EMAIL_CODE_MAX_ATTEMPTSМаксимум попыток на один конкретный код. 5BRUTE_FORCE_MAX_FAILURESМаксимум неудачных попыток в окне защиты от перебора. 5BRUTE_FORCE_WINDOW_SECONDSДлительность окна, в котором считаются неудачные попытки. 900BRUTE_FORCE_LOCK_SECONDSВремя временной блокировки после превышения лимита. 1800MY_DEVICES_SECTION_ENABLEDВключить раздел «Мои устройства» в меню подписки ( true/false).falseREQUIRED_CHANNEL_ID(Опционально) ID канала, на который пользователь должен подписаться перед использованием. Оставьте пустым, если проверка не нужна. -1001234567890REQUIRED_CHANNEL_LINK(Опционально) Публичная ссылка или invite на канал для кнопки «Проверить подписку». https://t.me/your_channelНастройки платежей и вебхуков
Переменная Описание WEBHOOK_BASE_URLОбязательно. Базовый URL для вебхуков, например https://your.domain.com.WEB_SERVER_HOSTХост для веб-сервера. WEB_SERVER_PORTПорт для веб-сервера. WEBAPP_SERVER_HOSTХост отдельного веб-сервера Mini App. WEBAPP_SERVER_PORTПорт отдельного веб-сервера Mini App. PAYMENT_METHODS_ORDER(Опционально) Порядок отображения кнопок оплаты через запятую. Поддерживаемые ключи: severpay,freekassa,platega,yookassa,stars,cryptopay. Первый будет сверху.YOOKASSA_ENABLEDВключить/выключить YooKassa ( true/false).YOOKASSA_SHOP_IDID вашего магазина в YooKassa. YOOKASSA_SECRET_KEYСекретный ключ магазина YooKassa. YOOKASSA_AUTOPAYMENTS_ENABLEDВключить автопродление (сохранение карт, автосписания, управление способами оплаты). YOOKASSA_AUTOPAYMENTS_REQUIRE_CARD_BINDINGТребовать обязательную привязку карты при оплате с автосписанием. Установите false, чтобы пользователю показывался чекбокс «Сохранить карту».NALOGO_INNИНН для авторизации в nalog.ru (самозанятый). NALOGO_PASSWORDПароль для авторизации в nalog.ru (самозанятый). CRYPTOPAY_ENABLEDВключить/выключить CryptoPay ( true/false).CRYPTOPAY_TOKENТокен из вашего CryptoPay App. FREEKASSA_ENABLEDВключить/выключить FreeKassa ( true/false).FREEKASSA_MERCHANT_IDID вашего магазина в FreeKassa. FREEKASSA_API_KEYAPI-ключ для запросов к FreeKassa REST API. FREEKASSA_SECOND_SECRETСекретное слово №2 — используется для проверки уведомлений от FreeKassa. FREEKASSA_PAYMENT_URL(Опционально, legacy SCI) Базовый URL платёжной формы FreeKassa. По умолчанию https://pay.freekassa.ru/.FREEKASSA_PAYMENT_IPВнешний IP вашего сервера, который будет передаваться в запрос оплаты. FREEKASSA_PAYMENT_METHOD_IDID метода оплаты через магазин FreeKassa. По умолчанию 44.STARS_ENABLEDВключить/выключить Telegram Stars ( true/false).PLATEGA_ENABLEDВключить/выключить Platega ( true/false).PLATEGA_MERCHANT_IDMerchantId из личного кабинета Platega. PLATEGA_SECRETAPI секрет для запросов Platega. PLATEGA_PAYMENT_METHODID способа оплаты (2 — SBP QR, 10 — РФ карты, 12 — международные карты, 13 — crypto). PLATEGA_RETURN_URL(Опционально) URL редиректа после успешной оплаты. По умолчанию ссылка на бота. PLATEGA_FAILED_URL(Опционально) URL редиректа при ошибке/отмене. По умолчанию как PLATEGA_RETURN_URL.SEVERPAY_ENABLEDВключить/выключить SeverPay ( true/false).SEVERPAY_MIDMID магазина в SeverPay. SEVERPAY_TOKENСекрет/токен для подписи запросов SeverPay. SEVERPAY_BASE_URL(Опционально) Базовый URL API SeverPay. По умолчанию https://severpay.io/api/merchant.SEVERPAY_RETURN_URL(Опционально) URL редиректа после оплаты (по умолчанию ссылка на бота). SEVERPAY_LIFETIME_MINUTES(Опционально) Время жизни платежной ссылки в минутах (30–4320). Настройки подписок
Для каждого периода (1, 3, 6, 12 месяцев) можно настроить доступность и цены:
1_MONTH_ENABLED:trueилиfalseRUB_PRICE_1_MONTH: Цена в рубляхSTARS_PRICE_1_MONTH: Цена в Telegram Stars Аналогичные переменные есть для3_MONTHS,6_MONTHS,12_MONTHS.
Настройки панели Remnawave
Переменная Описание PANEL_API_URLURL API вашей панели Remnawave. PANEL_API_KEYAPI ключ для доступа к панели. PANEL_WEBHOOK_SECRETСекретный ключ для проверки вебхуков от панели. USER_SQUAD_UUIDSID отрядов для новых пользователей. USER_EXTERNAL_SQUAD_UUIDОпционально. UUID внешнего отряда (External Squad) из документации Remnawave, куда автоматически добавляются новые пользователи. USER_TRAFFIC_LIMIT_GBЛимит трафика в ГБ (0 - безлимит). USER_HWID_DEVICE_LIMITЛимит устройств (HWID) для новых пользователей (0 - безлимит). Раздел "Мои устройства" становится доступен пользователям только при включении
MY_DEVICES_SECTION_ENABLED. Значение лимита устройств при создании записей в панели берётся изUSER_HWID_DEVICE_LIMIT.Настройки пробного периода
Переменная Описание TRIAL_ENABLEDВключить/выключить пробный период ( true/false).TRIAL_DURATION_DAYSДлительность пробного периода в днях. TRIAL_TRAFFIC_LIMIT_GBЛимит трафика для пробного периода в ГБ. -
Запустите контейнеры:
docker compose up -dЭта команда скачает образ и запустит сервис в фоновом режиме.
-
Настройка вебхуков (Обязательно): Вебхуки являются обязательным компонентом для работы бота, так как они используются для получения уведомлений от платежных систем (YooKassa, FreeKassa, CryptoPay, Platega, SeverPay) и панели Remnawave.
Вам понадобится обратный прокси (например, Nginx) для обработки HTTPS-трафика и перенаправления запросов на контейнер с ботом.
Пути для перенаправления:
https://<ваш_домен>/webhook/yookassa→http://remnawave-tg-shop:<WEB_SERVER_PORT>/webhook/yookassahttps://<ваш_домен>/webhook/freekassa→http://remnawave-tg-shop:<WEB_SERVER_PORT>/webhook/freekassahttps://<ваш_домен>/webhook/platega→http://remnawave-tg-shop:<WEB_SERVER_PORT>/webhook/plategahttps://<ваш_домен>/webhook/severpay→http://remnawave-tg-shop:<WEB_SERVER_PORT>/webhook/severpayhttps://<ваш_домен>/webhook/cryptopay→http://remnawave-tg-shop:<WEB_SERVER_PORT>/webhook/cryptopayhttps://<ваш_домен>/webhook/panel→http://remnawave-tg-shop:<WEB_SERVER_PORT>/webhook/panel- Для Telegram: Бот автоматически установит вебхук, если в
.envуказанWEBHOOK_BASE_URL. Путь будетhttps://<ваш_домен>/<BOT_TOKEN>.
Где
remnawave-tg-shop— это имя сервиса изdocker-compose.yml, а<WEB_SERVER_PORT>— порт, указанный в.env.Отдельный порт Web App:
https://<домен_web_app>/→http://remnawave-tg-shop:<WEBAPP_SERVER_PORT>/
Web App не должен проксироваться на
WEB_SERVER_PORT: этот порт оставьте для Telegram, платежных и Remnawave webhooks. -
Просмотр логов:
docker compose logs -f remnawave-tg-shop💡 Если включена проверка подписки на канал (
REQUIRED_CHANNEL_ID), добавьте бота администратором в этот канал. Пользователь увидит кнопку «Проверить подписку», и, после первого успешного подтверждения, дальнейшие действия блокироваться не будут.
Настройка Web App / Mini App
Web App запускается в том же контейнере, что и бот, но слушает отдельный порт WEBAPP_SERVER_PORT (по умолчанию 8081). Внутри Web App пользователь авторизуется через Telegram Mini Apps initData; если страницу открыть вне Telegram, показывается официальный Telegram Login Widget. Также доступен вход по email через одноразовый код из письма, если настроен SMTP: после отправки письма код вводится в отдельном модальном окне подтверждения. После успешного входа страница обновляет данные сразу, без сообщений боту.
-
Укажите в
.envпубличный URL Web App и порт:WEBAPP_ENABLED=True WEBAPP_SERVER_HOST=0.0.0.0 WEBAPP_SERVER_PORT=8081 SUBSCRIPTION_MINI_APP_URL=https://app.domain.com/ WEBAPP_TITLE="Моя подписка" WEBAPP_PRIMARY_COLOR="#00fe7a" WEBAPP_LOGO_URL= SMTP_HOST=smtp-relay.brevo.com SMTP_PORT=587 SMTP_FALLBACK_PORTS=2525,465 SMTP_USERNAME=<brevo-smtp-login> SMTP_PASSWORD=<brevo-smtp-key> SMTP_FROM_EMAIL=no-reply@domain.comЕсли основной порт не отвечает, отправка письма автоматически пробует fallback-порты из
SMTP_FALLBACK_PORTS. Для Brevo типичная схема:587с STARTTLS, затем2525, затем465через SSL. -
Убедитесь, что
docker-compose.ymlпубликует порт Web App:ports: - 127.0.0.1:8080:8080 - 127.0.0.1:${WEBAPP_SERVER_PORT:-8081}:${WEBAPP_SERVER_PORT:-8081} -
Проксируйте отдельный домен или location на порт Web App:
upstream remnawave-tg-shop-webapp { server remnawave-tg-shop:8081; } server { server_name app.domain.com; listen 443 ssl; http2 on; ssl_certificate "/etc/nginx/ssl/app_fullchain.pem"; ssl_certificate_key "/etc/nginx/ssl/app_privkey.key"; location / { proxy_pass http://remnawave-tg-shop-webapp; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } -
В BotFather настройте домен Mini App для бота (
/setdomain) и укажите домен изSUBSCRIPTION_MINI_APP_URL. Этот же домен используется и Telegram Login Widget. -
Перезапустите контейнер:
docker compose up -d --build
После этого кнопка «Моя подписка» в меню бота откроет Web App. Web App показывает текущую ссылку подключения, остаток времени, трафик, оплату и блок аккаунта. Пользователь может привязать email к Telegram-аккаунту через код из письма или привязать Telegram к email-аккаунту через Login Widget. После привязки вход работает обоими способами.
Для email-регистраций пользователь в панели Remnawave создается с анонимным username вида em_<referral_code>; email добавляется в описание пользователя панели и, если API панели принимает поле email, передается отдельным полем. Для Telegram-регистраций сохраняется существующая схема tg_<telegram_id>.
Шапка и модальные окна Web App учитывают Telegram safe area через --tg-content-safe-area-inset-top и --tg-safe-area-inset-top, а сверху добавлен повышенный дополнительный буфер, чтобы интерфейс не уезжал под панель Telegram при открытии из списка чатов.
Для настройки внешнего вида без запуска бота можно открыть файл bot/app/web/templates/subscription_webapp.html напрямую в браузере. Рядом с ним лежат telegram-web-app.js, telegram-widget.js, subscription_webapp.css и subscription_webapp.js, поэтому локальный предпросмотр работает без сервера и без внешнего CDN. При отдаче страницы через Web App сервер dev-mock автоматически вырезается и не попадает пользователям.
Локальная копия Telegram Web App SDK хранится в bot/app/web/templates/telegram-web-app.js, а локальная копия Telegram Login Widget - в bot/app/web/templates/telegram-widget.js. В контейнере обе копии автоматически обновляются при старте Web App и затем раз в 24 часа; если источник временно недоступен, используется уже сохраненная версия. У локального telegram-widget.js есть минимальная нормализация, чтобы при загрузке с вашего домена виджет все равно открывал iframe на Telegram-origin, а не на /embed/... вашего сайта. Для ручного обновления можно запустить команды:
python scripts/update_telegram_web_app_js.py
python scripts/update_telegram_widget_js.py
При необходимости оба скрипта принимают --source-url и --target, если нужно скачать файл в другое место или проверить альтернативный источник.
Подробная инструкция для развертывания на сервере с панелью Remnawave
1. Клонирование репозитория
git clone https://github.com/3252a8/remnawave-tg-shop && cd remnawave-tg-shop
2. Настройка переменных окружения
cp .env.example .env && nano .env
Обязательные поля для заполнения:
BOT_TOKEN- токен телеграмм бота, например,234567890:ABC-DEF1234ghIkl-zyx57W2v1u123ew11ADMIN_IDS- TG ID администраторов, например,12345678,98765432и т.д. (через запятую без пробелов)WEBHOOK_BASE_URL- Обязательно. Базовый URL для вебхуков, напримерhttps://webhook.domain.comPANEL_API_URL- URL API вашей панели Remnawave (например,http://remnawave:3000/apiилиhttps://panel.domain.com/api)PANEL_API_KEY- API ключ для доступа к панели (генерируется из UI-интерфейса панели)PANEL_WEBHOOK_SECRET- Секретный ключ для проверки вебхуков от панели (берётся из.envсамой панели)USER_SQUAD_UUIDS- ID отрядов для новых пользователей
3. Настройка Reverse Proxy (Nginx)
Перейдите в директорию конфигурации Nginx панели Remnawave:
cd /opt/remnawave/nginx && nano nginx.conf
Добавьте в nginx.conf следующую конфигурацию:
upstream remnawave-tg-shop {
server remnawave-tg-shop:8080;
}
map $http_upgrade $connection_upgrade {
default upgrade;
"" close;
}
server {
server_name webhook.domain.com; # Домен для отправки Webhook'ов
listen 443 ssl;
http2 on;
ssl_certificate "/etc/nginx/ssl/webhook_fullchain.pem";
ssl_certificate_key "/etc/nginx/ssl/webhook_privkey.key";
ssl_trusted_certificate "/etc/nginx/ssl/webhook_fullchain.pem";
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_intercept_errors on;
error_page 400 404 500 502 @redirect;
location / {
proxy_pass http://remnawave-tg-shop$request_uri;
}
location @redirect {
return 404;
}
}
4. Выпуск SSL-сертификата для домена webhook
Убедитесь, что установлены необходимые компоненты, а также откройте 80 порт:
sudo apt-get install cron socat
curl https://get.acme.sh | sh -s email=EMAIL && source ~/.bashrc
ufw allow 80/tcp && ufw reload
Выпустите сертификат:
acme.sh --set-default-ca --server letsencrypt
acme.sh --issue --standalone -d 'webhook.domain.com' \
--key-file /opt/remnawave/nginx/webhook_privkey.key \
--fullchain-file /opt/remnawave/nginx/webhook_fullchain.pem
5. Добавление сертификатов в Docker Compose Nginx
Отредактируйте docker-compose.yml панели Nginx:
cd /opt/remnawave/nginx && nano docker-compose.yml
Добавьте две строки в секцию volumes:
services:
remnawave-nginx:
image: nginx:1.26
container_name: remnawave-nginx
hostname: remnawave-nginx
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./fullchain.pem:/etc/nginx/ssl/fullchain.pem:ro
- ./privkey.key:/etc/nginx/ssl/privkey.key:ro
- ./subdomain_fullchain.pem:/etc/nginx/ssl/subdomain_fullchain.pem:ro
- ./subdomain_privkey.key:/etc/nginx/ssl/subdomain_privkey.key:ro
- ./webhook_fullchain.pem:/etc/nginx/ssl/webhook_fullchain.pem:ro # Добавьте эту строку
- ./webhook_privkey.key:/etc/nginx/ssl/webhook_privkey.key:ro # Добавьте эту строку
restart: always
ports:
- '0.0.0.0:443:443'
networks:
- remnawave-network
networks:
remnawave-network:
name: remnawave-network
driver: bridge
external: true
6. Запуск бота и перезапуск Nginx
Запустите бота:
cd /root/remnawave-tg-shop && docker compose up -d && docker compose logs -f -t
Перезапустите Nginx:
cd /opt/remnawave/nginx && docker compose down && docker compose up -d && docker compose logs -f -t
🐳 Docker
Файлы Dockerfile и docker-compose.yml уже настроены для локальной сборки и запуска проекта.
Если нужен запуск из готового образа, используйте docker-compose-remote-server.yml как шаблон и укажите свой image: вместо локальной сборки.
Этот репозиторий больше не публикует образы автоматически через GitHub Actions. В GHCR сохранён только тег 3.0.0; latest и 0.1.0 больше не используются.
Чтобы использовать сохранённый образ, можно запустить:
IMAGE_TAG=3.0.0 docker compose -f docker-compose-remote-server.yml up -d
Вариант с Caddy
Если нужен reverse proxy на Caddy, используйте docker-compose-caddy.yml вместе с Caddyfile. Это удобный вариант, когда хочется, чтобы Caddy сам выпускал TLS-сертификаты и проксировал и webhook'и, и Mini App без ручной настройки Nginx.
В этой схеме:
- Caddy публикует наружу
80и443. - Бот остается доступным только внутри docker-сети.
WEBHOOK_BASE_URLдолжен указывать на домен вебхуков, аSUBSCRIPTION_MINI_APP_URL- на домен Mini App.
Пример Caddyfile:
webhook.domain.com {
encode zstd gzip
reverse_proxy remnawave-tg-shop:{$WEB_SERVER_PORT:8080}
}
app.domain.com {
encode zstd gzip
reverse_proxy remnawave-tg-shop:{$WEBAPP_SERVER_PORT:8081}
}
Что нужно поменять под себя:
- заменить
webhook.domain.comиapp.domain.comна свои домены; - убедиться, что в
.envзаданыWEBHOOK_BASE_URL=https://webhook.domain.comиSUBSCRIPTION_MINI_APP_URL=https://app.domain.com/; - при необходимости скорректировать
WEB_SERVER_PORTиWEBAPP_SERVER_PORT, если они отличаются от стандартных8080и8081. - в BotFather укажите домен Mini App через
/setdomain, чтобы он совпадал сSUBSCRIPTION_MINI_APP_URL.
Запуск:
docker compose -f docker-compose-caddy.yml up -d --build
После этого Caddy сам выпустит сертификаты и будет проксировать webhook'и на порт 8080, а Mini App - на 8081.
📁 Структура проекта
.
├── bot/
│ ├── filters/ # Пользовательские фильтры Aiogram
│ ├── handlers/ # Обработчики сообщений и колбэков
│ ├── keyboards/ # Клавиатуры
│ ├── middlewares/ # Промежуточные слои (i18n, проверка бана)
│ ├── services/ # Бизнес-логика (платежи, API панели)
│ ├── states/ # Состояния FSM
│ └── main_bot.py # Основная логика бота
├── config/
│ └── settings.py # Настройки Pydantic
├── db/
│ ├── dal/ # Слой доступа к данным (DAL)
│ ├── database_setup.py # Настройка БД
│ └── models.py # Модели SQLAlchemy
├── locales/ # Файлы локализации (ru, en)
├── .env.example # Пример файла с переменными окружения
├── Dockerfile # Инструкции для сборки Docker-образа
├── docker-compose.yml # Файл для оркестрации контейнеров
├── requirements.txt # Зависимости Python
└── main.py # Точка входа в приложение
🔮 Планы на будущее
- Расширенные типы промокодов (например, скидки в процентах).
❤️ Поддержка
- Карты РФ и зарубежные: Tribute
- Crypto:
USDT TRC-20 TT3SqBbfU4vYm6SUwUVNZsy278m2xbM4GE