Нередко приходится упираться в системный лимит ВКонтакте, когда имеешь дело с большими по объёму клавиатурами для ботов. Чтобы "обойти" это ограничение - можно сделать пагинацию, то бишь разбить клавиатуру на несколько частей и добавить кнопки для переключения между ними. В этой статье напишем простого LongPoll-бота, который будет отправлять картинки при нажатии на кнопки, ну, и, конечно же, реализуем пагинацию клавиатуры с кнопками.
Шаг 1: Настройка сообщества
1. Включаем сообщения сообщества и возможности ботов:
2. Создаём токен сообщества с правами доступа на управление, сообщения и фотографии (также сохраняем его у себя, скоро он нам понадобится):
3. Включаем Long Poll API и выбираем нужную версию (также её запоминаем или сохраняем у себя, скоро понадобится):
4. Ставим галочку напротив входящих сообщений в событиях:
Шаг 2: Написание бота
Подключаем библиотеку и записываем в константы токен сообщества и выбранную версию API:
<?php
require_once __DIR__ . '/vendor/digitalstars/simplevk/autoload.php'; // Подключение библиотеки
const VK_KEY = '****************'; // Токен сообщества
const VERSION = '5.131'; // Версия VK API
Далее необходимо создать экземпляры класса LongPoll и класса Bot:
$vk = \DigitalStars\SimpleVK\LongPoll::create( VK_KEY, VERSION ); // Экземпляр класса LongPoll
$bot = \DigitalStars\SimpleVK\Bot::create( $vk ); // Экземпляр класса Bot
Клавиатуры формируются из массива такого типа:
[ [ 'btn_1' ], [ 'btn_2' ], [ 'btn_3' ] ]
Но элементов в нём может быть гораздо больше, поэтому нам понадобится функция (назову её pagination()), которая будет разбивать большие массивы на несколько частей (то есть разбивать клавиатуру на несколько страниц):
function pagination( array $keyboard ): array
{
if ( count( $keyboard ) <= 10 )
return $keyboard;
$keyboards = array_chunk( $keyboard, 9 );
$size = count( $keyboards );
foreach ( $keyboards as $key => $value )
{
if ( $key > 0 and $key + 1 < $size )
$keyboards[$key][] = [ 'btn_prev_' . $key, 'btn_next_' . $key ];
else if ( $key == 0 )
$keyboards[$key][] = [ 'btn_next_' . $key ];
else if ( $key + 1 == $size )
$keyboards[$key][] = [ 'btn_prev_' . $key ];
}
return $keyboards;
}
Как можно заметить - функция сразу проверяет, нужна ли вообще пагинация в данной ситуации. Если элементов не больше десяти - массив вернётся в прежнем виде. В противном случае клавиатура разобьётся на несколько частей по 9 строк + добавится строка с кнопками для переключения между страницами.
Теперь можно добавить кнопки, у меня их будет 15. А при нажатии на каждую бот будет отправлять картинку с одноимённым автомобилем:
$bot->btn( 'btn_1', [ 'Ford', 'blue' ] )->text( 'Ford' )->img( __DIR__ . '/img/ford.jpg' );
$bot->btn( 'btn_2', [ 'Kia', 'blue' ] )->text( 'Kia' )->img( __DIR__ . '/img/kia.jpg' );
$bot->btn( 'btn_3', [ 'Hyundai', 'blue' ] )->text( 'Hyundai' )->img( __DIR__ . '/img/hyundai.jpg' );
$bot->btn( 'btn_4', [ 'Honda', 'blue' ] )->text( 'Honda' )->img( __DIR__ . '/img/honda.jpg' );
$bot->btn( 'btn_5', [ 'Chevrolet', 'blue' ] )->text( 'Chevrolet' )->img( __DIR__ . '/img/chevrolet.jpg' );
$bot->btn( 'btn_6', [ 'Mazda', 'blue' ] )->text( 'Mazda' )->img( __DIR__ . '/img/mazda.jpg' );
$bot->btn( 'btn_7', [ 'Geely', 'blue' ] )->text( 'Geely' )->img( __DIR__ . '/img/geely.jpg' );
$bot->btn( 'btn_8', [ 'Chery', 'blue' ] )->text( 'Chery' )->img( __DIR__ . '/img/chery.jpg' );
$bot->btn( 'btn_9', [ 'Haval', 'blue' ] )->text( 'Haval' )->img( __DIR__ . '/img/haval.jpg' );
$bot->btn( 'btn_10', [ 'Volvo', 'blue' ] )->text( 'Volvo' )->img( __DIR__ . '/img/volvo.jpg' );
$bot->btn( 'btn_11', [ 'Toyota', 'blue' ] )->text( 'Toyota' )->img( __DIR__ . '/img/toyota.jpg' );
$bot->btn( 'btn_12', [ 'Range Rover', 'blue' ] )->text( 'Range Rover' )->img( __DIR__ . '/img/range_rover.jpg' );
$bot->btn( 'btn_13', [ 'Mercedes', 'blue' ] )->text( 'Mercedes' )->img( __DIR__ . '/img/mercedes.jpg' );
$bot->btn( 'btn_14', [ 'BMW', 'blue' ] )->text( 'BMW' )->img( __DIR__ . '/img/bmw.jpg' );
$bot->btn( 'btn_15', [ 'Alfa Romeo', 'blue' ] )->text( 'Alfa Romeo' )->img( __DIR__ . '/img/alfa_romeo.jpg' );
Теперь все эти кнопки можно сгруппировать в массив с помощью уже написанной функции pagination():
$keyboards = pagination( [
[ 'btn_1' ],
[ 'btn_2' ],
[ 'btn_3' ],
[ 'btn_4' ],
[ 'btn_5' ],
[ 'btn_6' ],
[ 'btn_7' ],
[ 'btn_8' ],
[ 'btn_9' ],
[ 'btn_10' ],
[ 'btn_11' ],
[ 'btn_12' ],
[ 'btn_13' ],
[ 'btn_14' ],
[ 'btn_15' ],
] );
Создадим также главное меню (главным меню будет первая страница клавиатуры) и редирект на него при вводе неизвестной команды:
$bot->redirect( 'other', 'first' );
$bot->cmd( 'first' )->kbd( $keyboards[0] )->text( 'Меню автомобилей:' );
У нас уже есть массив с клавиатурами, есть главное меню. Осталось только добавить вызов каждой страницы с помощью кнопок "Вперёд" и "Назад". Проходимся циклом foreach по каждой странице и добавляем на неё кнопки:
foreach ( $keyboards as $key => $value )
{
$bot->cmd( 'page_' . $key )->kbd( $value )->text( 'Меню автомобилей (страница ' . $key + 1 . '):' );
$bot->redirect( 'btn_prev_' . $key, 'page_' . $key - 1 )->btn( 'btn_prev_' . $key, $vk->buttonText( 'Предыдущая страница', 'red' ) );
$bot->redirect( 'btn_next_' . $key, 'page_' . $key + 1 )->btn( 'btn_next_' . $key, $vk->buttonText( 'Следующая страница', 'red' ) );
}
Да, и нужно не забыть запустить бота в конце:
$vk->listen( function() use ( $bot )
{
$bot->run();
} );
Весь код:
<?php
require_once __DIR__ . '/vendor/digitalstars/simplevk/autoload.php'; // Подключение библиотеки
const VK_KEY = '****************'; // Токен сообщества
const VERSION = '5.131'; // Версия VK API
$vk = \DigitalStars\SimpleVK\LongPoll::create( VK_KEY, VERSION ); // Экземпляр класса LongPoll
$bot = \DigitalStars\SimpleVK\Bot::create( $vk ); // Экземпляр класса Bot
$keyboards = pagination( [
[ 'btn_1' ],
[ 'btn_2' ],
[ 'btn_3' ],
[ 'btn_4' ],
[ 'btn_5' ],
[ 'btn_6' ],
[ 'btn_7' ],
[ 'btn_8' ],
[ 'btn_9' ],
[ 'btn_10' ],
[ 'btn_11' ],
[ 'btn_12' ],
[ 'btn_13' ],
[ 'btn_14' ],
[ 'btn_15' ],
] );
$bot->redirect( 'other', 'first' );
$bot->cmd( 'first' )->kbd( $keyboards[0] )->text( 'Меню автомобилей:' );
foreach ( $keyboards as $key => $value )
{
$bot->cmd( 'page_' . $key )->kbd( $value )->text( 'Меню автомобилей (страница ' . $key + 1 . '):' );
$bot->redirect( 'btn_prev_' . $key, 'page_' . $key - 1 )->btn( 'btn_prev_' . $key, $vk->buttonText( 'Предыдущая страница', 'red' ) );
$bot->redirect( 'btn_next_' . $key, 'page_' . $key + 1 )->btn( 'btn_next_' . $key, $vk->buttonText( 'Следующая страница', 'red' ) );
}
$bot->btn( 'btn_1', [ 'Ford', 'blue' ] )->text( 'Ford' )->img( __DIR__ . '/img/ford.jpg' );
$bot->btn( 'btn_2', [ 'Kia', 'blue' ] )->text( 'Kia' )->img( __DIR__ . '/img/kia.jpg' );
$bot->btn( 'btn_3', [ 'Hyundai', 'blue' ] )->text( 'Hyundai' )->img( __DIR__ . '/img/hyundai.jpg' );
$bot->btn( 'btn_4', [ 'Honda', 'blue' ] )->text( 'Honda' )->img( __DIR__ . '/img/honda.jpg' );
$bot->btn( 'btn_5', [ 'Chevrolet', 'blue' ] )->text( 'Chevrolet' )->img( __DIR__ . '/img/chevrolet.jpg' );
$bot->btn( 'btn_6', [ 'Mazda', 'blue' ] )->text( 'Mazda' )->img( __DIR__ . '/img/mazda.jpg' );
$bot->btn( 'btn_7', [ 'Geely', 'blue' ] )->text( 'Geely' )->img( __DIR__ . '/img/geely.jpg' );
$bot->btn( 'btn_8', [ 'Chery', 'blue' ] )->text( 'Chery' )->img( __DIR__ . '/img/chery.jpg' );
$bot->btn( 'btn_9', [ 'Haval', 'blue' ] )->text( 'Haval' )->img( __DIR__ . '/img/haval.jpg' );
$bot->btn( 'btn_10', [ 'Volvo', 'blue' ] )->text( 'Volvo' )->img( __DIR__ . '/img/volvo.jpg' );
$bot->btn( 'btn_11', [ 'Toyota', 'blue' ] )->text( 'Toyota' )->img( __DIR__ . '/img/toyota.jpg' );
$bot->btn( 'btn_12', [ 'Range Rover', 'blue' ] )->text( 'Range Rover' )->img( __DIR__ . '/img/range_rover.jpg' );
$bot->btn( 'btn_13', [ 'Mercedes', 'blue' ] )->text( 'Mercedes' )->img( __DIR__ . '/img/mercedes.jpg' );
$bot->btn( 'btn_14', [ 'BMW', 'blue' ] )->text( 'BMW' )->img( __DIR__ . '/img/bmw.jpg' );
$bot->btn( 'btn_15', [ 'Alfa Romeo', 'blue' ] )->text( 'Alfa Romeo' )->img( __DIR__ . '/img/alfa_romeo.jpg' );
$vk->listen( function() use ( $bot )
{
$bot->run();
} );
function pagination( array $keyboard ): array
{
if ( count( $keyboard ) <= 10 )
return $keyboard;
$keyboards = array_chunk( $keyboard, 9 );
$size = count( $keyboards );
foreach ( $keyboards as $key => $value )
{
if ( $key > 0 and $key + 1 < $size )
$keyboards[$key][] = [ 'btn_prev_' . $key, 'btn_next_' . $key ];
else if ( $key == 0 )
$keyboards[$key][] = [ 'btn_next_' . $key ];
else if ( $key + 1 == $size )
$keyboards[$key][] = [ 'btn_prev_' . $key ];
}
return $keyboards;
}
Шаг 3: Запуск бота
Запускать Long Poll бота я буду с помощью OpenServer (более подробно о нём идёт речь в данной статье). Если у вас он установлен - достаточно нажать на флажок, запустить сервер и перейти в консоль (вкладка "Дополнительно"):
В консоли нужно прописать следующую команду:
php "D:\Бот\index.php"
Естественно, путь нужно указать свой. Его можно скопировать, нажав правой кнопкой мыши по файлу с ботом:
Шаг 4: Тестирование бота
Чтобы бот отправил меню - отправьте любое сообщение ему. Теперь можно понажимать на кнопки:
На этом всё 😎
Перед публикацией, советую ознакомится с правилами!
Нашли ошибку?
Вы можете сообщить об этом администрации.
Выделив текст нажмите CTRL+Enter