Речь про беседы: бот добавлен в чат MAX и ему выданы права администратора — без них он не сможет удалять сообщения и исключать участников.
Подключение бота описано в статье «Как создать чат-бота в MAX».
Id беседы
platform_id — это chat_id беседы, отрицательное число вида -77736607809783. Передавать его нужно как есть, вместе со знаком минус.
Переменные, которые появляются сами
Заполняются на каждом событии, настраивать их не нужно.
| Переменная | Что внутри | Пример |
|---|---|---|
platform_id |
id беседы | -77736607809783 |
max_chat_type |
chat — беседа, dialog — личная переписка |
chat |
message_from |
id автора события | 1234567890 |
message_from_name |
как автор подписан | Павел |
message_from_username |
логин автора | pavel |
max_message_id |
id текущего сообщения на стороне MAX | mid.abc123 |
reply_from |
id автора процитированного сообщения | 987654321 |
reply_from_name |
его имя | Аня |
reply_from_username |
его логин | anna |
reply_message_id |
id процитированного сообщения | mid.def456 |
reply_text |
текст цитаты | кто дежурит сегодня? |
chat_member_id |
участник, которого касается событие входа/выхода | 1234567890 |
chat_member_name, chat_member_username
|
его имя и логин | Павел |
question |
текст входящего сообщения | спасибо! |
Имена message_from и reply_from намеренно совпадают с телеграмными и дискордовыми — групповые механики собираются одинаково на всех каналах.
Группа reply_* заполняется, только когда сообщение является ответом на другое. На обычном сообщении они очищаются, поэтому проверка reply_from != '' надёжно отличает ответ от обычного сообщения.
У цитаты сообщения бота автора нет. Если участник отвечает на сообщение, которое отправил бот или оператор из кабинета, reply_from останется пустым — начислить очки «боту» не получится, и это правильно.
max_chat_type отличает беседу от лички. Групповые механики стоит ограничивать условием по platform_id конкретной беседы или проверкой max_chat_type == 'chat'.
События
Кроме обычных сообщений в воронку приходят служебные события. Их текст попадает в question и ловится обычным текстовым условием.
Текст в question
|
Когда |
|---|---|
user_added |
участника добавили в беседу |
user_removed |
участника исключили из беседы |
bot_added |
бота добавили в беседу |
bot_removed |
бота исключили |
/start |
человек запустил бота в личке |
client_unsubscribed |
человек остановил бота |
На user_added и user_removed данные участника лежат в chat_member_id, chat_member_name, chat_member_username — приветствие пишется по ним, а не по message_from.
Если блок должен срабатывать только на живые сообщения участников, добавьте в условие:
message_from_outside == '0'
Это отсечёт служебные события разом — надёжнее, чем перечислять их тексты: участник может написать user_added руками. Кавычки вокруг '0' обязательны.
Сообщения
| Функция | Что делает |
|---|---|
max_send_message(chat_id, text) |
написать в беседу |
max_send_photo(chat_id, image_url, caption) |
отправить картинку |
max_send_document(chat_id, file_url, caption) |
отправить файл |
max_delete_message(message_id) |
удалить сообщение |
max_answer_callback(callback_id, notification, text) |
ответить на нажатие кнопки |
Id сообщения, на которое сработал блок, лежит в переменной max_message_id — отдельно доставать его не нужно:
max_delete_message(max_message_id)
Чтобы написать участнику в личку, а не в беседу, у max_send_message, max_send_photo и max_send_document есть аргумент send_by_user_id: со значением true первым аргументом передаётся id участника вместо id беседы.
Сообщение, отправленное через max_send_message, уходит в беседу, но не попадает в историю диалога в кабинете — там видны только ответы самого блока.
Участники
| Функция | Что делает |
|---|---|
max_get_chat_member(chat_id, user_id) |
данные участника беседы |
max_is_admin(chat_id, user_id) |
1 — администратор или владелец беседы, 0 — обычный участник |
max_add_chat_member(chat_id, user_id) |
добавить участника |
max_delete_chat_member(chat_id, user_id, block) |
исключить участника |
max_is_admin возвращает число, поэтому его можно сравнивать прямо в условии блока:
platform_id == -77736607809783 and max_is_admin(platform_id, message_from) == 0
Такое условие — типичный «гейт админов»: блок модерации не тронет администраторов беседы. При любой ошибке (беседа недоступна, у бота отобрали права) функция вернёт 0, то есть модерация продолжит работать, а не отключится.
У max_delete_chat_member третий аргумент решает, сможет ли участник вернуться: по умолчанию true — исключение с блокировкой, навсегда; со значением false участник просто удаляется из беседы и может зайти снова.
Очки и рейтинг
Встроенная система благодарностей: очки начисляются тому, чьё сообщение процитировали. На ней собираются уровни, звания и лидерборды.
| Функция | Что делает |
|---|---|
max_add_thanks_score(value) |
начислить очки автору цитируемого сообщения |
max_add_thanks_score_for_answer(value) |
начислить тому, кто ответил |
max_minus_thanks_score(value) |
снять очки; со значением 0 обнуляет |
max_get_score(user_id) |
очки участника числом; без аргумента — автор события |
max_get_level(user_id, points_per_level) |
уровень участника; порог по умолчанию 100 очков |
max_get_user_info(user_id) |
очки, место в рейтинге и имя одним объектом |
max_get_top(count, shift, humanize, delimiter) |
лидерборд |
У max_get_top аргумент count — сколько строк вывести, shift — со скольких пропустить (для листания), humanize со значением true вернёт готовый текст, delimiter — чем разделять имя и очки. Пустой лидерборд возвращает пустую строку.
В условии блока очки надо сравнивать через max_get_score — эта функция возвращает число, с которым сравнение работает как ожидается. get(max_get_user_info(), 'score') отдаёт строку, и сравнение с числом внутри одного выражения молча не сработает.
Очки беседы MAX хранятся в переменной проекта max_thanks_score_data, отдельно от телеграмных, дискордовых и вконтактовых — в проекте с несколькими каналами лидерборды не смешиваются.
Примеры
Приветствие новичка
Условие блока — user_added, текст ответа:
Привет, #{chat_member_name}! Загляни в закреплённые правила 👋
Удалить сообщение со стоп-словом, кроме админов
Условие — список стоп-слов, дополнительное условие:
platform_id == -77736607809783 and message_from_outside == '0' and max_is_admin(platform_id, message_from) == 0
В поле переменных:
max_delete_message(max_message_id)
max_send_message(platform_id, '⚠️ #{message_from_name}, сообщение удалено: запрещённое слово.')
Очки за благодарность с кулдауном и поздравление с уровнем
Условие — слова спасибо;спс;благодарю, дополнительное условие:
platform_id == -77736607809783 and message_from_outside == '0' and reply_from != '' and reply_from != message_from
В поле переменных:
now = int(float(timestamp))
last_map = if(gm_xp_last == None, {}, gm_xp_last)
last = last_map[message_from]
last = if(last == None, 0, last)
if (now - last >= 60) {
max_add_thanks_score(1)
last_map[message_from] = now
project.gm_xp_last = last_map
lvl = max_get_level(reply_from, 100)
granted_map = if(gm_lvl == None, {}, gm_lvl)
granted = granted_map[reply_from]
granted = if(granted == None, 0, granted)
if (lvl > granted) {
max_send_message(platform_id, '#{reply_from_name} вышел на уровень #{lvl} 🎉')
granted_map[reply_from] = lvl
project.gm_lvl = granted_map
}
}
reply_from != message_from не даёт начислять очки самому себе, а словарь gm_xp_last держит кулдаун в 60 секунд на каждого дающего.
Обратите внимание: поздравление считается по получателю очков (reply_from), а не по автору сообщения, и отправляется в том же блоке. На одно входящее сообщение срабатывает только один блок воронки, поэтому вынести награду в отдельный блок нельзя — он не получит управление.
Показать свои очки по команде
Условие — /xp, поле переменных:
points = max_get_score()
lvl = max_get_level()
place = get(max_get_user_info(), 'place')
Текст ответа:
#{message_from_name}, у тебя #{points} XP · уровень #{lvl} · место #{place}
Лидерборд по команде
Условие — /top, поле переменных:
top = max_get_top(10, 0, true, ' — ')
top = if(top == '', 'Пока никто не заработал XP', top)
Текст ответа:
🏆 Топ по XP:
#{top}