Completed
Push — develop ( 059b46...8f56e3 )
by Michele
02:21
created

ReactPHPWebhook::run()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 8
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 11
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Zanzara\UpdateMode;
6
7
use Psr\Container\ContainerInterface;
8
use Psr\Http\Message\ServerRequestInterface;
9
use React\EventLoop\LoopInterface;
10
use React\Http\Message\Response;
11
use React\Http\Server;
12
use Zanzara\Config;
13
use Zanzara\Context;
14
use Zanzara\Telegram\Telegram;
15
use Zanzara\Telegram\Type\Update;
16
use Zanzara\Telegram\Type\Webhook\WebhookInfo;
17
use Zanzara\Zanzara;
18
use Zanzara\ZanzaraLogger;
19
use Zanzara\ZanzaraMapper;
20
21
/**
22
 *
23
 */
24
class ReactPHPWebhook extends BaseWebhook
25
{
26
27
    /**
28
     * @var Server
29
     */
30
    private $server;
31
32
    public function __construct(ContainerInterface $container, Zanzara $zanzara, Telegram $telegram, Config $config,
33
                                ZanzaraLogger $logger, LoopInterface $loop, ZanzaraMapper $zanzaraMapper)
34
    {
35
        parent::__construct($container, $zanzara, $telegram, $config, $logger, $loop, $zanzaraMapper);
36
        $this->init();
37
    }
38
39
    private function init()
40
    {
41
        $processingUpdate = null;
42
        $this->server = new Server($this->loop, function (ServerRequestInterface $request) use (&$processingUpdate) {
43
            $token = $this->resolveTokenFromPath($request->getUri()->getPath());
44
            if (!$this->isWebhookAuthorized($token)) {
45
                $this->logger->errorNotAuthorized();
46
                return new Response(403, [], $this->logger->getNotAuthorizedMessage());
47
            }
48
            $json = (string)$request->getBody();
49
            /** @var Update $processingUpdate */
50
            $processingUpdate = $this->zanzaraMapper->mapJson($json, Update::class);
51
            $this->processUpdate($processingUpdate);
52
            return new Response();
53
        });
54
        $this->server->on('error', function ($e) use (&$processingUpdate) {
55
            $this->logger->errorUpdate($e, $processingUpdate);
56
            $errorHandler = $this->config->getErrorHandler();
57
            if ($errorHandler) {
58
                $errorHandler($e, new Context($processingUpdate, $this->container));
59
            }
60
        });
61
    }
62
63
    public function run()
64
    {
65
        $this->telegram->getWebhookInfo()->then(
66
            function (WebhookInfo $webhookInfo) {
67
                if (!$webhookInfo->getUrl()) {
68
                    $message = "Your bot doesn't have a webhook set, please set one before running Zanzara in webhook" .
69
                        " mode. See https://github.com/badfarm/zanzara/wiki#set-webhook";
70
                    $this->logger->error($message);
71
                    return;
72
                }
73
                $this->startListening();
74
            }
75
        );
76
    }
77
78
    private function startListening()
79
    {
80
        $socket = new \React\Socket\Server($this->config->getServerUri(), $this->loop, $this->config->getServerContext());
81
        $this->server->listen($socket);
82
        $this->logger->logIsListening();
83
    }
84
85
    /**
86
     * @return Server
87
     */
88
    public function getServer(): Server
89
    {
90
        return $this->server;
91
    }
92
93
}
94