diff --git a/src/Monolog/Handler/TelegramBotHandler.php b/src/Monolog/Handler/TelegramBotHandler.php new file mode 100644 index 00000000..34a87da5 --- /dev/null +++ b/src/Monolog/Handler/TelegramBotHandler.php @@ -0,0 +1,90 @@ + + */ +class TelegramBotHandler extends AbstractProcessingHandler +{ + private const BOT_API = 'https://api.telegram.org/bot'; + + /** + * Telegram bot access token provided by BotFather. + * Create telegram bot with https://telegram.me/BotFather and use access token from it. + * @var string + */ + private $apiKey; + + /** + * Telegram channel name. + * Since to start with '@' symbol as prefix. + * @var string + */ + private $channel; + + /** + * @param string $apiKey Telegram bot access token provided by BotFather + * @param string $channel Telegram channel name + * @inheritDoc + */ + public function __construct( + string $apiKey, + string $channel, + $level = Logger::DEBUG, + bool $bubble = true + ) { + parent::__construct($level, $bubble); + + $this->apiKey = $apiKey; + $this->channel = $channel; + $this->level = $level; + $this->bubble = $bubble; + } + + /** + * @inheritDoc + */ + protected function write(array $record): void + { + $this->send($record['formatted']); + } + + /** + * Send request to @link https://api.telegram.org/bot on SendMessage action. + * @param string $message + */ + protected function send(string $message): void + { + $ch = curl_init(); + $url = self::BOT_API . $this->apiKey . '/SendMessage'; + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([ + 'text' => $message, + 'chat_id' => $this->channel, + ])); + + $result = Curl\Util::execute($ch); + $result = json_decode($result, true); + + if ($result['ok'] === false) { + throw new RuntimeException('Telegram API error. Description: ' . $result['description']); + } + } +} \ No newline at end of file diff --git a/tests/Monolog/Handler/TelegramBotHandlerTest.php b/tests/Monolog/Handler/TelegramBotHandlerTest.php new file mode 100644 index 00000000..c9f22f0b --- /dev/null +++ b/tests/Monolog/Handler/TelegramBotHandlerTest.php @@ -0,0 +1,42 @@ + + * @link https://core.telegram.org/bots/api + */ +class TelegramBotHandlerTest extends TestCase +{ + /** + * @var TelegramBotHandler + */ + private $handler; + + public function testSendTelegramRequest(): void + { + $this->createHandler(); + $this->handler->handle($this->getRecord()); + } + + /** + * @param string $apiKey + * @param string $channel + */ + private function createHandler(string $apiKey = 'testKey', string $channel = 'testChannel'): void + { + $constructorArgs = [$apiKey, $channel, Logger::DEBUG, true]; + + $this->handler = $this->getMockBuilder(TelegramBotHandler::class) + ->setConstructorArgs($constructorArgs) + ->setMethods(['send']) + ->getMock(); + + $this->handler->expects($this->atLeast(1)) + ->method('send') + ->willReturn(null); + } +} \ No newline at end of file