src/RunningMode/Webhook.php
<?php
namespace SergiX44\Nutgram\RunningMode;
use Closure;
use JsonMapper_Exception;
use Psr\Log\LoggerInterface;
use Psr\SimpleCache\InvalidArgumentException;
use SergiX44\Nutgram\Hydrator\Hydrator;
use SergiX44\Nutgram\Nutgram;
use SergiX44\Nutgram\Telegram\Types\Common\Update;
use Throwable;
class Webhook implements RunningMode
{
protected bool $safeMode = false;
protected Closure $resolveSecretToken;
protected ?string $secretToken = null;
/**
* @param Closure|null $getToken
* @param string|null $secretToken
*/
public function __construct(?Closure $getToken = null, ?string $secretToken = null)
{
$this->resolveSecretToken = $getToken ?? static fn (): string => $_SERVER['HTTP_X_TELEGRAM_BOT_API_SECRET_TOKEN'];
$this->secretToken = $secretToken;
}
/**
* @param Nutgram $bot
* @throws JsonMapper_Exception
* @throws InvalidArgumentException
* @throws Throwable
*/
public function processUpdates(Nutgram $bot): void
{
$input = $this->input();
if ($input === null || ($this->safeMode && ($this->resolveSecretToken)() !== $this->secretToken)) {
return;
}
$update = null;
try {
/** @var Update $update */
$update = $bot->getContainer()
->get(Hydrator::class)
->hydrate(json_decode($input, true, flags: JSON_THROW_ON_ERROR), Update::class);
$bot->processUpdate($update);
$bot->getContainer()
->get(LoggerInterface::class)
->debug(sprintf('Update processed: %s%s%s', $update?->getType()?->value, PHP_EOL, $input));
} catch (Throwable $e) {
$bot->getContainer()
->get(LoggerInterface::class)
->error(sprintf('Update failed: %s%s%s', $update?->getType()?->value, PHP_EOL, $input), ['exception' => $e]);
throw $e;
}
}
/**
* @return bool
*/
public function isSafeMode(): bool
{
return $this->safeMode;
}
/**
* @param bool $safeMode
* @return self
*/
public function setSafeMode(bool $safeMode): self
{
$this->safeMode = $safeMode;
return $this;
}
/**
* @return string|null
*/
protected function input(): ?string
{
return file_get_contents('php://input') ?: null;
}
}