Заказать бота

VK Bot API: messages.send, клавиатуры, лимиты и ошибки

Разбор Bot API ВКонтакте: messages.send, peer_id, random_id, клавиатуры и payload. Типовые ошибки, ограничения и шаблоны стабильной отправки на Python.

Содержание статьи

Если бот в ВК «иногда отвечает, иногда нет», проблема чаще всего в деталях API: лимиты, неверный peer_id, ошибки в клавиатуре или некорректная работа с random_id.

Этот материал — концентрат практики по messages.* для Bot API: что важно настроить, какие есть ограничения и как писать код без скрытых ловушек.

Что нужно знать до старта

  • Бот работает от имени сообщества, не личной страницы.
  • Включены Возможности ботов, Long Poll API и событие message_new.
  • У токена есть права на сообщения сообщества.

Базовая настройка подробно разобрана в статье «Как создать бота для ВК с нуля».

Минимальная отправка сообщения

На уровне API отправка строится вокруг метода messages.send.

Пример на vkbottle:

from vkbottle.bot import Bot, Message
bot = Bot(token="VK_TOKEN")
@bot.on.message(text="привет")
async def hello(message: Message):
    await bot.api.messages.send(
        peer_id=message.peer_id,
        random_id=0,
        message="Привет! Чем помочь?",
    )

Почему важен random_id

random_id нужен для защиты от дублирования. Если сеть «дернулась» и запрос ушёл повторно, VK не отправит одно и то же сообщение дважды.

На практике:

  • для простых ботов можно ставить random_id=0 (часто используется во фреймворках);
  • для highload лучше генерировать уникальный id самостоятельно.

Разница между peer_id и from_id

Ошибка №1 у новичков — отправка в from_id вместо peer_id.

  • from_id — кто написал;
  • peer_id — куда отвечать (личка/беседа).

Если бот работает и в беседах, отвечай именно в peer_id, иначе часть ответов будет уходить не туда.

Клавиатуры: как не получить ошибку

Клавиатура — JSON, который передаётся вместе с сообщением. В vkbottle удобнее пользоваться билдерами.

from vkbottle import Keyboard, Text
from vkbottle.bot import Bot, Message
bot = Bot(token="VK_TOKEN")
menu_keyboard = (
    Keyboard(inline=False)
    .add(Text("💰 Цены"), color="primary")
    .add(Text("🚚 Доставка"), color="secondary")
    .row()
    .add(Text("📞 Контакты"), color="positive")
    .get_json()
)
@bot.on.message(text=["меню", "start", "начать"])
async def menu(message: Message):
    await message.answer(
        "Выберите раздел:",
        keyboard=menu_keyboard,
    )

Частые ошибки с клавиатурами

  1. Слишком длинный текст кнопки.
  2. Неверный JSON (если формируешь вручную).
  3. Пытаешься отправить inline-клавиатуру туда, где ожидается обычная.
  4. Передаёшь payload не строкой JSON.

Payload: как строить сценарии без хрупкого текста

Если ориентироваться только на текст кнопки ("Цены", "Прайс"), UX ломается при любом переименовании. Надёжнее использовать payload.

import json
from vkbottle import Keyboard, Text
from vkbottle.bot import Bot, Message
bot = Bot(token="VK_TOKEN")
keyboard = (
    Keyboard()
    .add(Text("💰 Цены", payload={"cmd": "prices"}), color="primary")
    .add(Text("📞 Контакты", payload={"cmd": "contacts"}), color="positive")
    .get_json()
)
@bot.on.message(text="меню")
async def show_menu(message: Message):
    await message.answer("Меню", keyboard=keyboard)
@bot.on.message()
async def route_by_payload(message: Message):
    if not message.payload:
        return
    data = json.loads(message.payload)
    cmd = data.get("cmd")
    if cmd == "prices":
        await message.answer("Тарифы: Старт / Бизнес / Индивидуально")
    elif cmd == "contacts":
        await message.answer("Напишите в ЛС сообщества, ответим в рабочее время")

Ограничения, о которых забывают чаще всего

1) Ограничение частоты запросов

У VK есть лимиты на методы API. Если бот массово шлёт ответы или рассылки, легко получить ошибки «слишком много запросов».

Что делать:

  • ставить очередь отправки;
  • добавлять паузы между массовыми отправками;
  • группировать операции, где это возможно.

2) Ограничения по контенту

Сообщения могут не отправляться из-за запрещённого контента или неверных вложений.

Практика:

  • валидируй пользовательский ввод;
  • не вставляй «сырые» ссылки и команды без проверки;
  • логируй ошибки API целиком.

3) Ограничения в беседах

В чатах поведение бота зависит от прав и режима беседы. Бот может не видеть часть событий, если не добавлен корректно.

Надёжный шаблон обработчика

import logging
from vkbottle.bot import Bot, Message
logging.basicConfig(level=logging.INFO, format="%(asctime)s | %(levelname)s | %(message)s")
bot = Bot(token="VK_TOKEN")
@bot.on.message()
async def safe_handler(message: Message):
    try:
        text = (message.text or "").strip().lower()
        if text in {"привет", "hello"}:
            await message.answer("Привет! Напишите «меню»")
            return
        if text == "меню":
            await message.answer("Разделы: цены, доставка, контакты")
            return
        await message.answer("Не понял запрос. Напишите «меню».")
    except Exception:
        logging.exception("Ошибка обработки сообщения")

Почему это важно:

  • нет немых падений;
  • ошибка логируется и не останавливает весь бот;
  • пользователю всегда приходит ответ, даже если команда не распознана.

Частые вопросы

Почему бот отвечает в личке, но молчит в группе?

Обычно не включён message_new в типах событий Long Poll API или выключены возможности бота в сообществе.

Можно ли обойтись без клавиатур?

Да, но с клавиатурами сценарии понятнее для пользователя: меньше ошибок ввода и быстрее переход к нужному действию.

Что такое random_id в VK API и почему без него бывают дубли?

random_id — это защита от повторной доставки одного и того же сообщения. Если сеть «дёрнулась» и запрос отправился повторно, корректный random_id помогает избежать дублей.

Почему messages.send возвращает ошибку, хотя токен выглядит правильным?

Частые причины: нет нужных прав у ключа сообщества, отключены события бота, перепутан peer_id или отправка идёт в диалог, где боту нельзя писать.

Что лучше для Bot API в 2026: vk_api или vkbottle?

Для новых проектов обычно лучше vkbottle: меньше шаблонного кода и удобнее масштабировать сценарии. Подробное сравнение — vkbottle или vk_api.

Что такое payload в VK API?

payload — это произвольная строка (обычно JSON), которую можно прикрепить к кнопке клавиатуры. Когда пользователь нажимает кнопку, бот получает её содержимое в message.payload и обрабатывает по этому ключу, а не по тексту. Это надёжнее: текст можно перевести или изменить, payload — нет.

Как работает messages.send в VK API?

messages.send — основной метод для отправки сообщений в VK Bot API. Обязательные параметры: peer_id (получатель) и random_id (защита от дублей). Дополнительно — message, keyboard, attachment. В vkbottle метод доступен через await bot.api.messages.send(...).

Почему messages.send форматирование не работает?

VK API не поддерживает HTML или Markdown в сообщениях, в отличие от Telegram. Для форматирования используются только эмодзи, переводы строк и Unicode-символы. Если нужен «жирный» текст — пишите CAPS LOCK или используйте символы рамок.

Какой метод vkbottle отвечает за отправку ответного сообщения?

message.answer(text) — это сокращение, которое автоматически подставляет правильный peer_id и генерирует random_id. Под капотом вызывает messages.send. Это самый удобный способ ответить пользователю в обработчике.

Почему не отправляется сообщение в боте VK?

Шесть типичных причин: 1) нет прав у токена; 2) выключен message_new в Long Poll; 3) пользователь не нажал «Начать»; 4) бот заблокирован пользователем; 5) превышен лимит rate limit; 6) неверный peer_id. Логируйте ошибки messages.send — VK обычно возвращает понятный код.

Что такое логирование API в VK-боте?

Логирование — это запись всех взаимодействий с VK API в файл или консоль: какие методы вызывались, что вернулось, какие ошибки. В vkbottle логирование можно включить через logging.basicConfig(level=logging.DEBUG) или middleware. Это критично для отладки в продакшне.

Можно ли запретить пользователю писать в чат через VK API?

API сообщества не позволяет «забанить» конкретного пользователя в личке от имени бота. Но можно игнорировать его сообщения в коде через blacklist в обработчике. Для бесед (multi-user чатов) используется метод messages.removeChatUser.

Что внедрить прямо сейчас

  1. Перевести меню бота на payload, а не на проверку текста.
  2. Добавить централизованное логирование ошибок.
  3. Проверить, что везде используется peer_id для ответов.
  4. Ввести очередь/ограничение частоты отправки для массовых сообщений.

Нужен рабочий бот без долгой настройки инфраструктуры?

Если нужен бот с индивидуальной логикой, интеграциями и сложными ветками диалога — оставьте заявку на разработку под ключ.

Для быстрого запуска типового сценария можно выбрать решение в каталоге готовых ботов.

Следующая статья по теме

Комментарии

Загрузка...