---
url: /templates/astral.md
description: >-
Пространство astral в шаблонах — клубы семьи Astral, профили игроков Brawl
Stars, рейтинги, статистика и проверка по черному списку.
---
# Пространство astral
Через объект astral шаблоны получают данные проекта Astral: клубы семьи, профили игроков Brawl Stars, рейтинги, статистику клубов и черный список. Данные доступны только для чтения — шаблон ничего не может в них изменить.
## Уровни доступа { #tiers }
Что доступно чату, зависит от его уровня. Уровень определяет сервер Astral — бот и шаблон не могут его изменить.
| Уровень | Какие чаты | Что доступно |
|---|---|---|
| | Любой чат | Клубы семьи, рейтинги, публичные профили игроков, статистика клубов |
| | Чат, привязанный к клубу Astral | Все из `public` + история вступлений и выходов клуба, снимок состава, **проверка и просмотр черного списка** |
Узнать уровень чата: `{{ astral.tier }}` → `public` или `family`.
## Клубы { #clubs }
| Вызов | Уровень | Что вернет |
|---|---|---|
| `astral.clubs()` | public | Список клубов семьи |
| `astral.club('#TAG')` | public | Клуб по тегу или `null` |
| `club.members` | public | Состав клуба |
| `club.stats('week')` | public | Статистика за период: `'today'`, `'24h'`, `'week'`, `'month'` |
| `club.history(24)` | family | События вступления и выхода за N часов (до 168) |
| `club.snapshot()` | family | Снимок состава |
| `chat.astral.club` | — | Первый клуб, привязанный к этому чату, или `null` |
| `chat.astral.clubs` | — | Все клубы, привязанные к чату |
### Свойства клуба { #club }
| Свойство | Что в нем |
|---|---|
| `tag`, `name`, `description`, `type` | Тег, название, описание, тип клуба |
| `trophies`, `requiredTrophies` | Кубки клуба и порог вступления |
| `membersCount` | Число участников |
| `globalRank`, `localRank` | Место в мировом и локальном рейтинге |
| `president` | Имя президента или `null` |
| `badgeId` | ID значка клуба |
Участник клуба (`club.members`): `tag`, `name`, `trophies`, `role`.
Статистика (`club.stats(…)`): `period`, `currentMembers`, `joins`, `leaves`, `trophiesChange`, `netChange`.
Событие истории (`club.history(…)`): `event` (`join` или `leave`), `playerTag`, `playerName`, `trophies`, `role`, `ts`.
## Игроки { #players }
| Вызов | Уровень | Что вернет |
|---|---|---|
| `astral.player('#TAG')` | public | Профиль игрока или `null` |
| `member.astral.playerTag` | public | Тег игрока, привязанного к участнику Telegram, или `null` |
| `member.astral.player` | public | Профиль привязанного игрока или `null` |
| Свойство игрока | Что в нем |
|---|---|
| `tag`, `name` | Тег и имя |
| `trophies`, `highestTrophies` | Кубки сейчас и рекорд |
| `expLevel` | Уровень опыта |
| `club` | Клуб: `club.tag`, `club.name`, или `null` |
| `victories.trio`, `victories.duo`, `victories.solo` | Победы 3×3, в дуо и соло |
| `brawlersCount` | Число бойцов |
| `ranked.current`, `ranked.seasonBest`, `ranked.allTimeBest` | Рейтинговый режим |
| `iconId` | ID иконки профиля |
`member.astral` работает только для участников этого чата.
## Рейтинги { #rankings }
| Вызов | Что вернет |
|---|---|
| `astral.rankings.clubs(страна, сколько?)` | Топ клубов, до 25 |
| `astral.rankings.players(страна, сколько?)` | Топ игроков, до 25 |
Страна — `'global'` или код страны: `'ru'`, `'kz'`, `'by'`. Запись рейтинга: `rank`, `tag`, `name`, `trophies`, `membersCount`, `club`.
## Черный список { #blacklist }
Только для чатов уровня .
| Вызов | Что вернет |
|---|---|
| `astral.blacklist.check('#TAG')` | Результат проверки: `blacklisted` (да/нет), `type` (`project` — проектный или `club` — клубный), `clubTag`, `reason` |
| `astral.blacklist.page(вид, страница)` | Страница списка до 25 записей. Вид: `'project'` или `'club'` |
Запись списка: `playerTag`, `playerName`, `type`, `clubTag`, `reason`, `createdAt`.
## Примеры { #examples }
### Проверка игрока по ЧС { #example-blacklist }
Команда `!чс ABCD1234`, работает в чате, привязанном к клубу:
```template
{% set tag = arguments.get(1) | upper | replace('#', '') %}
{% require tag returning 'Укажи тег игрока: !чс ABCD1234' %}
{% set r = astral.blacklist.check(tag) %}
{% if r.blacklisted -%}
⛔ #{{ tag }} в черном списке ({{ r.type == 'project' ? 'проектный' : 'клубный' }}). Причина: {{ r.reason }}
{%- else -%}
✅ #{{ tag }} не найден в черном списке.
{%- endif %}
```
✅ #ABCD1234 не найден в черном списке.
### Приветствие с профилем Brawl Stars { #example-welcome }
```template
{%- set p = member.astral.player -%}
# Привет, {{ member.name }}!
Ты {{ chat.memberCount | number_format }}-й участник **{{ chat.title }}**.
{% if p %}
{{ table([['Игрок', p.name], ['Кубки', p.trophies | number_format], ['Клуб', p.club.name ?: '—']], { bordered: true, compact: true }) }}
{% endif %}
{% do url_button('Правила', 'https://telegra.ph/pravila-chata') %}
```
# Привет, Анна!
Ты 1 248-й участник **Клуб Astral**.
| | |
|---|---|
| Игрок | Anna\_BS |
| Кубки | 24 510 |
| Клуб | Astral Family |
### Топ клуба с листанием { #example-top }
```template
{% set club = chat.astral.club %}
{% require club returning 'Этот чат не привязан к клубу Astral' %}
{% set page = (parameters.get('page')) ?: 0 %}
{% if component.id == 'next' %}{% set page += 1 %}{% elseif component.id == 'prev' and page > 0 %}{% set page -= 1 %}{% endif %}
{% do parameters.store('page', page) %}
{% set members = club.members | sort_by('trophies', 'DESC') | slice(page * 10, 10) %}
**{{ club.name }}** · страница {{ page + 1 }}
{% for m in members %}
{{ page * 10 + loop.index }}. {{ m.name }} — {{ m.trophies | number_format }}
{% endfor %}
{% do button('SECONDARY', 'prev', null, '⬅️', 'self', page == 0) %}
{% do button('SECONDARY', 'next', null, '➡️', 'self', (members | length) < 10) %}
```
### Таблица лучших игроков клуба { #example-table }
```template
{% set club = chat.astral.club %}
{% require club returning 'Этот чат не привязан к клубу Astral' %}
## {{ club.name }}
{{ table_of(club.members | sort_by('trophies', 'DESC') | slice(0, 15), { name: 'Игрок', trophies: 'Кубки' }, { header: true, index: '#', striped: true }) }}
{{ footer('Обновлено ' ~ datetime(now(), 'r')) }}
```
## Ошибки { #errors }
| Ситуация | Что происходит |
|---|---|
| Функция уровня `family` в чате уровня `public` | Ошибка: «Доступно только в чатах, привязанных к клубу Astral» (`tier_forbidden`) |
| Клуб или игрок не найден | Возвращается `null` — проверяйте через `require` или `?:` |
| Сервис Astral или Brawl Stars недоступен | Ошибка «Данные Astral временно недоступны» (`astral_unavailable`) |
| Больше 5 обращений за выполнение | Ошибка `quota_astral` |
| Неверный тег, период или страна | Ошибка `bad_arguments` |
## Кэш и квота { #cache }
Бот ненадолго запоминает ответы, поэтому данные обновляются с задержкой:
| Данные | Обновляются раз в |
|---|---|
| Уровень чата, привязки, черный список, история клуба, игрок | 60 секунд |
| Клубы, состав, статистика, снимок, привязка игрока к Telegram | 5 минут |
| Рейтинги | 15 минут |
За одно выполнение — не больше 5 обращений к `astral`, включая ленивые свойства вроде `club.members`. Обращение считается, даже если ответ взят из кэша. Сохраняйте результат в переменную: `{% set club = chat.astral.club %}`.
::: info Приватность
Данные приходят очищенными: в них нет имен сотрудников Astral, внутренних идентификаторов и чужих привязок Telegram.
:::