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 ( , ) .
(, -, )
( ) — . ( ?). — « » « ». .
- « » , , .
, backend .
— « », .
- , , « »
json- Telegram URL (webhook) .
backend Telegram, Telegram. — ( ).
Telegram API PHP
danog/MadelineProto — , , «».
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 . .
. . ( ), . cron, .
, .
«» . , — .
. , , «» .
@PabloR
P.S.: PHP, ,