mateodioev / tg-handler
Library for created telegram bots more easy
Requires
- php: >=8.1
- kombyte/simple-logger: ^1.0
- mateodioev/string-vars: ^1.2
- mateodioev/tgbot: ^v4.2
- psr/log: ^3.0
- smoren/string-formatter: ^1.0
Requires (Dev)
- amphp/http-server: ^3.2
- amphp/log: ^2.0
- friendsofphp/php-cs-fixer: ^3.35
- monolog/monolog: ^3.5
- phpunit/phpunit: ^10
- dev-main
- v5.x-dev
- v5.8.2
- v5.8.1
- v5.8.0
- v5.7.3
- v5.7.2
- v5.7.1
- v5.7.0
- v5.6.1
- v5.6.0
- v5.5.2
- v5.5.1
- v5.5.0
- v5.4.2
- v5.4.1
- v5.4-beta
- v5.3.1
- v5.3.0
- v5.3-beta
- v5.2.1
- v5.2.0
- v5.1.5
- v5.1.4
- v5.1.3.1
- v5.1.3
- v5.1.2
- v5.1.1
- v5.1
- v5.0.1
- v5.0.0
- v4.x-dev
- v4.2.2
- v4.2.1
- v4.2
- v4.1.4
- v4.1.3.1
- v4.1.3
- v4.1.2.1
- v4.1.2
- v4.1.1
- v4.1.0
- v4.0.9
- v4.0.8
- v4.0.7
- v4.0.6
- v4.0.5
- v4.0.4
- v4.0.3
- v4.0.2
- v4.0.1
- v4.0.0-beta
- v3.x-dev
- v3.5.0
- v3.4.05
- v3.4.04
- v3.4.03
- v3.4.02
- v3.4.0
- v3.3.1
- v3.3.0
- v3.2.2
- v3.2.1
- v3.2.0
- v3.1.3
- v3.1.1
- v3.1
- v3.0
- v3.0-beta
- v2.3
- v2.2
- v2.1.2
- v2.1.1
- v2.1
- v2.0
- v2.0-beta
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1
- v1.0
This package is auto-updated.
Last update: 2024-11-10 05:33:57 UTC
README
Installation
composer require mateodioev/tg-handler
use Mateodioev\TgHandler\Bot;
Usage
Create new instance and add your command
$bot = new Bot($botToken); $bot->onEvent(YourCommandInstance); $bot->byWebhook(); // or $bot->longPolling($timeout); // No needs server with ssl
Creating new command instance
All text commands need to extend Mateodioev\TgHandler\Commands\MessageCommand
class, and put the logic in the method handle
.
use Mateodioev\TgHandler\Commands\MessageCommand; use Mateodioev\Bots\Telegram\Api; use Mateodioev\TgHandler\Context; class MyCommand extends MessageCommand { protected string $name = 'start'; protected string $description = 'Start the bot'; public function handle(Api $bot, Context $context){ // TODO: Implement handle() method. $bot->sendMessage($context->getChatId(), 'Hello!!!'); } } $bot->onEvent(MyCommand::get());
This command works with /start any text here
or /start
. If you need another prefixes (/, !) you can add with method addPrefix
or with property prefix
class MyCommand extends MessageCommand { protected string $name = 'start'; protected string $description = 'Start the bot'; protected array $prefix = ['/', '!']; // Additionally you can add command aliases protected array $alias = ['help']; ... } // or $myCommand = MyCommand::get(); $myCommand->setPrefixes(['/', '!']); // Set prefix, no need to set `$prefix` property
Using middlewares
You can add middlewares to your command. Middlewares are closures that will be executed before the command. All middlewares results will be passed to the command as an array.
For example, you can create a middleware that will check if the user is authorized, and if not, the command will not be executed.
class MyCommand extends MessageCommand { protected string $name = 'start'; protected string $description = 'Start the bot'; protected array $middlewares = [ 'authUser' ]; public function handle(Api $bot, Context $context, array $args = []){ // $args[0] is the result of the middleware authUser // Your logic here } } // Your middleware function function authUser(Context $ctx, Api $bot) { $user = User::find($ctx->getUserId()); if (!$user) { $bot->replyTo($ctx->getChatId(), 'You are not authorized', $ctx->getMessageId()) throw new \Mateodioev\TgHandler\Commands\StopCommand(); // Stop command execution } return $user; }
You can use
StopCommand
exception to stop command execution
Using filters
Now you can set custom filters to you event for validate, all filters need to extends the interface Mateodioev\TgHandler\Filters\Filter
use Mateodioev\Bots\Telegram\Api; use Mateodioev\TgHandler\Context; [\Mateodioev\TgHandler\Filters\FilterFromUserId(996202950)]; class FilterCommand extends MessageCommand { protected string $name = 'filter'; public function handle(Api $bot, Context $context, array $args = []) { } }
Now this command only respond to the user ID 996202950
Using multiple filters
You can use FilterCollection
use Mateodioev\TgHandler\Events\Types\MessageEvent; use Mateodioev\TgHandler\Filters\{FilterCollection, FilterMessageChat, FilterMessageRegex}; #[FilterCollection( new FilterMessageChat(TestChat::CHAT_ID), new FilterMessageRegex('/.*(mt?proto).*/i') )] class TestChat extends MessageEvent { const CHAT_ID = 'Put your chat id here'; public function execute(Api $bot, Context $context, array $args = []) { // your logic here } }
Or can use this sintax
use Mateodioev\TgHandler\Events\Types\MessageEvent; use Mateodioev\TgHandler\Filters\{FilterCollection, FilterMessageChat, FilterMessageRegex}; #[FilterMessageChat(TestChat::CHAT_ID), FilterMessageRegex('/.*(filters).*/i')] class TestChat extends MessageEvent { const CHAT_ID = 'Put your chat id here'; public function execute(Api $bot, Context $context, array $args = []) { // your logic here } }
Conversations
To start a new conversation you simply return an instance of the Mateodioev\TgHandler\Conversations\Conversations
in a interface of Mateodioev\TgHandler\Events\EventInterface
Conversation:
use Mateodioev\Bots\Telegram\Api; use Mateodioev\TgHandler\Context; use Mateodioev\TgHandler\Conversations\MessageConversation; class MyConversation extends MessageConversation { // This is optional, only for validate the user input message protected string $format = 'My name is {w:name}'; public function execute(Api $bot, Context $context, array $args = []) { $bot->sendMessage( $context->getChatId(), 'Nice to meet you ' . $this->param('name') ); } }
EventInterface handler for this case an instance of MessageCommand
use Mateodioev\Bots\Telegram\Api; use Mateodioev\TgHandler\Commands\MessageCommand; use Mateodioev\TgHandler\Context; class Name extends MessageCommand { protected string $name = 'name'; public function handle(Api $bot, Context $context, array $args = []) { $bot->replyTo( $context->getChatId(), 'Please give me your name:', $context->getMessageId(), ); // Register next conversation handler return nameConversation::new($context->getChatId(), $context->getUserId()); } }
Register the conversation
$bot->onEvent(Name::get());
For more details see examples folder
Loging
Basic usage
use Mateodioev\TgHandler\Log\{Logger, TerminalStream}; $log = new Logger(new TerminalStream); // Print logs in terminal $bot->setLogger($log); // Save logger
Collections of streams
use Mateodioev\TgHandler\Log\{BulkStream, Logger, TerminalStream, PhpNativeStream}; BulkStream::add(new TerminalStream); // print logs in terminal BulkStream::add((new PhpNativeStream)->activate(__DIR__)); // save logs in .log file and catch php warnings $bot->setLogger(new Logger(new BulkStream));
Set log level
use Mateodioev\TgHandler\Log\{Logger, TerminalStream}; $log = new Logger(new TerminalStream); // disable all logs $log->setLevel(Logger:ALL, false); // Enable only critical, error and emergency messages $log->setLevel(Logger::CRITICAL | Logger::ERROR | Logger::EMERGENCY); $bot->setLogger($log);
Use
The logger can be used from the bot or event instances (MessageCommand, CallbackCommand, etc)
Bot:
$bot->getLogger()->debug('This is a debug message'); // output: [Y-m-d H:i:s] [DEBUG] This is a debug message $bot->getLogger()->info('This is a debug message with {paramName}', [ 'paramName' => 'context params' ]); // output: [Y-m-d H:i:s] [INFO] This is a debug message with context params
Event instances:
use Mateodioev\TgHandler\Commands\MessageCommand; use Mateodioev\Bots\Telegram\Api; use Mateodioev\TgHandler\Context; class MyCommand extends MessageCommand { protected string $name = 'start'; protected string $description = 'Start the bot'; public function handle(Api $bot, Context $context) { $this->logger()->debug('Loging inside event'); $this->logger()->info('User {name} use the command {commandName}', [ 'name' => $context->getUserName() ?? 'null', 'commandName' => $this->name ]); } } // register the command $bot->onEvent(MyCommand::get());
Manager errors
You can register an exception handler the will be used if an exception occurs within the Events::execute method method or in the event middlewares
// Base exception class UserException extends \Exception {} // Specific exception final class UserNotRegistered extends UserException {} final class UserBanned extends UserException {} // This only manage UserBanned exception $bot->setExceptionHandler(UserBanned::class, function (UserBanned $e, Bot $bot, Context $ctx) { $bot->getApi()->sendMessage($ctx->getChatId(), 'You are banned'); }); // This manage all UserException sub classes $bot->setExceptionHandler(UserException::class, function (UserException $e, Bot $bot, Context $ctx) { $bot->getLogger()->warning('Ocurrs an user exception in chat id: ' . $ctx->getChatId()); });