A simple Telegram bot that asks 1 question

gimp creativity
gimp creativity

The main idea of ​​the bot is to counter spam - registrations in the Telegram group.





Below I will tell you about the process of creating a Telegram bot that performs a simple function - asks a new user of the group a question and provides an opportunity to choose an answer to it.





For everyone who wants to see the code at once and in full - welcome to the end of the article (there are links there)





Tools

  • PHP 7.4





  • Laminas Framework (formerly Zend Framework)





  • Php-telegram-bot / core library





  • Documentation from the official Telegram website





  • Created bot via @BotFather in your messenger





  • Postman - for testing without resorting to a smartphone





  • Docker ( )





  • ( )





. , . Telegram.





, - Combot, Terminator ( , ) .





  1. (, -, )





  2. ( ) — . ( ?). — « » « ». .





  3. - « » , , .





  4. , backend .





  5. — « », .





  6. - , , « »





json- Telegram URL (webhook) .





Free enough picture of the scheme

backend Telegram, Telegram. — ( ).





Telegram API PHP

  1. danog/MadelineProto — , , «».





  2. php-telegram-bot/core — , . , xdebug-





php-telegram-bot/core

«» class Longman\TelegramBot\Telegram. json- - .





Longman\TelegramBot\Telegram , ( ).





, , Interop\Container\ContainerInterface Laminas .





-

( Laminas)









<?php
use Longman\TelegramBot\Commands\SystemCommand;
use Longman\TelegramBot\Entities\ServerResponse;
use Longman\TelegramBot\Request;

class GenericmessageCommand extends SystemCommand
{
    /**
     * @var string
     */
    protected $name = 'genericmessage';
    
    protected $description = 'Handle generic message';
    
    protected $version = '1.0.0';
    
    public function execute(): ServerResponse
    {
        /** @var \Longman\TelegramBot\Entities\Message $message */
        $message = $this->getMessage();
        
        //      
        
        return Request::emptyResponse();
    }
}
      
      



Telegram - . , , , — .





, . .





.





, . callback_data — . ( ) id . id .





<?php
use Longman\TelegramBot\Entities\InlineKeyboard;
use QuestionKeyboardMap;

class KeybordQuestion
{
    
    protected $curentUserId = '';
    
    /**
     *      
     * @return array [reply_markup => InlineKeyboard]
     */
    public function getQuestion()
    {
        
        $keyboard = new InlineKeyboard([
            ['text' => ' !', 'callback_data' => QuestionKeyboardMap::CALLBACK_ANSWER_BOT.$this->curentUserId],
            ['text' => ' !', 'callback_data' => QuestionKeyboardMap::CALLBACK_ANSWER_HUMAN.$this->curentUserId],
        ]);
        
        return ['reply_markup' => $keyboard];
        
    }
    public function setCurentUserId(string $curentUserId)
    {
        $this->curentUserId = $curentUserId;
        return $this;
    }
}
      
      



. framework- Laminas, .





<?php
use TelegramApi;
use Laminas\EventManager\EventManager;
use Longman\TelegramBot\Commands\SystemCommand;
use Longman\TelegramBot\Entities\ServerResponse;
use Longman\TelegramBot\Exception\TelegramException;
use Events;
use Longman\TelegramBot\Request;

class NewchatmembersCommand extends SystemCommand
{
    /**
     * @var string
     */
    protected $name = 'newchatmembers';
    
    /**
     * @var string
     */
    protected $description = 'New Chat Members';
    
    /**
     * @var string
     */
    protected $version = '1.3.0';
    
    public function execute(): ServerResponse
    {
        /** @var TelegramApi $this->telegram */
        /** @var \Laminas\EventManager\EventManager $eventManager */
        $eventManager = $this->telegram->getServiceManager()->get(EventManager::class);
        /** @var \Laminas\ServiceManager\ServiceManager $serviceManager */
        /** @var \Longman\TelegramBot\Entities\Message $message */
        $message = $this->getMessage();
        /** @var array $members */
        $members = $message->getNewChatMembers();
        
        $eventManager->trigger(
            Events::NEW_USER_SENT_REQUEST_TO_JOIN_GROUP,
            null,
            ['message' => $message,'members' => $members]
        );
    
        return Request::emptyResponse();
    }
    
}
      
      



processRequestToJoinGroup Events





<?php
use Laminas\EventManager\EventManager;
use Laminas\ModuleManager\Feature\ConfigProviderInterface;
use Laminas\Mvc\MvcEvent;

class Module implements ConfigProviderInterface
{
    
    public function onBootstrap(MvcEvent $e)
    {
        /** @var \Northmule\Telegram\Events\Events $eventsService */
        $eventsService = $e->getApplication()->getServiceManager()->get(Events::class);
        $eventManager = $e->getApplication()->getServiceManager()->get(EventManager::class);

        $eventManager->attach(EventsMap::NEW_USER_SENT_REQUEST_TO_JOIN_GROUP,[$eventsService,'processRequestToJoinGroup']);

    }

}
      
      



. .





<?php

use Laminas\EventManager\Event;
use Longman\TelegramBot\Entities\Message;
use Longman\TelegramBot\Entities\User;
use Longman\TelegramBot\Entities\User as UserEntities;
use Longman\TelegramBot\Request;
use KeybordQuestion;
use TelegramRestrict;


class Events
{

    /**
     *       
     * @param Event $event
     */
    public function processRequestToJoinGroup(Event $event)
    {
        $message = $event->getParam('message',null);
        $members = $event->getParam('members',[]);
        if (!($message instanceof Message)) {
            return;
        }
        
        /** @var KeybordQuestion $keybord */
        $keybord = $this->serviceManager->get(KeybordQuestion::class); //  
        $keybord->setCurentUserId((string)$message->getFrom()->getId()); //  
        /** @var  TelegramRestrict $restrictionService */
        $restrictionService = $this->serviceManager->get(TelegramRestrict::class);
        $question = $keybord->getQuestion();
        try {
            //     ,    
            $restrictionService->setRestrict($message->getChat()->getId(),$message->getFrom()->getId());
            
            if ($message->botAddedInChat()) { //   
                return  Request::sendMessage([
                    'chat_id' => $message->getChat()->getId(),
                    'text'    => " !",
                    'disable_notification' => true,
                ]);
            }
            
            $member_names = [];
            /** @var UserEntities $member */
            foreach ($members as $member) {
                $member_names[] = $member->tryMention();
            }
            
            return  Request::sendMessage(
                array_merge([
                    'chat_id' => $message->getChat()->getId(),
                    'text'    => '! ' . implode(', ', $member_names) . '! ,  ?',
                    'disable_notification' => true,
                ],$question)
            );
        } catch (\Exception $e) {
            $this->logger->err($e->getMessage(),$e->getTrace());
            return;
        }
        
        
    }

}
      
      







, , , « »





<?php

use Laminas\EventManager\Event;
use Laminas\EventManager\EventManager;
use Longman\TelegramBot\Entities\CallbackQuery;
use Longman\TelegramBot\Entities\Message;
use Longman\TelegramBot\Entities\User;
use Longman\TelegramBot\Request;
use EventsMap;
use QuestionKeyboard;
use TelegramRestrict;


class Events
{

    /**
     *       
     */
    public function checkUsersResponse(Event $event)
    {
        $message = $event->getParam('message',null);
        $user = $event->getParam('user',null);
        $callback = $event->getParam('callback', null);
        
        if (!($message instanceof Message)) {
            return;
        }
        if (!($user instanceof User)) {
            return;
        }
        if (!($callback instanceof CallbackQuery)) {
            return;
        }
        
        $approved = false;
        
        if ($callback->getData() === QuestionKeyboard::CALLBACK_ANSWER_HUMAN.$user->getId()) {
            $approved = true;
        }
        
        /** @var  TelegramRestrict $restrictionService */
        $restrictionService = $this->serviceManager->get(TelegramRestrict::class);
        
        try {
            if ($approved) {
                $eventManager = $this->serviceManager->get(EventManager::class);
                $eventManager->trigger(
                    EventsMap::THE_NEW_USER_ANSWERED_CORRECTLY,
                    null,
                    ['user' => $user,'message' => $message]
                );
                //  
                $restrictionService->unsetRestrict($message->getChat()->getId(),$user->getId());
                
                //  
                Request::deleteMessage(
                    [
                        'chat_id' => $message->getChat()->getId(),
                        'message_id' => $message->getMessageId(),
                    ]
                );
                
                //  
                return  Request::sendMessage([
                    'chat_id' => $message->getChat()->getId(),
                    'text'    => " !",
                    'disable_notification' => true,
                ]);
                
            }
        } catch (\Exception $e) {
            $this->logger->err($e->getMessage(),$e->getTrace());
            return;
        }
        
    }

}
      
      







Laminas. ( )





( ) — - .





,

  • «» , « ». . , Telegram webhook.





  • « » ( Telegram), «» . «» .





  • «» ( ) — ( ). , «» , - . ( , Longman\TelegramBot\Request). «» - Request.





  • , , webhook Telegram backend ( ) 100- , 101- «» . , webhook- ( allowed_updates)





. . , ( ).





, , «» id . .





Json example from Telegram service with string concatenation field and user ID
Json Telegram c

. . ( ), . cron, .





, .





«» . , — .





. , , «» .





Before joining
The user is about to join the group
User replied - I'm human
-





  • API Telegram php-telegram-bot/core





  • Laminas





  • Laminas





@PabloR









P.S.: PHP, ,








All Articles