Настройка Callback API для бота сообщества ВКонтакте
Подготовка серверной части к подключению
Callback API — это инструмент для отслеживания активности пользователей в Вашем сообществе ВКонтакте. С его помощью Вы можете реализовать новые полезные функции, например:
- Бота для отправки мгновенных ответов на поступающие сообщения.
- Систему автоматической модерации контента.
- Сервис для сбора и обработки показателей вовлеченности аудитории.
Чтобы начать использовать Callback API, подключите свой сервер в настройках сообщества и выберите типы событий, данные о которых требуется получать (например, новые комментарии и новые фотографии). Когда в сообществе произойдет событие выбранного типа, ВКонтакте отправит на Ваш сервер запрос в формате JSON с основной информацией об объекте, вызвавшем событие (например, добавленный комментарий). Вам больше не нужно делать регулярные запросы к API, чтобы отслеживать обновления — теперь Вы будете получать их мгновенно.
Инструкция по подключению подробно описана в отличной документации для разработчиков ВКонтакте.
Разберем её подробнее, для размещения скрипта чат-бота мы должны иметь функционирующий веб-сервер.
Для работы с callback API ВКонтакте рекомендует использовать протокол https, инструкцию по бесплатному получению сертификата cloudflare и настройки сервера вы сможете найти в статье, которую можно найти в поисковой системе Google по запросу Бесплатный SSL сертификат CloudFlare.
По окончании настройки сервера вы должны иметь рабочий web-сервер, на который мы загрузим скрипт нашего бота.
Настройка сообщества ВКонтакте
Генерация ключа доступа
Важным моментом в работе бота сообщества являются ответы на пользовательские сообщения и различные события, для того, чтобы мы могли взаимодействовать с пользователем от имени сообщества, нам необходимо создать специальный ключ. Для этого перейдем во вкладку "Управление сообществом".

Далее спустимся в раздел "Работа с API" > "Ключи доступа".

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

В нашем случае нам хватит доступа к сообщениям сообщества.

Сохраним данный ключ, он нам понадобится при настройке backend.
Настройка callback API
Теперь мы должны связать наш сервер и сообщество, для этого мы должны указать данные нашего сервера и создать секретный ключ. Для этого нам необходимо перейти в раздел управления сообщества и спуститься во вкладку "Работа с API".

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

Введем секретный ключ и нажимаем «Сохранить», после мы должны получить соответствующее уведомление о успешной установке ключа. Кнопку «Подтвердить» напротив поля с адресом сервера не нажимаем.
Заданный Вами секретный ключ будет передаваться с каждым уведомлением от сервера в отдельном поле secret. Это позволит Вам достоверно определять, что уведомление пришло именно от нашего сервера.

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

Настройка типов событий
Важным моментом в работе бота сообщества, является ответы на пользовательские сообщения и различные события, для того, чтобы мы могли взаимодействовать с пользователем от имени сообщества, нам необходимо указать какие именно события мы хотим получать. Так как мы собираемся отслеживать входящие сообщения, вступления в сообщества и выход из него, то нам необходимо установить соответствующие галочки. Для этого перейдем во вкладку "Управление сообществом".

Далее спустимся в раздел "Работа с API" > "Типы событий".


Установите необходимые пункты в данном разделе.
Настройка backend бота ВКонтакте
Следующим этапом мы должны создать специальный скрипт, который будем принимать запросы от callback API вконтакте и определенным образом реагировать на события. Создадим, например, php-скрипт handler.php, адрес к этом скрипту, после настройки backend, мы должны указать в настройках сообщества.
Обратите внимание на значения следующих переменных:
$confirmationToken $token $secretKey
В confirmationToken хранится код, которые сервер должен вернуть, в нашем случае:
004eec27
token хранит в себе ключ доступа, который мы генерировали в главе «Генерация ключа доступа»
secretKey мы задавали в разделе управления сообщества callback API. Итоговый код выглядит следующим образом (handler.php):
<?php
if (!isset($_REQUEST)) {
return;
}
//Строка для подтверждения адреса сервера из настроек Callback API
$confirmationToken = '004eec27';
//Ключ доступа сообщества
$token = 'Ваш ключ';
// Secret key
$secretKey = 'testSecureKey';
//Получаем и декодируем уведомление
$data = json_decode(file_get_contents('php://input'));
// проверяем secretKey
if(strcmp($data->secret, $secretKey) !== 0 && strcmp($data->type, 'confirmation') !== 0)
return;
//Проверяем, что находится в поле "type"
switch ($data->type) {
//Если это уведомление для подтверждения адреса сервера...
case 'confirmation':
//...отправляем строку для подтверждения адреса
echo $confirmationToken;
break;
//Если это уведомление о новом сообщении...
case 'message_new':
//...получаем id его автора
$userId = $data->object->user_id;
//затем с помощью users.get получаем данные об авторе
$userInfo = json_decode(file_get_contents("https://api.vk.com/method/users.get?user_ids={$userId}&v=5.0"));
//и извлекаем из ответа его имя
$user_name = $userInfo->response[0]->first_name;
//С помощью messages.send и токена сообщества отправляем ответное сообщение
$request_params = array(
'message' => "{$user_name}, ваше сообщение зарегистрировано!<br>".
"Мы постараемся ответить в ближайшее время.",
'user_id' => $userId,
'access_token' => $token,
'v' => '5.0'
);
$get_params = http_build_query($request_params);
file_get_contents('https://api.vk.com/method/messages.send?' . $get_params);
//Возвращаем "ok" серверу Callback API
echo('ok');
break;
// Если это уведомление о вступлении в группу
case 'group_join':
//...получаем id нового участника
$userId = $data->object->user_id;
//затем с помощью users.get получаем данные об авторе
$userInfo = json_decode(file_get_contents("https://api.vk.com/method/users.get?user_ids={$userId}&v=5.0"));
//и извлекаем из ответа его имя
$user_name = $userInfo->response[0]->first_name;
//С помощью messages.send и токена сообщества отправляем ответное сообщение
$request_params = array(
'message' => "Добро пожаловать в наше сообщество МГТУ им. Баумана ИУ5 2016, {$user_name}!<br>" .
"Если у Вас возникнут вопросы, то вы всегда можете обратиться к администраторам сообщества.<br>" .
"Их контакты можно найти в соответсвующем разделе группы.<br>" .
"Успехов в учёбе!",
'user_id' => $userId,
'access_token' => $token,
'v' => '5.0'
);
$get_params = http_build_query($request_params);
file_get_contents('https://api.vk.com/method/messages.send?' . $get_params);
//Возвращаем "ok" серверу Callback API
echo('ok');
break;
}
?>
После того как вы загрузите код, вы должны вернуться в раздел «Управление сообществом» > «Работа с API» > «Callback API», ввести адрес до скрипта и нажать «Подтвердить»

После этого, конфигурация сообщества для работы с ботом завершена, теперь, если мы отправим сообщением в сообщество, мы получим ответ.

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

Мы будем отлавливать событие group_join, для этого в операторе switch создадим новый раздел. Мы не будем рассматривать join_type подробно, так как у нас открытая группа, но вы можете обрабатывать этот параметр на ваше усмотрение.
// Если это уведомление о вступлении в группу
case 'group_join':
//...получаем id нового участника
$userId = $data->object->user_id;
//затем с помощью users.get получаем данные об авторе
$userInfo = json_decode(file_get_contents("https://api.vk.com/method/users.get?user_ids={$userId}&v=5.0"));
//и извлекаем из ответа его имя
$user_name = $userInfo->response[0]->first_name;
//С помощью messages.send и токена сообщества отправляем ответное сообщение
$request_params = array(
'message' => "Добро пожаловать в наше сообщество МГТУ им. Баумана ИУ5 2016, {$user_name}!<br>" .
"Если у Вас возникнут вопросы, то вы всегда можете обратиться к администраторам сообщества.<br>" .
"Их контакты можно найти в соответсвующем разделе группы.<br>" .
"Успехов в учёбе!",
'user_id' => $userId,
'access_token' => $token,
'v' => '5.0'
);
$get_params = http_build_query($request_params);
file_get_contents('https://api.vk.com/method/messages.send?' . $get_params);
//Возвращаем "ok" серверу Callback API
echo('ok');
break;

Полный код обработчика бота ВКонтакте с функцией приветственного сообщения:
<?php
if (!isset($_REQUEST)) {
return;
}
//Строка для подтверждения адреса сервера из настроек Callback API
$confirmationToken = '004eec27';
//Ключ доступа сообщества
$token = 'Ваш ключ';
// Secret key
$secretKey = 'testSecureKey';
//Получаем и декодируем уведомление
$data = json_decode(file_get_contents('php://input'));
// проверяем secretKey
if(strcmp($data->secret, $secretKey) !== 0 && strcmp($data->type, 'confirmation') !== 0)
return;
//Проверяем, что находится в поле "type"
switch ($data->type) {
//Если это уведомление для подтверждения адреса сервера...
case 'confirmation':
//...отправляем строку для подтверждения адреса
echo $confirmationToken;
break;
//Если это уведомление о новом сообщении...
case 'message_new':
//...получаем id его автора
$userId = $data->object->user_id;
//затем с помощью users.get получаем данные об авторе
$userInfo = json_decode(file_get_contents("https://api.vk.com/method/users.get?user_ids={$userId}&v=5.0"));
//и извлекаем из ответа его имя
$user_name = $userInfo->response[0]->first_name;
//С помощью messages.send и токена сообщества отправляем ответное сообщение
$request_params = array(
'message' => "{$user_name}, ваше сообщение зарегистрировано!<br>".
"Мы постараемся ответить в ближайшее время.",
'user_id' => $userId,
'access_token' => $token,
'v' => '5.0'
);
$get_params = http_build_query($request_params);
file_get_contents('https://api.vk.com/method/messages.send?' . $get_params);
//Возвращаем "ok" серверу Callback API
echo('ok');
break;
// Если это уведомление о вступлении в группу
case 'group_join':
//...получаем id нового участника
$userId = $data->object->user_id;
//затем с помощью users.get получаем данные об авторе
$userInfo = json_decode(file_get_contents("https://api.vk.com/method/users.get?user_ids={$userId}&v=5.0"));
//и извлекаем из ответа его имя
$user_name = $userInfo->response[0]->first_name;
//С помощью messages.send и токена сообщества отправляем ответное сообщение
$request_params = array(
'message' => "Добро пожаловать в наше сообщество МГТУ им. Баумана ИУ5 2016, {$user_name}!<br>" .
"Если у Вас возникнут вопросы, то вы всегда можете обратиться к администраторам сообщества.<br>" .
"Их контакты можно найти в соответсвующем разделе группы.<br>" .
"Успехов в учёбе!",
'user_id' => $userId,
'access_token' => $token,
'v' => '5.0'
);
$get_params = http_build_query($request_params);
file_get_contents('https://api.vk.com/method/messages.send?' . $get_params);
//Возвращаем "ok" серверу Callback API
echo('ok');
break;
}
?>
Реализация прощания с участником после того, как он покинул сообщество
Реализация идентичная, в конкретном случае мы обрабатываем group_leave
// Если это уведомление о выходе из группы
case 'group_leave':
//...получаем id ушедшего участника
$userId = $data->object->user_id;
//затем с помощью users.get получаем данные об авторе
$userInfo = json_decode(file_get_contents("https://api.vk.com/method/users.get?user_ids={$userId}&v=5.0"));
//и извлекаем из ответа его имя
$user_name = $userInfo->response[0]->first_name;
//С помощью messages.send и токена сообщества отправляем ответное сообщение
$request_params = array(
'message' => "{$user_name}, нам очень жаль прощаться с вами 😔<br>" .
"Мы всегда будем ждать Вас в нашей уютной компании.<br>" .
"Если возникли вопросы - свяжитесь с администратором сообщества<br>" .
"Константин - https://vk.com/kulakovkostya",
'user_id' => $userId,
'access_token' => $token,
'v' => '5.0'
);
$get_params = http_build_query($request_params);
file_get_contents('https://api.vk.com/method/messages.send?' . $get_params);
//Возвращаем "ok" серверу Callback API
echo('ok');
break;
Полный листинг кода:
<?php
if (!isset($_REQUEST)) {
return;
}
//Строка для подтверждения адреса сервера из настроек Callback API
$confirmationToken = '004eec27';
//Ключ доступа сообщества
$token = 'Ваш ключ';
// Secret key
$secretKey = 'testSecureKey';
//Получаем и декодируем уведомление
$data = json_decode(file_get_contents('php://input'));
// проверяем secretKey
if(strcmp($data->secret, $secretKey) !== 0 && strcmp($data->type, 'confirmation') !== 0)
return;
//Проверяем, что находится в поле "type"
switch ($data->type) {
//Если это уведомление для подтверждения адреса сервера...
case 'confirmation':
//...отправляем строку для подтверждения адреса
echo $confirmationToken;
break;
//Если это уведомление о новом сообщении...
case 'message_new':
//...получаем id его автора
$userId = $data->object->user_id;
//затем с помощью users.get получаем данные об авторе
$userInfo = json_decode(file_get_contents("https://api.vk.com/method/users.get?user_ids={$userId}&v=5.0"));
//и извлекаем из ответа его имя
$user_name = $userInfo->response[0]->first_name;
//С помощью messages.send и токена сообщества отправляем ответное сообщение
$request_params = array(
'message' => "{$user_name}, ваше сообщение зарегистрировано!<br>".
"Мы постараемся ответить в ближайшее время.",
'user_id' => $userId,
'access_token' => $token,
'v' => '5.0'
);
$get_params = http_build_query($request_params);
file_get_contents('https://api.vk.com/method/messages.send?' . $get_params);
//Возвращаем "ok" серверу Callback API
echo('ok');
break;
// Если это уведомление о вступлении в группу
case 'group_join':
//...получаем id нового участника
$userId = $data->object->user_id;
//затем с помощью users.get получаем данные об авторе
$userInfo = json_decode(file_get_contents("https://api.vk.com/method/users.get?user_ids={$userId}&v=5.0"));
//и извлекаем из ответа его имя
$user_name = $userInfo->response[0]->first_name;
//С помощью messages.send и токена сообщества отправляем ответное сообщение
$request_params = array(
'message' => "Добро пожаловать в наше сообщество МГТУ им. Баумана ИУ5 2016, {$user_name}!<br>" .
"Если у Вас возникнут вопросы, то вы всегда можете обратиться к администраторам сообщества.<br>" .
"Их контакты можно найти в соответсвующем разделе группы.<br>" .
"Успехов в учёбе!",
'user_id' => $userId,
'access_token' => $token,
'v' => '5.0'
);
$get_params = http_build_query($request_params);
file_get_contents('https://api.vk.com/method/messages.send?' . $get_params);
//Возвращаем "ok" серверу Callback API
echo('ok');
break;
// Если это уведомление о выходе из группы
case 'group_leave':
//...получаем id ушедшего участника
$userId = $data->object->user_id;
//затем с помощью users.get получаем данные об авторе
$userInfo = json_decode(file_get_contents("https://api.vk.com/method/users.get?user_ids={$userId}&v=5.0"));
//и извлекаем из ответа его имя
$user_name = $userInfo->response[0]->first_name;
//С помощью messages.send и токена сообщества отправляем ответное сообщение
$request_params = array(
'message' => "{$user_name}, нам очень жаль прощаться с вами 😔<br>" .
"Мы всегда будем ждать Вас в нашей уютной компании.<br>" .
"Если возникли вопросы - свяжитесь с администратором сообщества<br>" .
"Константин - https://vk.com/kulakovkostya",
'user_id' => $userId,
'access_token' => $token,
'v' => '5.0'
);
$get_params = http_build_query($request_params);
file_get_contents('https://api.vk.com/method/messages.send?' . $get_params);
//Возвращаем "ok" серверу Callback API
echo('ok');
break;
}
?>
Исходный код на GitHub: github.com/KostyaKulakov/vksocialbot
Комментарии (14)
YDombrovsky
22.05.2017 09:07+2Листинг кода на GitHub лучше выложить
KostyaKulakov
22.05.2017 09:19Спасибо, добавил ссылку на репозиторий в конец туториала.
OsAlex
22.05.2017 11:29Существует ли возможность организации общения бота от имени пользователя, а не группы?
KostyaKulakov
22.05.2017 11:33Да, такая возможность существует, но её реализация отличается от рассмотренной в туториале.
KazinPro
22.05.2017 12:13Так это же просто перепечатанный help…
ТыцKostyaKulakov
22.05.2017 12:18-1Алексей, спасибо за комментарий. В данном туториале были произведены доработки кода, например, добавлена проверка secureKey, в примере расширенного функционала рассмотрены часто используемые приемы, которых нет в готовом виде в официальной документации. Одной из немаловажной особенностью данного туториала является то, что все шаги настройки и подготовки рассмотрены на действующем сообществе с реальными задачами.
KazinPro
22.05.2017 14:31+1Все равно спасибо за эту статью. Взял на вооружение.
Будут ли примеры реализации остальных разделов?
Работа со стеной, комментами и т.д.
berezuev
22.05.2017 12:47-2Короче, авторы, вот вам тема для идеального поста:
Пишем чат-бота для Telegram на React.js с публикацией на Amazon S3 через Docker.
Sho0ter
22.05.2017 16:57+1По поводу сообщения при событии group_join:
901 Нельзя первым писать пользователю от имени сообщества.
Документация messages.send
Flagman
В последнее время столько статей про ботов для ВК, что, видимо, скоро там будут одни боты :)
HunterNNm
Может эти статьи тоже уже боты пишут?
TimsTims
Не мешайте свободе слова! Возможно, именно в этот момент, где-нибудь в Африке находится одинокий бот, который очень хочет, но не знает как, поселиться ВКонтакте!
Kriger91
Или ближе :)
kot2566
Можно ссылки на эти статьи?