Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
75 / 75
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
OnTelegramEndpoint
100.00% covered (success)
100.00%
75 / 75
100.00% covered (success)
100.00%
2 / 2
10
100.00% covered (success)
100.00%
1 / 1
 parseInput
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 handle
100.00% covered (success)
100.00%
71 / 71
100.00% covered (success)
100.00%
1 / 1
9
1<?php
2
3namespace Olz\Api\Endpoints;
4
5use Olz\Api\OlzTypedEndpoint;
6use Olz\Entity\TelegramLink;
7use PhpTypeScriptApi\HttpError;
8use Symfony\Component\HttpFoundation\Request;
9
10/**
11 * @extends OlzTypedEndpoint<
12 *   array{
13 *     authenticityCode: non-empty-string,
14 *     telegramEvent: non-empty-string,
15 *   },
16 *   ?array{}
17 * >
18 */
19class OnTelegramEndpoint extends OlzTypedEndpoint {
20    public function parseInput(Request $request): mixed {
21        return [
22            'authenticityCode' => $request->query->get('authenticityCode'),
23            'telegramEvent' => json_encode(json_decode($request->getContent(), true)),
24        ];
25    }
26
27    protected function handle(mixed $input): mixed {
28        $expected_code = $this->envUtils()->getTelegramAuthenticityCode();
29        $actual_code = $input['authenticityCode'];
30        if ($actual_code != $expected_code) {
31            throw new HttpError(403, "Kein Zugriff!");
32        }
33
34        $telegram_event = json_decode($input['telegramEvent'], true);
35        $message_text = $telegram_event['message']['text'] ?? null;
36        $message_chat_id = $telegram_event['message']['chat']['id'] ?? null;
37        $message_user_id = $telegram_event['message']['from']['id'] ?? null;
38
39        if ($message_chat_id === null) {
40            $this->log()->notice('Telegram message without chat_id', [$telegram_event]);
41            return [];
42        }
43
44        $this->telegramUtils()->callTelegramApi('sendChatAction', [
45            'chat_id' => $message_chat_id,
46            'action' => 'typing',
47        ]);
48
49        $telegram_pin_chars = $this->telegramUtils()->getTelegramPinChars();
50        $telegram_pin_length = $this->telegramUtils()->getTelegramPinLength();
51
52        if (preg_match("/^\\/start ([{$telegram_pin_chars}]{{$telegram_pin_length}})$/", $message_text, $matches)) {
53            try {
54                $pin = $matches[1];
55                $telegram_link = $this->telegramUtils()->linkChatUsingPin($pin, $message_chat_id, $message_user_id);
56                $user = $telegram_link->getUser();
57                $user_first_name = $user?->getFirstName();
58                $this->telegramUtils()->callTelegramApi('sendMessage', [
59                    'chat_id' => $message_chat_id,
60                    'text' => "Hallo, {$user_first_name}!",
61                ]);
62            } catch (\Exception $exc) {
63                $this->telegramUtils()->callTelegramApi('sendMessage', [
64                    'chat_id' => $message_chat_id,
65                    'text' => $exc->getMessage(),
66                ]);
67            }
68            return [];
69        }
70
71        if (preg_match("/^\\/start\\s*$/", $message_text, $matches)) {
72            $this->telegramUtils()->startAnonymousChat($message_chat_id, $message_user_id);
73        }
74
75        $chat_state = $this->telegramUtils()->getChatState($message_chat_id);
76        if ($chat_state == null) {
77            $this->telegramUtils()->startAnonymousChat($message_chat_id, $message_user_id);
78            $chat_state = $this->telegramUtils()->getChatState($message_chat_id);
79        }
80
81        $is_anonymous_chat = $this->telegramUtils()->isAnonymousChat($message_chat_id);
82        if ($is_anonymous_chat) {
83            $pin = $this->telegramUtils()->getFreshPinForChat($message_chat_id);
84            $this->telegramUtils()->callTelegramApi('sendMessage', [
85                'chat_id' => $message_chat_id,
86                'parse_mode' => 'HTML',
87                'text' => "<b>Willkommen bei der OL Zimmerberg!</b>\n\nDamit dieser Chat zu irgendwas zu gebrauchen ist, musst du <a href=\"https://olzimmerberg.ch/konto_telegram?pin={$pin}\">hier dein OLZ-Konto verlinken</a>.\n\nDieser Link wird nach 10 Minuten ungültig; wähle /start, um einen neuen Link zu erhalten.",
88                'disable_web_page_preview' => true,
89            ]);
90            return [];
91        }
92
93        $telegram_link_repo = $this->entityManager()->getRepository(TelegramLink::class);
94        $telegram_link = $telegram_link_repo->findOneBy([
95            'telegram_chat_id' => $message_chat_id,
96        ]);
97        $user = $telegram_link?->getUser();
98
99        if (preg_match("/^\\/ich\\s*$/", $message_text, $matches)) {
100            $response_message = <<<ZZZZZZZZZZ
101                <b>Du bist angemeldet als:</b>
102                <b>Name:</b> {$user?->getFullName()}
103                <b>Benutzername:</b> {$user?->getUsername()}
104                <b>E-Mail:</b> {$user?->getEmail()}
105                ZZZZZZZZZZ;
106            $this->telegramUtils()->callTelegramApi('sendMessage', [
107                'chat_id' => $message_chat_id,
108                'parse_mode' => 'HTML',
109                'text' => $response_message,
110            ]);
111            return [];
112        }
113
114        $this->telegramUtils()->callTelegramApi('sendMessage', [
115            'chat_id' => $message_chat_id,
116            'text' => 'Hä?',
117        ]);
118
119        return [];
120    }
121}