1. Go to this page and download the library: Download viktorprogger/telegram-bot library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
viktorprogger / telegram-bot example snippets
[
(new Group(
// This bot will work in private chats only
new RuleDynamic(static fn(Update $update) => $update->chat->type === ChatType::PRIVATE),
...[
'/start' => new Route(
new RuleStatic('/start'),
[StartAction::class, 'handle'],
),
'/pay' => new Route(
new RuleStatic('/pay'),
[PayAction::class, 'handle'],
),
'rates requests' => (new Route(
new RuleDynamic(
static fn(Update $update): bool => preg_match('#^/rates \w+ \w+$#', $update->requestData ?? '') === 1,
),
[RatesAction::class, 'handle'],
))->withMiddlewares(PaidAccessMiddleware::class),
],
))->withMiddlewares(UserRegisterMiddleware::class),
]
final readonly class StartAction
{
public function handle(Update $update): ResponseInterface
{
return (new Response($update))
->withRequest(
new Message(
// You should properly escape all special characters to send a markdown message
'Hello\\! Use \\/pay command to get premium\\, and then use \\/rates command ' .
'to see currency exchange rates\\. I\\.e\\. `/pay USD GBP`\\.',
MessageFormat::MARKDOWN,
$update->chat->id,
),
);
}
}
final readonly class RatesAction
{
public function __construct(private readonly RatesService $ratesService) {}
public function handle(
Update $update,
#[UpdateAttribute('user')] User $user,
): ResponseInterface {
// User sent a request like "/rates USD GBP", so we need to get USD and GBP from the request
[, $currency1, $currency2] = explode(' ', $update->requestData);
$user->saveRequestHistory($currency1, $currency2);
$rate = $this->ratesService->getRate($currency1, $currency2);
$date = date('Y-m-d H:i:s');
// send a message as a response
return (new Response($update))
->withRequest(
new Message(
"1 $currency1 = $rate $currency2 on $date. To get a reverse rate, " .
"use /rates $currency2 $currency1 command.",
MessageFormat::TEXT,
$update->chat->id,
),
);
}
}
final class UserRegisterMiddleware implements MiddlewareInterface
{
public function __construct(private UserRepository $repository)
{
}
public function process(Update $update, UpdateHandlerInterface $handler): ResponseInterface
{
// Repository either finds a user or creates a new one
$holder = $this->repository->getUser($update->user, $update->chat->id);
// now $update->getAttribute('user') contains a User object
return $handler->handle($update->withAttribute('user', $holder));
}
}
final class PaidAccessMiddleware implements MiddlewareInterface
{
public function process(Update $update, UpdateHandlerInterface $handler): ResponseInterface
{
/** @var User $user */
$user = $update->getAttribute('user');
if (!$user->isPremium()) {
return (new Response($update))
->withRequest(new Message(
'Only premium users can use this command',
MessageFormat::TEXT,
$update->chat->id,
));
}
return $handler->handle($update);
}
}
use Botasis\Client\Telegram\Client\ClientPsr;
use Botasis\Runtime\Application;
use Botasis\Runtime\CallableFactory;
use Botasis\Runtime\Emitter;
use Botasis\Runtime\Handler\DummyUpdateHandler;
use Botasis\Runtime\Middleware\Implementation\RouterMiddleware;
use Botasis\Runtime\Middleware\MiddlewareDispatcher;
use Botasis\Runtime\Middleware\MiddlewareFactory;
use Botasis\Runtime\Router\Route;
use Botasis\Runtime\Router\Router;
use Botasis\Runtime\Router\RuleStatic;
use Botasis\Runtime\UpdateHandlerInterface;
use Http\Client\Socket\Client;
use HttpSoft\Message\RequestFactory;
use HttpSoft\Message\StreamFactory;
use Psr\Container\ContainerInterface;
use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Yiisoft\Di\Container;
use Yiisoft\EventDispatcher\Dispatcher\Dispatcher;
/**
* @var string $token - a bot token you've got from the BotFather
* @var ClientInterface $httpClient - an HTTP client. If you've installed the php-http/socket-client package,
* it's {@see Client}. Either it's a client of your choice.
* @var RequestFactoryInterface $requestFactory - a PSR-17 HTTP request factory. If you've installed the httpsoft/http-message package,
* it's {@see RequestFactory}.
* @var StreamFactoryInterface $streamFactory - a PSR-17 HTTP stream factory. If you've installed the httpsoft/http-message package,
* it's {@see StreamFactory}.
* @var EventDispatcherInterface $eventDispatcher - a PSR-14 event dispatcher. If you've installed the yiisoft/event-dispatcher package,
* it's {@see Dispatcher}.
* @var ContainerInterface $container - a PST-11 DI container. If you've installed the yiisoft/di package,
* it's {@see Container}.
*/
$client = new ClientPsr(
$token,
$httpClient,
$requestFactory,
$streamFactory,
);
$emitter = new Emitter($client, $eventDispatcher);
$middlewareDispatcher = new MiddlewareDispatcher(
new MiddlewareFactory($container, new CallableFactory($container)),
$eventDispatcher,
);
/**
* Routes definition. Here we define a route for the /start message. The HelloAction will be instantiated by a DI container.
*/
$routes = [
new Route(new RuleStatic('/start'), [HelloAction::class, 'handle']),
];
/**
* Middlewares definition. {@see RouterMiddleware} should be the last one.
*/
$middlewares = [new RouterMiddleware(new Router($container, $middlewareDispatcher, ...$routes))];
$middlewareDispatcher = $middlewareDispatcher->withMiddlewares();
$application = new Application($emitter, new DummyUpdateHandler(), $middlewareDispatcher);
final class CharacterNameCommandAction
{
public function __construct(private StateRepositoryInterface $repository) {}
public function handle(Update $update): ResponseInterface
{
$state = new StateJson($update->user->id, $update->chat->id, 'setting-name');
$this->repository->save($state);
return (new Response($update))
->withRequest(new Message(
'Enter your character name below',
MessageFormat::TEXT,
$update->chat->id,
));
}
}