Профиль BEAM
Как отдать клиентам профиль с серверами, брендингом и маршрутизацией.
Профиль BEAM — это JSON: серверы, группы, брендинг, лимиты и пресет ProTun. Отдать его можно тремя способами:
Подписка
Обычная подписка работает как есть. Брендинг — заголовками или тело в формате BEAM.
Ссылка beam://
Весь профиль в одной ссылке — для кнопки на сайте, бота или чата.
Файл .beam
Тот же профиль файлом. Клиент перетаскивает его в BEAM.
Минимальный профиль
{
"name": "MyVPN",
"url": "https://sub.myvpn.example/abc123",
"branding": { "iconUrl": "https://myvpn.example/logo.png", "supportUrl": "https://t.me/myvpn_support" },
"links": [
"[Основные]",
"vless://...#Германия",
"vless://...#Нидерланды",
"[Игровые]",
"trojan://...#Gaming FI"
]
}Поля
| Поле | Что это |
|---|---|
name | имя профиля; если нет — берётся provider |
provider | имя провайдера |
links | серверы как share-ссылки и маркеры групп, до 1000 строк |
nodes | серверы как готовые outbound’ы Xray |
url | адрес подписки — профиль будет обновляться с него |
updateIntervalHours | интервал обновления, часы |
branding | логотип, баннер, ссылки — см. Брендинг |
expiresAt | конец подписки, unix-время в секундах |
dataLimit, dataUsed | лимит и расход трафика, байты |
proTunPreset | схема ProTun |
proTunLocked | запретить менять пресет |
Нужны links или nodes: профиль без серверов BEAM не примет. Ссылки, которые не удалось разобрать, пропускаются.
Пресет ProTun
Соберите схему в ProTun, экспортируйте в .protun и вставьте в proTunPreset как есть. С proTunLocked: true клиент не сможет её изменить — см. Правила провайдера.
Файл .beam
Файл — это BEAM + байт версии 0x02 + gzip от JSON профиля. В таком же виде (или просто gzip от JSON) можно отдавать тело подписки по url — тогда при обновлении приедут и серверы, и брендинг, и пресет.
import gzip, json
def write_beam(path, profile):
with open(path, "wb") as f:
f.write(b"BEAM" + bytes([2]) + gzip.compress(json.dumps(profile, ensure_ascii=False).encode()))Лимиты и срок можно отдавать заголовком subscription-userinfo, интервал — profile-update-interval, как в обычных подписках.
