[VK BOT] Бот раздающий ключи Steam
Статьи / PHP
План по статье:
1. Подготовка (Не обязательно если вы скачаете исходник для дальнейшей работы):
- Бот для группы вк (Ссылка на статью)
- RedBeanPhp (Как скачать, установить)
2. Создание index.php для простаты записи в базу данных
- Подключение rbphp
- Создание формы в HTML
- Запись данных через rbphp
3. Написание бота:
- Создадим новую команду (Бот, дай ключ)
- Получаем ключи из базы данных и записываем в массив
- Отправляем ключ и удаляем его из базы данных
4. Настройка выдачи только одного ключа на человека (В след. доработке)
1. Приступим к подготовке))Как сделать бота для вк вы можете ознакомиться
тутМожно так же скачать архив готовый для дальнейшей работы
Скачать архивТеперь рассмотрим как установить RedBeanPhp
Официальный сайт RedBeanPHPЗайдите и скачайте от туда архив, в котором будет файл rb.php
Извлеките этот файл в папку с вашим ботом
Теперь нужно подключить базу данных через rbphp, для этого создайте файл db.php, куда впишите
<?php
require 'rb.php';
R::setup( 'mysql:host=localhost;dbname=mydatabase',
'user', 'password' );
require 'rb.php';
- отвечает за подключение redbeanphp из нашей папки
R::setup( 'mysql:host=localhost;dbname=mydatabase',
'user', 'password' )
заменяем на свои данные. Данная команда взята от
сюда2. Плавно перешли к созданию index.phpВам нужно создать простой 'html сайт', где будет одна форма и всё, но не забудьте что расширение
.php !!!!Далее можно просто скопировать код
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Add key</title>
</head>
<body>
<form action="index.php" method="POST">
<input type="text" name="steam_key" value="" placeholder="Ключ Steam игры"><br>
<button type="submit" name="add_key">Записать в бд</button>
</form>
</body>
</html>
Немного разберем код:
<form action="index.php" method="POST">
'<form>' - тэг в html
action - это показывает то, куда будет отправлен метод POST
method - если интересно, то загуглите
Далее идет
<input type="text" name="steam_key" value="" placeholder="Ключ Steam игры">
Это поле <input> с название name='steam_key', по этому названию мы далее обработаем данные которые сюда ввели
placeholder - то, что будет написано в данном поле

<button type="submit" name="add_key">Записать в бд</button>
Можно было вместо button использовать input, главное что type будет submit, который отравит нашу форму
Название name нужно для дальнейшей проверки на обработке
Приступим к php части этого кодаВ начале перед
<!DOCTYPE html>
Пропишем
<?php
require 'db.php';
$data = $_POST; //Записали данные из поста. Можно вместо $data использольвать $_POST['add_key'] и т.п. но через $data лучше выглядит))
if(isset($data['add_key'])){ // По названию кнопки определяем пришло ли наши данные из формы
if(!empty($data['steam_key'])){ //Если введенное полне не пустое то
$c_key = R::dispense( 'keys' );
$c_key->title = $data['steam_key'];
$post = R::store( $c_key );
echo "Ключ был записан )";
}else{
echo 'Вы не ввели ключ';
}
}
?>
Разберем этот код:
<?php
- Указывает на php скрипт, логично же?
require 'db.php';
- Очень важная штука, при помощи её мы подключаем и redbeanphp и базу данных. В принципе одно и тоже
if(isset($data['add_key'])){
- Здесь мы узнали, что пришла наша форма, 'add_key' это название той самой кнопки из формы
if(!empty($data['steam_key'])){
- Это означает: Если поле steam_key не является пустым
$c_key = R::dispense( 'keys' );
- Создали переменную, которая в будущем запишет все данные ниже в нашу базу под название 'keys'
$c_key->title = $data['steam_key'];
- Структура: $наша_созданная_база->строка_в_бд = нашим данным из поля
$post = R::store( $c_key );
- $post не обязательно,
R::store($c_key); записал наши данные в ту самую базу 'keys'
Без этой строки ничего не будет записываться в бдДалее просто вывели текст о успехе записи в бд
Пример после записи заполнения и отправки в бд:

3. А вот и сам ботНаписав бота, мы в
if ($data->type == 'message_new') {
}
Добавим новую команду
if ($data->type == 'message_new') {
if($cmd == 'бот ключ' || $cmd == 'стим ключ' || $cmd == 'steam ключ' || $cmd == 'steam key' || $cmd == 'бот дай ключ' || $cmd == 'бот, дай ключ'){
}
}
Но вот, почему не работает да? А ведь ваш бот еще не знает что такое $cmd
Вернемся к вашим переменным и добавим там строку
$cmd = mb_strtolower($message, 'utf-8');
mb_strtolower
- Данная команда все буквы делает маленькими, т.е. 'БоТ' станет 'бот'
В нашем случае используем после сообщения кодировку 'utf-8' т.к. обрабатываем кириллицу
Отлична, теперь давайте создадим в этой команде массив из ключей. Для это через rb получим все данные из 'keys'
$keys = [];
$db_keys = R::findAll('keys');
Первая строка - наш массив с ключами
$db_keys = R::findAll('keys');
- мы получаем все данные из базы keys
После чего обработаем полученные данные в $db_keys и запишем их в массив:
foreach ($db_keys as $key) {
$get_key = $key['title'];
$get_key_id = $key['id'];
array_push($keys, [$get_key, $get_key_id]);
}
О foreach почитайте в интернете, поясню только две строчки:
(если что это работает как цикл угу типа так)$get_key = $key['title'];
- Создали переменную, которая содержит данные из текущей строчки, под названием title
$get_key_id = $key['id'];
- Получаем id этого ключа, для удаления этого ключа из бд
array_push($keys, [$get_key, $get_key_id]);
- В наш массив добавили в конце массив с ключем и его id ([0] - ключ [1] - id)
Вот мы имеем теперь массив с нашими ключами
Теперь нам нужно выбрать рандомный ключ и вывести его.
После создадим переменную с нашим key, который мы рандомно выберем из массива:
$rand_key = array_rand($keys,1);
array_rand($массив, кол-во строк);
- при помощи этого мы вытащили из массива $keys одно значение
Теперь просто отправим ключ пользователю:
$vk->sendMessage($id, "Вот ваш ключ: {$rand_key[0]} :-)");
После чего мы должны удалить ключ из базы:
$del_key = R::load('keys', $key_steam[1]);
R::trash($del_key);
$del_key = R::load('keys', $key_steam[1];
- Мы загрузили строчку по id ключа ($key_steam - это рандомный массив с ключом и его id, а [1] - указывает на id в этом массиве
R::trash($del_key);
- Мы удалили эту строчку
В итоге у нас получилась команда:
if ($data->type == 'message_new') { // Если это новое сообщение то выполняем код указанный в условии
if($cmd == 'бот ключ' || $cmd == 'стим ключ' || $cmd == 'steam ключ' || $cmd == 'steam key' || $cmd == 'бот дай ключ' || $cmd == 'бот, дай ключ'){
$keys = [];
$db_keys = R::findAll('keys');
foreach ($db_keys as $key) {
$get_key = $key['title'];
$get_key_id = $key['id'];
array_push($keys, [$get_key, $get_key_id]);
}
$rand_key = array_rand($keys,1);
$key_steam = $keys[$rand_key];
$vk->sendMessage($id, "Вот ваш ключ: {$key_steam[0]} :-)");
$del_key = R::load('keys', $key_steam[1]);
R::trash($del_key);
}
}
4. А теперь сделаем ограничение по ключам.Один человек может взять только 2 ключа.
!Внимание: сейчас закрываем глаза на код, связанный с выдачей ключа, и перед ним (т.е. после проверки на команду) прописываем
Для этого нам нужно проверить, есть ли в нашей базе пользователь с $id, если нет, то создадим нового:
$vk_user = R::findOne('users', 'user_id = ?', [$id]);
if(!$vk_user){
$new_user = R::dispense('users');
$new_user->user_id = $id;
$new_user->keys = 1;
R::store($new_user);
}
$vk_user = R::findOne('users', 'user_id = ?', [$id]);
- создали переменную которая хранит данные (ну или не хранит) о пользователи в бд (т.е. если найдет такого)
Далее проверим, если не пусто, то создаем нового пользователя со столбцами user_id - ID пользователя ВК, keys - кол-во взятых ключей (ставим 1, т.к. создали нового пользователя и он сразу берет ключ)
Вот мы узнали пользователя или создали нового, далее надо проверить, сколько ключей он взял:
if($vk_user->keys >= 2){
$vk->sendMessage($id, "Вы взяли максимальное кол-во ключей");
}
В данном случае проверяем, если пользователь взял более (ваше число, у меня 2), то напишем ему об этом и закончим действие, для чего после } пропишем else и откроем {
!Внимание: тут будет находиться код отправки ключа, но также допишем внутри прибавление числа в бд (ну то есть кол-во взятых ключей)Получаем:else{
$keys = [];
$db_keys = R::findAll('keys');
foreach ($db_keys as $key) {
$get_key = $key['title'];
$get_key_id = $key['id'];
array_push($keys, [$get_key, $get_key_id]);
}
$rand_key = array_rand($keys,1);
$key_steam = $keys[$rand_key];
$vk->sendMessage($id, "Вот ваш ключ: {$key_steam[0]} :-)");
$del_key = R::load('keys', $key_steam[1]);
R::trash($del_key);
$vk_user->keys = $vk_user->keys + 1;
R::store($vk_user);
}
Тут главное прописать прибавление в самом конце, т.к. если новый пользователь, то мы будет приписывать число в пустую переменную!
$vk_user->keys = $vk_user->keys + 1;
В данном случае мы взяли найденную переменную, обратились к столбцу Keys и добавили ему 1 ключ
После чего через R::store мы обновили данные в бд
P.S. Это моя первая статья, надеюсь не будете сильно ругать, но укажите на мои косяки)

Вот что получилось, ниже находятся полные скрипты:
1. db.php где находится подключение к redbeanPHP и базе данных:
<?php
require 'rb.php';
R::setup( 'mysql:host=localhost;dbname=db-name',
'user', 'password' );
2. Код странички index.php
<?php
require 'db.php';
$data = $_POST; //Записали данные из поста. Можно вместо $data использольвать $_POST['add_key'] и т.п. но через $data лучше выглядит))
if(isset($data['add_key'])){ // По названию кнопки определяем пришло ли наши данные из формы
if(!empty($data['steam_key'])){ //Если введенное полне не пустое то
$c_key = R::dispense( 'keys' );
$c_key->title = $data['steam_key'];
$post = R::store( $c_key );
echo "Ключ был записан )";
}else{
echo 'Вы не ввели ключ';
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Add key</title>
</head>
<body>
<form action="index.php" method="POST">
<input type="text" name="steam_key" value="" placeholder="Ключ Steam игры"><br>
<button type="submit" name="add_key">Записать в бд</button>
</form>
</body>
</html>
3. Код самого бота:
<?php
require 'db.php';
include "vk_api.php";
const VK_KEY = "Длинный ключ";
const ACCESS_KEY = "Ключ проверки";
const VERSION = "5.81";
$vk = new vk_api(VK_KEY, VERSION);
$data = json_decode(file_get_contents('php://input')); //Получает и декодирует JSON пришедший из ВК
if ($data->type == 'confirmation') { //Если vk запрашивает ключ
exit(ACCESS_KEY); //Завершаем скрипт отправкой ключа
}
$vk->sendOK();
$id = $data->object->from_id; // Узнаем ид пользователя который отправляет команду ()
$message = $data->object->text; // Текст самого сообщения
$cmd = mb_strtolower($message, 'utf-8'); // при помощи mb_strtolower мы сообщение типа 'БОТ КЛЮЧ' преобразовали в 'бот ключ'
if ($data->type == 'message_new') { // Если это новое сообщение то выполняем код указанный в условии
if($cmd == 'бот ключ' || $cmd == 'стим ключ' || $cmd == 'steam ключ' || $cmd == 'steam key' || $cmd == 'бот дай ключ' || $cmd == 'бот, дай ключ'){
$vk_user = R::findOne('users', 'user_id = ?', [$id]);
if(!$vk_user){
$new_user = R::dispense('users');
$new_user->user_id = $id;
$new_user->keys = 1;
R::store($new_user);
}
if($vk_user->keys >= 2){
$vk->sendMessage($id, "Вы взяли максимальное кол-во ключей");
}else{
$keys = [];
$db_keys = R::findAll('keys');
foreach ($db_keys as $key) {
$get_key = $key['title'];
$get_key_id = $key['id'];
array_push($keys, [$get_key, $get_key_id]);
}
$rand_key = array_rand($keys,1);
$key_steam = $keys[$rand_key];
$vk->sendMessage($id, "Вот ваш ключ: {$key_steam[0]} :-)");
$del_key = R::load('keys', $key_steam[1]);
R::trash($del_key);
$vk_user->keys = $vk_user->keys + 1;
R::store($vk_user);
}
}
}
4. На всякий кидаю код vk_api.php (не ну а в друг вы не можете скачать):
<?php
class vk_api{
/**
* Токен
* @var string
*/
private $token = '';
private $v = '';
/**
* @param string $token Токен
*/
public function __construct($token, $v){
$this->token = $token;
$this->v = $v;
}
/**
* Отправить сообщение пользователю
* @param int $sendID Идентификатор получателя
* @param string $message Сообщение
* @return mixed|null
*/
public function sendDocMessage($sendID, $id_owner, $id_doc){
if ($sendID != 0 and $sendID != '0') {
return $this->request('messages.send',array('attachment'=>"doc". $id_owner . "_" . $id_doc,'user_id'=>$sendID));
} else {
return true;
}
}
public function sendMessage($sendID,$message){
if ($sendID != 0 and $sendID != '0') {
return $this->request('messages.send',array('message'=>$message, 'peer_id'=>$sendID));
} else {
return true;
}
}
public function sendOK(){
echo 'ok';
$response_length = ob_get_length();
// check if fastcgi_finish_request is callable
if (is_callable('fastcgi_finish_request')) {
/*
* This works in Nginx but the next approach not
*/
session_write_close();
fastcgi_finish_request();
return;
}
ignore_user_abort(true);
ob_start();
$serverProtocole = filter_input(INPUT_SERVER, 'SERVER_PROTOCOL', FILTER_SANITIZE_STRING);
header($serverProtocole.' 200 OK');
header('Content-Encoding: none');
header('Content-Length: '. $response_length);
header('Connection: close');
ob_end_flush();
ob_flush();
flush();
}
public function sendButton($sendID, $message, $gl_massiv = [], $one_time = False) {
$buttons = [];
$i = 0;
foreach ($gl_massiv as $button_str) {
$j = 0;
foreach ($button_str as $button) {
$color = $this->replaceColor($button[2]);
$buttons[$i][$j]["action"]["type"] = "text";
if ($button[0] != null)
$buttons[$i][$j]["action"]["payload"] = json_encode($button[0], JSON_UNESCAPED_UNICODE);
$buttons[$i][$j]["action"]["label"] = $button[1];
$buttons[$i][$j]["color"] = $color;
$j++;
}
$i++;
}
$buttons = array(
"one_time" => $one_time,
"buttons" => $buttons);
$buttons = json_encode($buttons, JSON_UNESCAPED_UNICODE);
//echo $buttons;
return $this->request('messages.send',array('message'=>$message, 'peer_id'=>$sendID, 'keyboard'=>$buttons));
}
public function sendDocuments($sendID, $selector = 'doc'){
if ($selector == 'doc')
return $this->request('docs.getMessagesUploadServer',array('type'=>'doc','peer_id'=>$sendID));
else
return $this->request('photos.getMessagesUploadServer',array('peer_id'=>$sendID));
}
public function saveDocuments($file, $titile){
return $this->request('docs.save',array('file'=>$file, 'title'=>$titile));
}
public function savePhoto($photo, $server, $hash){
return $this->request('photos.saveMessagesPhoto',array('photo'=>$photo, 'server'=>$server, 'hash' => $hash));
}
/**
* Запрос к VK
* @param string $method Метод
* @param array $params Параметры
* @return mixed|null
*/
public function request($method,$params=array()){
$url = 'https://api.vk.com/method/'.$method;
$params['access_token']=$this->token;
$params['v']=$this->v;
if (function_exists('curl_init')) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type:multipart/form-data"
));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$result = json_decode(curl_exec($ch), True);
curl_close($ch);
} else {
$result = json_decode(file_get_contents($url, true, stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'content' => http_build_query($params)
)
))), true);
}
if (isset($result['response']))
return $result['response'];
else
return $result;
}
private function replaceColor($color) {
switch ($color) {
case 'red':
$color = 'negative';
break;
case 'green':
$color = 'positive';
break;
case 'white':
$color = 'default';
break;
case 'blue':
$color = 'primary';
break;
default:
# code...
break;
}
return $color;
}
private function sendFiles($url, $local_file_path, $type = 'file') {
$post_fields = array(
$type => new CURLFile(realpath($local_file_path))
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type:multipart/form-data"
));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
$output = curl_exec($ch);
return $output;
}
public function sendImage($id, $local_file_path)
{
$upload_url = $this->sendDocuments($id, 'photo')['upload_url'];
$answer_vk = $this->sendFiles($upload_url, $local_file_path, 'photo');
$upload_file = $this->savePhoto($answer_vk[0]['photo'], $answer_vk[0]['server'], $answer_vk[0]['hash']);
$this->request('messages.send', array('attachment' => "photo" . $upload_file[0]['owner_id'] . "_" . $upload_file[0]['id'], 'peer_id' => $id));
return 1;
}
}