How to create a bot in vk or VK Callback API

Hello! Recently, on one project, I had to come across a VK bot that “lives” in group messages. Prior to that, I had the most diverse experience in creating bots from personal pages. In order for the bot to be able to respond normally to messages, one had to do all kinds of perversions with crowns, timers, “remembering” messages and other various horrors.
How surprised I was when I started smoking VK API groups with regards to messages, I saw this miracle - Callback API.

For impatient or loving to deal with everything on their own at the end there is a ready-made example.

The article is not intended for beginners at all, and I did not drastically delay it, especially omitting the chewing of very obvious things, otherwise it would be a very huge article. The subject of writing bots in general is not a very new topic.




For those who do not know what it is, I will tell you briefly.
With the help of this chip, VC itself automatically sends requests in the JSON format, where we specify ourselves.
About the JSON format, I wrote a little info in the article about creating authorization through VK

So, in this callback request, VK can notify about everything: new group messages, outgoing messages from the group, videos, audio, comments, new subscribers, and so on. And having read this request, we can decide how to respond to this request.
Just like payment systems. Magic.

Let's go in order. In order to use the callback api to create a bot or something else, you need:

First, of course, create a group.
Open the "Community Management" section, in which on the right there is such a menu:

We choose to work with the API, where we have all the settings.

First of all, you need to create an API key, which is immediately desirable to be written somewhere, because to display it again, you will need to receive a text message on the phone.
Above is a tab with the Callback API.

Open it and see what is there. You can immediately specify “Incoming message” in the event types, we don’t touch the rest yet, otherwise they will unnecessarily strain the server, both VK and yours.

I propose to do this:
Let the bot respond to messages with the same message that was sent to him, only back to front, ahah

First, let's blind two files. callback.php and vk.class.php . The class is needed purely for convenience, so as not to pile up a large pile of code in one file. Let's do it carefully ?

Looking ahead, I’ll say that you can’t specify the localhosts, the VK server simply won’t see them, for tests or even a full-fledged bot, in any case, you will have to make some kind of poor server.

Before using the callback api itself, you also have to first confirm your callback script by returning the desired line to vk. All requests from the callback will fly in JSON format (already said), and VK, as it were, shows how they will look. The first of these is confirmation, which will look something like this:

{"type":"confirmation","group_id":GROUPID}

Now we go to our callback.php , in which you first need to receive a request from VK and check what came there and immediately process it. The structure of the request sent from VK can be found in the official documentation of VK
Below is the full code of the callback.php file, which will be equipped with a ton of comments)
All the code will be simplified as much as possible, in many places on some large and serious project it’s better not to do this) You will need at least error handlers and so on, which VK can quite return to itself. It would also be desirable to use a secret key and all sorts of different

<?php
	$body = file_get_contents('php://input'); //Get the line in $body json
	$arr = json_decode($body, true); //Parse json array request into variable $arr
	
	if ($arr['type'] == 'confirmation') { //If we received a request for confirmation of the callback script, then
		exit("xxxxxxxx");  //we give back our confirmation code issued by VK and stop the script, then it doesn’t need anything
	}
	//If the script is executed further, then this is not confirmation, but one of the notifications.
	//Because at this stage we only process the incoming letter, then this is an incoming letter
	if ($arr['type'] == 'message_new') { //We’ll check, just in case, whether this incoming message is accurate
		function cir_strrev($stroka){ //Since the strrev function cannot properly flip the Cyrillic alphabet, we need a crutch through an array. Create a function
			preg_match_all('/./us', $stroka, $array); 
			return implode('',array_reverse($array[0]));
		}
	
		//It means exactly incoming. You can already connect our class
		include_once ('vk.class.php'); //Between things we connect our vk.class.php
		
		//Immediately and create this class, which will be written a little later
		//Here we write the api key, which was created at the very beginning
		$vk = new vk('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
		
		$sms = $arr['object']['body']; //We get the text of the message that we received.
		//You can learn about the structure of this array that flew to us from VK from the official documentation. Link above to code
		
		//Immediately we get user_id, which needs to send all this back
		$vk_id = $arr['object']['user_id'];
		
		//Flip the line back and forth using the php strrev function
		$sms_rev = cir_strrev($sms);
		
		//We use our not yet written class to send a message in response
		$vk->send($vk_id, $sms_rev);
	}
	exit('ok'); //Be sure to return "ok", otherwise VK will send a notification several times

Now, actually, vk.class.php itself:

<?php
//Init Class
class VK {

	public $token = ''; //We create a public variable for the token, which must be sent every time when using api vk

	public function __construct($token) {
		$this->token = $token; //We hammer in a variable token when constructing a class
	}
	
	public function send($id, $message) {	//We set the public send function to send messages
		//We fill in the $data array with info, which we will send via api to VK. About the api function "messages.send" can be found in the official documentation vk
		$data = array( 
			'peer_id'      => $id,
			'message' 	   => $message,
			'v'            => '5.46', //Version for the function. It must be transmitted. You can find out what you need through official VK documentation
		);
		//We get the answer through the send to api function, which we will create below
		$out = $this->request('messages.send', $data);
		//And let the function return the answer. True, in this example we will not use it in any way, let there be a deposit for the future
		return $out;
	}	
	
	public  function request($method, $data = array()) {
		$curl = curl_init(); //curl-murl in a variable. It is preferable to use curl for sending, but it is also possible through file_get_contents if the server does not support
		
		$data['access_token'] = $this->token; //the token to be sent along with the request also needs to be added to the date

		curl_setopt($curl, CURLOPT_URL, 'https://api.vk.com/method/' . $method); //Links to different api-vk methods look like this: https://api.vk.com/method/I_TUT_SAM_METHOD, so the method can be completely hammered into this function without any links
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST'); //Send via POST
		curl_setopt($curl, CURLOPT_POST, true);
		curl_setopt($curl, CURLOPT_POSTFIELDS, $data); //The data itself is sent
		
		$out = json_decode(curl_exec($curl), true); //We get the execution result, which we immediately decrypt from JSON into an array for convenience
		
		curl_close($curl);
		
		return $out; //Send the response as an array
	}
}