Полезные примеры
Готовые шаблоны, которые можно скопировать и поменять под себя. У каждого примера написано, куда его вставить и какие настройки выбрать.
Как пользоваться
Наведите курсор на блок кода — справа появится кнопка копирования. UUID действий в примерах вымышленные: замените их на UUID своих действий из меню «⋯».
Приветствие с правилами
Где: «Приветствия» → «Приветствие при входе». Режим Rich, синтаксис Markdown.
# Добро пожаловать, {{ member.name }}!
Ты **{{ chat.memberCount | number_format }}**-й участник **{{ chat.title }}**.
<details><summary>📜 Правила чата</summary>
1. Без рекламы и ссылок на другие чаты
2. Без оскорблений
3. Флуд и спам — мьют на час
</details>
{% do url_button('Полные правила', 'https://telegra.ph/pravila-chata') %}Добро пожаловать, Анна!
Ты 1 248-й участник Клуб Astral.
📜 Правила чата
- Без рекламы и ссылок на другие чаты
- Без оскорблений
- Флуд и спам — мьют на час
Случайное число
Где: пользовательская команда !ранд, действие «Отправка сообщения».
{% set minimum = arguments.get(1) %}
{% set maximum = arguments.get(2) %}
{% require minimum returning 'Пожалуйста, укажите минимальное значение!' %}
{% require minimum is number returning 'Минимальное значение должно быть числом!' %}
{% require maximum returning 'Пожалуйста, укажите максимальное значение!' %}
{% require maximum is number returning 'Максимальное значение должно быть числом!' %}
{% if (minimum > maximum) %}
{% return 'Максимальное значение должно быть больше минимального!' %}
{% endif %}
{{ member }}, вам выпало **{{ random(minimum, maximum) }}**Магический шар
Где: команда !шар, «Отправка сообщения». Ответы выпадают с разной вероятностью.
{% require arguments.value returning 'Задай вопрос: !шар выиграем ли мы турнир?' %}
🎱 {{ random(
['Бесспорно', 'Скорее да', 'Спроси позже', 'Даже не думай', 'Звезды говорят — да'],
[25, 25, 20, 20, 10]
) }}🎱 Звезды говорят — да
Монетка с реакцией
Где: команда !монетка, «Отправка сообщения».
{% set side = random(['Орел', 'Решка']) %}
🪙 {{ member.name }} подбрасывает монетку… **{{ side }}**!
{% do reaction(side == 'Орел' ? '🔥' : '👍') %}Профиль участника
Где: команда !профиль, «Отправка сообщения». Можно вызвать для себя или ответом на чужое сообщение.
{% set m = arguments.targetMember ?: member %}
## {{ m.name }}
{{ table([
['Уровень', m.rank.level],
['Опыт', m.rank.totalExp | number_format],
['Место в чате', m.rank.rank],
['До следующего уровня', m.rank.remainingExp | number_format],
['Предупреждения', m.warnCount],
['В чате с', date(m.joinedAt, 'd MMMM yyyy')]
], { bordered: true, compact: true }) }}Анна Смирнова
| Уровень | 12 |
| Опыт | 18 430 |
| Место в чате | 7 |
| До следующего уровня | 880 |
| Предупреждения | 0 |
| В чате с | 11 апреля 2026 |
Экономика: бонус, баланс, перевод
Три команды, которые работают вместе. Монеты хранятся в атрибуте coins и дублируются в индекс balances для топа.
!бонус — раз в сутки +100 монет. «Отправка сообщения»:
{% set last = member.getAttribute('bonus_at') %}
{% require now().millis - (last.value ?: 0) >= 86400000 returning '⏳ Бонус уже получен. Приходи завтра!' %}
{% set coins = member.getAttribute('coins').increment(100) %}
{% do last.update(now().millis) %}
{% do chat.getIndex('balances').get(member.id).update(coins) %}
💰 {{ member }}, +100 монет! Теперь у тебя **{{ coins | number_format }}** 🪙!баланс — показать монеты. «Отправка сообщения», режим ответа — эфемерно:
{% set m = arguments.targetMember ?: member %}
У {{ m.name }} **{{ (m.getAttribute('coins').value ?: 0) | number_format }}** 🪙!перевод @кому сумма — «Отправка сообщения»:
{% set target = arguments.targetMember %}
{% set amount = arguments.get(2) %}
{% require target returning 'Кому переводим? !перевод @anna 50' %}
{% require target.id != member.id returning 'Нельзя перевести самому себе' %}
{% require (amount is number) and amount > 0 returning 'Сумма должна быть положительным числом' %}
{% set mine = member.getAttribute('coins') %}
{% require (mine.value ?: 0) >= amount returning 'Недостаточно монет' %}
{% set left = mine.decrement(amount) %}
{% set theirs = target.getAttribute('coins').increment(amount) %}
{% set balances = chat.getIndex('balances') %}
{% do balances.get(member.id).update(left) %}
{% do balances.get(target.id).update(theirs) %}
💸 {{ member }} → {{ target }}: **{{ amount }}** 🪙Команда пишет две записи индекса — это максимум за одно выполнение, см. квоты.
Топ с листанием
Где: команда !топ, «Отправка сообщения», флажок «Заменять сообщение с нажатой кнопкой» включен. Использует индекс balances из примера выше.
{% set pageNum = (parameters.get('page')) ?: 0 %}
{% if component.id == 'next' and not (parameters.get('isLast')) %}{% set pageNum += 1 %}{% elseif component.id == 'prev' and pageNum > 0 %}{% set pageNum -= 1 %}{% endif %}
{% set page = chat.indexes.balances.getPageOf(pageNum, 10, 'DESC') %}
{% do parameters.store('page', page.number) %}
{% do parameters.store('isLast', page.isLast) %}
## 💰 Самые богатые · {{ page.number + 1 }}/{{ page.totalPages ?: 1 }}
{% for entry in page %}
{{ loop.index + page.number * page.size }}. {{ mention(entry.key) }} — {{ entry.value | number_format }} 🪙
{% else %}
Пока никто ничего не заработал.
{% endfor %}
{% do button('PRIMARY', 'prev', null, '⬅️', 'self', page.isFirst) %}
{% do button('PRIMARY', 'next', null, '➡️', 'self', page.isLast) %}Выбор роли из меню
Участник выбирает роль бота — например, любимый режим игры.
Действие 1 — «Меню» (по умолчанию), «Отправка сообщения»:
Выбери свой любимый режим — получишь роль и доступ к топику:
{% do select_menu('STRING', 'mode', 'Режим', 'a7c3e1f0-5b2d-4c8e-9f1a-2d3e4f5a6b7c')
.addOption('Броулбол', 'r_brawlball', '⚽')
.addOption('Захват кристаллов', 'r_gemgrab', '💎')
.addOption('Одиночное ШД', 'r_showdown', '🌵') %}Действие 2 — «Выдать», «Отправка сообщения», куда — эфемерно:
{% set roleId = component.selectedOptions | first %}
{% transform r in ['r_brawlball', 'r_gemgrab', 'r_showdown'] as others %}
{% if r != roleId %}{% return r %}{% endif %}
{% endtransform %}
{% do member.modifyRoles([roleId], others) %}
Готово! Теперь у тебя роль {{ chat.getRole(roleId) }}.transform собирает список «остальных» ролей, а modifyRoles одним вызовом выдает выбранную и снимает остальные. ID ролей (r_brawlball и другие) замените на ID своих ролей из раздела «Роли бота».
Счетчик вызовов
Где: любой шаблон. Считает, сколько раз его выполнили, в атрибуте чата.
{% set n = bot.getAttribute('hello_count').increment(1) %}
Привет! Со мной поздоровались уже {{ n }} {{ plural(n, 'ru', 'раз', 'раза', 'раз', 'раза') }}.Проверка игрока по ЧС
Где: команда !чс, «Отправка сообщения». Работает только в чате, привязанном к клубу Astral.
{% 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 %}Больше примеров с данными Astral — в статье Пространство astral.
Подтверждение бана кнопками
Разобран подробно в статье Кнопки и меню выбора.