Полное руководство: как сделать клавиатуру в ВК боте

Ошибка 403 при вызове метода messages.send часто возникает из-за того, что вы пытаетесь отправить встроенную клавиатуру без указания параметра attachment или в неправильном формате JSON. Для корректного отображения интерактивных элементов в диалоге с пользователем необходимо формировать структуру данных, соответствующую спецификации VK Bot API.

Разработка интерфейса для бота в ВКонтакте требует четкого понимания того, как сервер обрабатывает JSON-объекты кнопок. Клавиатура — это не просто набор текста, а сложный инструмент управления, позволяющий пользователю выбирать опции, переходить по ссылкам или запускать действия без ввода текста. Неправильная инициализация массива кнопок приведет к тому, что пользователь увидит пустое сообщение или стандартный набор действий системы.

Типы клавиатур и их назначение

Прежде чем приступать к кодированию, необходимо определить цель использования интерфейса. В экосистеме ВКонтакте существует четыре основных типа кнопок, каждый из которых имеет свой цвет и функционал. Использование правильного цвета кнопки напрямую влияет на поведение пользователя и удобство восприятия информации.

Синие кнопки (Action Type: text) предназначены для стандартного ввода текста в ответ бота. Они универсальны и подходят для большинства сценариев диалога. Зеленые кнопки (Action Type: location) автоматически отправляют геолокацию пользователя, что критично для сервисов доставки или поиска ближайших точек. Красные кнопки (Action Type: callback) отправляют скрытый payload-код, не меняя историю переписки, что идеально для меню без спама в чате.

Серые кнопки (Action Type: open_app или vkapps) открывают мини-приложения или переходят по внешним ссылкам. Игнорирование этого требования приведет к тому, что нажатие на кнопку не вызовет никакого ответа от сервера.

  • 🔵 Текстовые кнопки — стандартный ввод данных, подходит для меню «Назад» или «Заказать».
  • 🟢 Локационные кнопки — передача координат, используется в сервисах такси или доставки.
  • 🔴 Callback-кнопки — скрытая отправка данных, необходима для пагинации и интерактива.

Структура JSON объекта клавиатуры

Ключ к успешной реализации интерфейса — это правильное формирование JSON-структуры. Весь объект клавиатуры должен состоять из массива строк, где каждая строка представляет собой ряд кнопок. Если вы отправите плоский список, система отобразит их хаотично или отклонит запрос.

Каждый ряд (строка) может содержать от 1 до 4 кнопок. Превышение этого лимита приведет к ошибке валидации. Внутри каждой кнопки обязательно должны присутствовать поля action с типом и текстом (или payload). Отсутствие поля one_time сделает клавиатуру исчезающей после первого нажатия, что может быть как преимуществом, так и критическим недостатком.

Для создания многострочного меню необходимо вкладывать массивы кнопок внутрь главного массива. Например, чтобы сделать ряд из двух кнопок, вы создаете массив с двумя объектами, а затем помещаете этот массив в главный список. Это позволяет гибко управлять раскладкой интерфейса в зависимости от состояния бота.

{

"one_time": false,

"buttons": [

[

{

"action": {

"type": "text",

"label": "Меню",

"payload": "{\"command\": \"menu\"}"

}

},

{

"action": {

"type": "text",

"label": "Помощь",

"payload": "{\"command\": \"help\"}"

}

}

]

]

}

☑️ Проверка структуры JSON

Выполнено: 0 / 4

Реализация на Python с использованием vk_api

При использовании библиотеки vk_api процесс создания клавиатуры упрощается благодаря классу KeyboardBuilder. Этот инструмент автоматически сериализует объекты в корректный JSON, минимизируя риск синтаксических ошибок. Вам не нужно вручную прописывать кавычки или запятые, достаточно вызывать методы добавления кнопок.

Сначала инициализируйте объект билдера, затем добавьте кнопки методом add_button. После завершения набора кнопок в текущем ряду вызовите row(), чтобы начать новую строку. Завершающий вызов get_keyboard() вернет готовый объект, который можно передать в метод отправки сообщения.

Важно настроить параметр one_time в момент инициализации. Если вы оставите его по умолчанию (False), клавиатура останется на экране после нажатия. Для диалоговых ботов, где меню должно обновляться при каждом ответе, лучше использовать one_time=True.

Пример кода создания клавиатуры

import vk_api

from vk_api.utils import get_random_id

def get_keyboard():

kb = vk_api.Keyboard(one_time=False)

kb.add_button('Купить', payload={'command': 'buy'})

kb.add_button('Отмена', payload={'command': 'cancel'})

kb.row()

kb.add_button('Оформить', payload={'command': 'order'}, color='positive')

return kb.get_keyboard()

⚠️ Внимание: Вставьте проверку на длину payload. Максимальная длина полезной нагрузки (payload) для callback-кнопок ограничена 64 символами. Превышение этого лимита вызовет ошибку API и прервет выполнение скрипта.

Обработка нажатий и Callback API

Создание кнопки — это только половина задачи. Чтобы интерфейс был живым, необходимо настроить обработку событий на стороне сервера. Когда пользователь нажимает на кнопку, ВКонтакте отправляет вебхук на ваш сервер или вы должны опрашивать метод messages.getEvents.

В случае использования callback типа кнопки, сервер получит событие с типом message_event и полем payload. Важно сразу же отправить подтверждение нажатия через метод messages.answerCallbackEvent. Если этот шаг пропустить, нажатая кнопка будет визуально «забугериться» (останется в нажатом состоянии) у пользователя.

Логика обработки должна быть модульной: извлеките команду из JSON, проверьте ее значение и выполните соответствующее действие. Это позволяет легко масштабировать бота, добавляя новые пункты меню без переписывания основного кода. Используйте словари-маппинги для связывания команд и функций обработки.

Динамические меню и условия отображения

Статичная клавиатура подходит только для простейших сценариев. В реальных проектах меню должно меняться в зависимости от состояния пользователя. Например, если пользователь уже находится в корзине, кнопки «Добавить товар» должны смениться на «Оформить заказ».

Для реализации такой логики храните текущий статус пользователя в базе данных или кэше. При каждом запросе проверяйте этот статус и генерируйте Keyboard динамически. Это позволяет создать персонализированный опыт взаимодействия.

📊 Какой тип кнопки вы используете чаще всего?
Текстовая (text)
Callback (payload)
Ссылка (open_url)
Геолокация (location)
Цвет кнопки Код цвета Назначение Пример использования
Синий (Default) нет Обычное действие «Продолжить чтение»
Зеленый (Positive) positive Подтверждение «Подтвердить покупку»
Красный (Negative) negative Отмена или удаление «Удалить из корзины»
Серый (Secondary) secondary Вспомогательное действие «Назад», «Меню»

Ограничения и частые ошибки

Разработчики часто сталкиваются с тем, что клавиатура не отображается вовсе. Самая частая причина — попытка отправить вложенный объект вместо JSON-строки в параметр keyboard метода отправки сообщения. API ожидает строку, а не словарь.

Еще одна проблема возникает при смешивании типов кнопок в одном ряду. Хотя технически это разрешено, логически это может запутать пользователя. Также стоит избегать слишком длинных названий кнопок, так как они могут обрезаться на мобильных устройствах.

Не забывайте про лимиты: максимум 4 кнопки в строке и 3-4 строки в одной клавиатуре (в зависимости от версии API). Превышение этих лимитов приведет к возврату ошибки с кодом 11 или 403. Используйте проверку валидности перед отправкой в продакшн.

⚠️ Внимание: При использовании open_url (открытие ссылки) убедитесь, что URL начинается с https://. HTTP-ссылки будут заблокированы клиентом ВКонтакте, и кнопка станет неактивной.

Для сложных интерфейсов рассмотрите возможность использования Mini Apps вместо традиционных кнопок. Они позволяют создавать полноценные веб-интерфейсы внутри переписки, что снимает ограничения по количеству и расположению элементов управления.

FAQ: Часто задаваемые вопросы

Как проверить, работает ли моя клавиатура?

Самый простой способ — отправить тестовое сообщение боту и нажать на кнопку. Если бот ответил мгновенно и без ошибок в консоли, все работает. Также можно использовать онлайн-валидаторы JSON.

Можно ли добавить картинку на кнопку?

Нет, в стандартной клавиатуре ВК нельзя добавлять изображения на кнопки. Для этого необходимо использовать Inline-клавиатуру (для постов) или Mini Apps.

Что делать, если кнопка не нажимается?

Проверьте, отправляете ли вы message_event ответ. Если вы не отвечаете на событие нажатия, интерфейс может «зависнуть». Также проверьте лимиты payload.

Как сделать кнопку, которая исчезает после нажатия?

Используйте параметр one_time: true при создании клавиатуры. Это заставит её удалиться с экрана сразу после первого взаимодействия.