Dialog telegram bot in PHP

    On this subject many articles on Habré and simply on the Internet are written . And I will tell about my experience with the telegram bot and moments that could not be solved “in the forehead”.

    Bot creation


    The first thing you need to start with is creating a bot. There is official documentation and steps are detailed there.

    If nothing is clear in the described instructions, here is a step-by-step instruction
    1. We find BotFather in the telegram of the bot and add a contact list to ourselves
    2. look at the available bot commands using the / help command


    3. we select / newbot and then, following the instructions, we perform the necessary actions (the next picture is taken from google)




    After creating the bot, you will receive a token that you will need to use in the code of your bot, so the message with the token must be saved.

    We connect the bot with the application \ site


    The fun begins, and it was here that I ran into the first problem.
    First of all, we select the php library for creating the bot. I opted for this library , as it seemed to me the most convenient.

    After connecting the library, you need to organize the interaction of the bot with your site \ application. You can organize this interaction using webhooks .

    A webhook is a kind of relay that will send all requests from the bot to the address specified during the registration of the webhook. Registering a webhook is very simple, you just need to send a request of the form https: //api.telegram.org/bot~token~/setWebhook?url=https: //example.ru/path , where
    https: //example.ru/- this is a link to your site where the bot will redirect requests.
    ~ token ~ is the token that you received when registering your bot.
    path is the part of the url to which calls will come.

    And this is where the problem arises. It turns out a webhook can only be registered if the site is on https. If your site is on http, then you won’t be able to register a webhook.

    But there is a way out if you do not want to buy a certificate
    You can use the Let's Encrypt service.
    Go to the getting startted section and follow the instructions.

    Writing a bot code


    Now let's start programming. After the relationship is organized, you can begin to write the logic of our bot.

    Telegram developers, in order to make it easier for users to work with bots, ask all developers to implement support for the following commands:

    / start - starts communication with the user (for example, sends a greeting message). You can also pass additional arguments to this command.
    / help - displays a message using command prompts. It can be a short message about your bot and a list of available commands.

    All we need to do is write the following code in the controller of your application / site:

    $token = "токен";
    $bot = new \TelegramBot\Api\Client($token);
    // команда для start
    $bot->command('start', function ($message) use ($bot) {
        $answer = 'Добро пожаловать!';
        $bot->sendMessage($message->getChat()->getId(), $answer);
    });
    // команда для помощи
    $bot->command('help', function ($message) use ($bot) {
        $answer = 'Команды:
    /help - вывод справки';
        $bot->sendMessage($message->getChat()->getId(), $answer);
    });
    $bot->run();
    

    Now if you write / help in the telegram window of the bot, the text will be displayed:

    Commands:
    / help - help output


    Well, we wrote a list of recommended commands. Then we can implement the commands we need.

    Since teams can take arguments, we use this opportunity. For example, we will make our bot respond to the hello Vasya command with a message: Hello, Vasya.

    To do this, write the following code:

    $bot->command('hello', function ($message) use ($bot) {
        $text = $message->getText();
        $param = str_replace('/hello ', '', $text);
        $answer = 'Неизвестная команда';
        if (!empty($param))
        {
        	$answer = 'Привет, ' . $param;
        }
        $bot->sendMessage($message->getChat()->getId(), $answer);
    });

    It turns out everything is very simple and fast.

    Enter the list of bot commands


    In order for the bot to be able to provide online help



    , the BotFather bot needs to report a list of commands.
    You can do this with his / setcommands command

    Bicycle


    The option described above is not entirely convenient, because I do not want to drive text after the command, because if you use the tips from the bot, then this is completely unrealistic.

    So you need to make the bot remember the command that you enter. This can be done using any repository (MySQL, memcached, redis, tarantool, Postgres, etc)
    All that is needed is to remember the previous user input.

    To do this, before sending the message to the user, place it in your repository, and before accepting the message, check if the data is in the repository. And if there is, then based on these data to build further logic.

    Here at this stage, I again had difficulty, since I did not find in the library the opportunity to get a command before calling the command method. Also, I did not like the fact that all the logic would be locked within one application controller.

    It was decided to write your own data processor, with the ability to move each command to a separate application controller.

    First, we describe the entry point to the controller

    function main()
    {
    	$telegram = new Telegram();
    	// подключаем хранилище
    	$storage = new Storage();
    	// получаем объект сообщения
    	$message = $telegram->getMessage();
    	// получаем команду, если ее передали
    	$command = $message->getCommand();
    	// получаем текст, если его передали (тут лежит все, что не является командой)
    	$text = $message->getParams($command);
    	// если команда пустая, то мы проверяем, есть ли у пользователя на предыдущем шаге вызов команды и восстановливаем ее
    	if (empty($command))
    	{
    	  $command = $storage->restoreCommand($message->getChat()->getId());
    	}
    	// запоминаем команду, котрую ввел пользователь
    	$storage->storeCommand(
    	    $message->getChat()->getId(),
    	    $command
    	);
    	// логика подключения нашего метода для котроллера
    	$this->chooseMethod($command, $message, $text);
    }

    Now consider one of the methods.

    function getnewtext(Message $telegram, $text)
    {
    	// если не передали текст, то выведем сообщение с разъяснением
    	if (empty($text))
    	{
    	  $answer = "Введите слово или несколько слов для поиска. Именно по ним будет происходить поиск 5 свежих новостей.";
    	  $telegram->sendMessage($telegram->getChat()->getId(), $answer);
    	}
    	else
    	{
    		// основаня логика
    		$tgNews = new TelegramNews();
    		$arData = $tgNews->getByWord($text, 'new');
    		if (empty($arData))
    		{
    			$answer = 'Ничего не найдено';
    		}
    		else
    		{
    			$answer = common_setViewGetContent('telegram/get', [
    			    'data' => $arData
    			]);
    		}
    		$telegram->sendMessage($telegram->getChat()->getId(), $answer);
    	}
    }

    So it has become much more enjoyable, interactive and convenient.



    Thank you for reading the article to the end. You can play with a live bot that works in dialogue mode here .

    UPD: the ability to send photos to some types of requests has been added to the bot. For example, on
    / gettable - returns the resulting table of sporting events
    / getevents - returns events of sporting events

    Also popular now: