Речь про беседы сообщества: бот добавлен в чат, ему выданы права администратора, а в настройках сообщества включены «Сообщения из бесед». Без этого ВК не пришлёт содержимое сообщений беседы.
Подключение сообщества описано в статье «Как создать чат-бота ВКонтакте».
Id беседы
vk_id (он же platform_id) — это peer_id: 2000000000 + номер беседы. Номер виден в адресной строке сообщества при открытой беседе. Первая беседа сообщества — 2000000001, вторая — 2000000002 и так далее.
Переменные, которые появляются сами
Заполняются на каждом событии беседы, настраивать их не нужно.
| Переменная | Что внутри | Пример |
|---|---|---|
vk_id, platform_id
|
id беседы (peer_id) |
2000000005 |
from_id |
id автора текущего сообщения | 493121376652230668 |
conversation_message_id |
номер сообщения внутри беседы | 142 |
reply_from_id |
id автора процитированного сообщения | 413984787162726410 |
reply_text |
текст цитаты | кто дежурит сегодня? |
reply_cmid |
номер процитированного сообщения в беседе | 139 |
reply_attachments |
вложения цитаты | |
message_from_outside |
0 — сообщение человека, 3 — служебное событие | 0 |
question |
текст входящего сообщения | спасибо! |
chat_member_id |
участник, которого касается служебное событие | 413984787162726410 |
chat_action_by_self |
1 — участник сделал это сам, 0 — его добавили или исключили | 1 |
chat_action_text |
новое название беседы при её переименовании | Общий чат |
Группа reply_* заполняется, только когда сообщение является ответом на другое. На обычном сообщении они очищаются, поэтому проверка reply_from_id != '' надёжно отличает ответ от обычного сообщения.
from_id и reply_from_id есть только в беседах. В личной переписке с сообществом их нет — механики, завязанные на них, там просто не сработают.
Имён участников в переменных нет. name и full_name у клиента — это название беседы. Имя автора берётся отдельным вызовом:
#{vk_get_name(from_id)}
Три группы chat_member_id, chat_action_by_self, chat_action_text приходят только на служебных событиях беседы — см. следующий раздел.
События беседы
Кроме сообщений в воронку приходят служебные события. Их тип попадает в question, так что ловятся они обычным текстовым условием.
Текст в question
|
Когда | Кто в chat_member_id
|
|---|---|---|
chat_invite_user |
участника добавили в беседу | кого добавили |
chat_invite_user_by_link |
участник зашёл по ссылке-приглашению | кто зашёл |
chat_kick_user |
участник вышел или его исключили | о ком речь |
chat_title_update |
беседу переименовали | кто переименовал |
chat_pin_message |
сообщение закрепили | кто закрепил |
chat_unpin_message |
сообщение открепили | кто открепил |
chat_photo_update, chat_photo_remove
|
сменили или убрали аватар беседы | кто сменил |
У chat_kick_user различить «вышел сам» и «исключили» помогает chat_action_by_self: 1 — ушёл сам, 0 — исключил кто-то другой (его id лежит в from_id).
Если блок должен срабатывать только на живые сообщения участников, добавьте в условие:
message_from_outside == '0'
Это отсечёт все служебные события разом — надёжнее, чем перечислять их тексты: участник может написать chat_invite_user руками. Кавычки вокруг '0' обязательны.
Сообщения
| Функция | Что делает |
|---|---|
vk_send_message(peer_id, text) |
написать в беседу или личку |
vk_edit_message(peer_id, message_id, text) |
изменить своё сообщение |
vk_delete_messages(peer_id, cmids) |
удалить сообщения беседы |
vk_pin_message(peer_id, conversation_message_id) |
закрепить |
vk_unpin_message(peer_id) |
открепить |
vk_send_chat_action(peer_id, action) |
показать «печатает»: typing или audiomessage
|
vk_send_sticker(peer_id, sticker_id) |
отправить стикер |
Удалять и редактировать ВК разрешает только сообщения не старше суток. В vk_delete_messages для беседы передаётся номер сообщения внутри беседы — conversation_message_id, он же лежит в одноимённой переменной:
vk_delete_messages(vk_id, conversation_message_id)
Сообщение, отправленное через vk_send_message, уходит в беседу, но не попадает в историю диалога в кабинете — там видны только ответы самого блока.
Участники
| Функция | Что делает |
|---|---|
vk_get_name(user_id, full) |
имя участника; со вторым аргументом true — имя и фамилия |
vk_is_admin(peer_id, user_id) |
1 — администратор беседы, 0 — обычный участник |
vk_remove_chat_user(user_id) |
исключить из беседы |
vk_get_chat_member_count(peer_id) |
сколько человек в беседе |
vk_export_chat_link(peer_id, new) |
ссылка-приглашение; со вторым аргументом true старая ссылка сбрасывается |
vk_is_admin возвращает число, поэтому его можно сравнивать прямо в условии блока:
vk_id == 2000000005 and vk_is_admin(vk_id, from_id) == 0
Такое условие — типичный «гейт админов»: блок модерации не тронет администраторов беседы. При любой ошибке (беседа недоступна, у бота нет прав) функция вернёт 0, то есть модерация продолжит работать, а не отключится.
Исключить администратора беседы бот не сможет — это ограничение ВКонтакте.
Очки и рейтинг
Встроенная система благодарностей: очки начисляются тому, чьё сообщение процитировали. На ней собираются уровни, звания и лидерборды.
| Функция | Что делает |
|---|---|
vk_add_thanks_score(value) |
начислить очки автору цитируемого сообщения |
vk_add_thanks_score_for_answer(value) |
начислить тому, кто ответил |
vk_minus_thanks_score(value) |
снять очки; со значением 0 обнуляет |
vk_get_score(user_id) |
очки участника числом; без аргумента — автор события |
vk_get_level(user_id, points_per_level) |
уровень участника; порог по умолчанию 100 очков |
vk_get_user_info(user_id) |
очки, место в рейтинге и имя одним объектом |
vk_get_top(count, shift, delimiter, humanize) |
лидерборд |
vk_get_user_link() |
упоминание автора цитаты вида [id123
|
vk_mark_ban_user(), vk_mark_unban_user() |
исключить автора цитаты из начислений и вернуть обратно |
У vk_get_top аргумент count — сколько строк вывести, shift — со скольких пропустить (для листания), delimiter — чем разделять имя и очки, humanize по умолчанию true и возвращает готовый текст с кликабельными упоминаниями. Со значением false вернётся список объектов — если лидерборд рисуется своей разметкой.
Порядок аргументов у vk_get_top отличается от дискордового и максового: там третьим идёт humanize, а здесь delimiter. Так сделано, чтобы не сломать воронки, написанные до появления humanize.
В условии блока очки надо сравнивать через vk_get_score — эта функция возвращает число, с которым сравнение работает как ожидается. get(vk_get_user_info(), 'score') отдаёт строку, и сравнение с числом внутри одного выражения молча не сработает.
Очки беседы ВК хранятся в переменной проекта vk_thanks_score_data, отдельно от телеграмных, дискордовых и максовых — в проекте с несколькими каналами лидерборды не смешиваются.
Примеры
Приветствие новичка
Условие блока — chat_invite_user, текст ответа:
Привет, #{vk_get_name(chat_member_id)}! Загляни в закреплённые правила 👋
Удалить сообщение со стоп-словом, кроме админов
Условие — список стоп-слов, дополнительное условие:
vk_id == 2000000005 and message_from_outside == '0' and vk_is_admin(vk_id, from_id) == 0
В поле переменных:
vk_delete_messages(vk_id, conversation_message_id)
vk_send_message(vk_id, '⚠️ #{vk_get_name(from_id)}, сообщение удалено: запрещённое слово.')
Очки за благодарность с кулдауном и поздравление с уровнем
Условие — слова спасибо;спс;благодарю, дополнительное условие:
vk_id == 2000000005 and message_from_outside == '0' and reply_from_id != '' and reply_from_id != from_id
В поле переменных:
now = int(float(timestamp))
last_map = if(gm_xp_last == None, {}, gm_xp_last)
last = last_map[from_id]
last = if(last == None, 0, last)
if (now - last >= 60) {
vk_add_thanks_score(1)
last_map[from_id] = now
project.gm_xp_last = last_map
lvl = vk_get_level(reply_from_id, 100)
granted_map = if(gm_lvl == None, {}, gm_lvl)
granted = granted_map[reply_from_id]
granted = if(granted == None, 0, granted)
if (lvl > granted) {
vk_send_message(vk_id, '#{vk_get_name(reply_from_id)} вышел на уровень #{lvl} 🎉')
granted_map[reply_from_id] = lvl
project.gm_lvl = granted_map
}
}
reply_from_id != from_id не даёт начислять очки самому себе, а словарь gm_xp_last держит кулдаун в 60 секунд на каждого дающего.
Обратите внимание: поздравление считается по получателю очков (reply_from_id), а не по автору сообщения, и отправляется в том же блоке. На одно входящее сообщение срабатывает только один блок воронки, поэтому вынести награду в отдельный блок нельзя — он не получит управление.
Показать свои очки по команде
Условие — /xp, поле переменных:
points = vk_get_score()
lvl = vk_get_level()
place = get(vk_get_user_info(), 'place')
Текст ответа:
#{vk_get_name(from_id)}, у тебя #{points} XP · уровень #{lvl} · место #{place}
Лидерборд по команде
Условие — /top, поле переменных:
top = vk_get_top(10, 0, ' — ')
top = if(top == '', 'Пока никто не заработал XP', top)
Текст ответа:
🏆 Топ по XP:
#{top}


