-
Notifications
You must be signed in to change notification settings - Fork 4
Operator API Quick Start ru
Это для операторов панелей, которые хотят, чтобы их копия ClashFest выглядела как их сервис. Клиент читает HTTP-заголовки ответа с вашего URL подписки и подстраивается.
Если вы разработчик панели и хотите нативно вынести эти заголовки в свою админку — см. Справочник заголовков.
- По вашему URL подписки клиенты ходят
GET <sub-url>. - Ваша панель умеет добавлять кастомные HTTP-заголовки ответа. Любая современная Clash-панель это умеет — см. инструкции по панелям ниже.
- Публичный HTTPS-URL с вашим лого (PNG или WebP, рекомендуется 256×256, ≤200KB). Тема ClashFest по умолчанию тёмная, так что лого «под тёмный фон» достаточно; если хотите отдельное лого для светлой темы — разместите оба.
⚠️ X-Branding-Enabled: trueобязателен. Брендинг — opt-in на каждую подписку. Без этого мастер-переключателя все остальныеX-Brand-*заголовки парсятся, но игнорируются, и приложение остаётся дефолтным. Это причина №1 «мой брендинг не показывается».
Мастер-переключатель плюс три идентити-заголовка дают заметный «брендированный» вид:
X-Branding-Enabled: true
X-Brand-Name: SwiftVPN
X-Brand-Logo-URL: https://cdn.example.com/swiftvpn-logo-dark.png
X-Brand-Accent-Color: #5E35B1
Чтобы откатить брендинг позже — уберите X-Branding-Enabled или поставьте false; клиент вернётся к дефолтному UI на следующем обновлении подписки.
Исключение: заголовки политики оператора, например
X-Brand-Hide-Global-Mode, применяются по одному лишь наличию и не требуютX-Branding-Enabled. См. Справочник заголовков.
После этого заполните инфо оператора, чтобы экран About выглядел как настоящая визитка:
X-Brand-Website-URL: https://swiftvpn.example.com
X-Brand-Support-URL: https://t.me/swiftvpn_support
X-Brand-Telegram-URL: https://t.me/swiftvpn_news
X-Brand-Bot-URL: https://t.me/swiftvpn_bot
X-Brand-Privacy-URL: https://swiftvpn.example.com/privacy
X-Brand-Terms-URL: https://swiftvpn.example.com/terms
X-Brand-Help-URL: https://swiftvpn.example.com/help
Опционально — вариант лого для светлой темы:
X-Brand-Logo-Light-URL: https://cdn.example.com/swiftvpn-logo-light.png
Это всё для v1. v2 добавляет X-Brand-Status-URL, X-Brand-Renew-URL и статичный чип X-Brand-Max-Devices. v3 добавляет X-Brand-Hide-Routing для упрощённого UI юзера.
Точные подписи UI меняются между версиями панелей. Принцип везде один: найти секцию «custom headers» для ответов подписки и вставить значения.
- Админка → Settings → Subscription
- Прокрутите до Custom Headers (или Response Headers)
- Добавьте по одной записи на строку:
X-Branding-Enabled: true X-Brand-Name: SwiftVPN X-Brand-Logo-URL: https://cdn.example.com/swiftvpn-logo-dark.png X-Brand-Accent-Color: #5E35B1 X-Brand-Support-URL: https://t.me/swiftvpn_support - Сохраните.
- Проверьте
curl -I <subscription-url>— заголовкиX-Brand-*должны быть в ответе.
Marzban отдаёт заголовки подписки через host-level template-конфиг (/etc/marzban/.env или конфиг-файл вашей установки).
SUB_PROFILE_TITLE="vasya@example.com"
SUBSCRIPTION_PAGE_TEMPLATE="subscription/page.html"
CUSTOM_TEMPLATES_DIRECTORY="/var/lib/marzban/templates/"Для произвольных X-Brand-* заголовков переопределите роутер подписки, расширив ответ через response.headers["X-Brand-Name"] = "SwiftVPN" в app/subscription/v2ray.py (или в том билдере ответа, что у вашей версии). Для большинства деплоеров проще поставить небольшой reverse-proxy (nginx / Caddy) впереди и добавить заголовки там — см. «Универсальный reverse proxy» ниже.
В Marzneshin v0.5+ есть секция «Subscription branding» в админке под Settings → Branding. Вставьте заголовки прямо туда.
Для старых версий используйте reverse-proxy подход.
Админка → Hosts → выберите хост → Branding. Каждое поле маппится на один заголовок. Сохраните и перепроверьте curl -I.
У 3x-ui есть панель «Subscription Settings». Ищите Response Headers в свежих сборках. Если в вашей версии нет — reverse-proxy подход.
Если панель не отдаёт кастомные заголовки — поставьте nginx (или Caddy) перед роутом подписки, пусть инжектит заголовки:
nginx:
location /sub/ {
proxy_pass http://localhost:8080;
add_header X-Branding-Enabled "true" always;
add_header X-Brand-Name "SwiftVPN" always;
add_header X-Brand-Logo-URL "https://cdn.example.com/swiftvpn-logo-dark.png" always;
add_header X-Brand-Accent-Color "#5E35B1" always;
add_header X-Brand-Website-URL "https://swiftvpn.example.com" always;
add_header X-Brand-Support-URL "https://t.me/swiftvpn_support" always;
add_header X-Brand-Telegram-URL "https://t.me/swiftvpn_news" always;
add_header X-Brand-Privacy-URL "https://swiftvpn.example.com/privacy" always;
add_header X-Brand-Terms-URL "https://swiftvpn.example.com/terms" always;
}Флаг always важен — без него nginx пропускает заголовки на не-2xx ответах.
Caddy:
sub.swiftvpn.example.com {
reverse_proxy localhost:8080
header X-Branding-Enabled "true"
header X-Brand-Name "SwiftVPN"
header X-Brand-Logo-URL "https://cdn.example.com/swiftvpn-logo-dark.png"
header X-Brand-Accent-Color "#5E35B1"
header X-Brand-Website-URL "https://swiftvpn.example.com"
header X-Brand-Support-URL "https://t.me/swiftvpn_support"
header X-Brand-Telegram-URL "https://t.me/swiftvpn_news"
header X-Brand-Privacy-URL "https://swiftvpn.example.com/privacy"
header X-Brand-Terms-URL "https://swiftvpn.example.com/terms"
}После деплоя:
curl -I "https://your-domain.example/sub/<token>"Вы должны увидеть свои X-Brand-* заголовки в ответе. Если нет — панель/прокси их не шлёт, проверьте конфиг.
Если заголовки есть, но приложение не реагирует — значения, скорее всего, не прошли валидацию. Частые проблемы:
- URL лого
http://(нуженhttps://) - Файл лого слишком большой (>512KB) или неверного типа (не PNG / WebP / JPEG)
- Акцент не ровно
#RRGGBB(без#RGB, безrgba()) - В имени бренда control-символы или >32 символов после trim
См. Безопасность для полных правил валидации.
Юзер может нажать Settings → Reset branding, чтобы убрать ваш брендинг и вернуться к дефолтной идентичности. Это не атака — это намеренный «аварийный выход», который приложение обязано предлагать (как «сброс к заводским»). Ваш брендинг вернётся на следующем фетче подписки, пока заголовки шлются.
By design, следующее остаётся дефолтом ClashFest независимо от брендинга:
- Иконка лаунчера Android (юзер поставил «ClashFest» из стора — она и остаётся на домашнем экране)
- Имя пакета Android и листинг в сторе
- Строка «powered by ClashFest» на экране About
- Settings → About → «App version» / идентификатор сборки
Если нужна полностью white-label презентация в сторе (своя иконка, свой листинг) — это другой скоуп: обсудите с нами полноценный форк / rebrand-сборку.
📱 User Guide
- Getting Started
- Profiles & Nodes
- Routing & Rules
- Settings
- Deep Links
- Encrypted Subscriptions
- Troubleshooting
🏢 Operator API
📺 Companion