Сервис / работает

ShadowNet VPN

Telegram-бот, сайт с личным кабинетом и оплатой, свой бэкенд над панелью серверов и собственные приложения, которые сейчас в разработке.

Платформы
Telegram, веб, Windows, Android
Бот и API
Python / aiogram / FastAPI / PostgreSQL
Сайт
React / Vite / Tailwind
Приложения
Go / Xray-core / Flutter
Сайт ShadowNet: первый экран с тарифами
01

Как устроено

Бот и сайт работают поверх одного бэкенда с общей бизнес-логикой. Серверная панель только исполняет команды: подписки, деньги и трафик хранятся в своей базе, поэтому панель можно сменить, не потеряв ни одного клиента.

02

Бот

С него начинается большинство клиентов. Нажал /start — получил 3 дня бесплатно и ключ с QR-кодом, подключился за минуту. Дальше в боте оплата, продление, подарки и поддержка.

  1. Оплата картой, через СБП и криптовалютой, внутренний кошелёк
  2. Подарочные подписки, промокоды и акции для вернувшихся
  3. Реферальная программа с выводом заработка на карту
  4. Поддержка в группе с темами, синхронно с чатом на сайте
03

Сайт и кабинет

Лендинг и личный кабинет в одном приложении. Вход по почте, через Google или Telegram, и аккаунты склеиваются: оплатил на сайте — подписка видна и в боте.

В кабинете оплата и история заказов, подарки, дерево рефералов, живой чат поддержки, а для себя — админка на два десятка страниц. Страницы с ценами и ответами собираются заранее, чтобы сайт открывался быстро и хорошо индексировался.

Сайт ShadowNet: пробный период оформлен как чек на 0 рублей
Мобильная версия сайта ShadowNet
04

Изнутри

Так выглядит кабинет после входа: срок подписки, сколько трафика осталось, какие серверы сейчас работают и какие устройства подключены.

Отсюда же подключают ещё одно устройство, докупают места или перевыпускают ключ, вводят промокод. Поддержка — кнопкой в углу, живым чатом.

Личный кабинет ShadowNet: активная подписка, трафик, серверы и устройства

Одна почта, два аккаунта

Почта хранилась так, как её ввели, а искалась точным совпадением. Аккаунт Ivan@Mail.ru не находился по ivan@mail.ru: вход и «Забыли пароль» молча не работали.

А из-за пробела в конце адреса у одного человека завелось два аккаунта: на одном подписка, на другом ничего. Теперь у почты один канон — без пробелов и в нижнем регистре, одинаковый в коде и в базе.

services/database/users.py, migrations.py

def norm_email(email: str | None) -> str | None:    """Канонический вид e-mail: без краевых пробелов, в нижнем регистре.    Уникальность в БД держит функциональный индекс idx_users_email_lower, поэтому    и хранить, и искать надо в одном регистре. До этой нормализации точечный поиск    (email = $1) расходился с индексом: аккаунт, сохранённый как Ivan@Mail.ru, не    находился по ivan@mail.ru — вход и сброс пароля молча не работали.    """    return email.strip().lower() if email else email...    await pool.execute(        "CREATE INDEX IF NOT EXISTS idx_users_email_canon "        "ON users (LOWER(BTRIM(email))) WHERE email IS NOT NULL"    )

Фрагменты из репозиториев, сокращены

05

От /start до подключения

bot · backend · panel
06

В цифрах

16
серверов в управлении: ноды, сайт, бэкенд и мониторинг
1 114
коммитов в боте, сайте, приложениях и инструментах с конца января
~140
маршрутов API у бэкенда, на котором живут бот и сайт
280+
файлов с автотестами, тесты гоняются в CI на чистой базе
Все проекты t.me/kroooot

Нужен бот, сервис или сайт? Опишите задачу, отвечу в течение дня.