Lines 100.00% 17 / 17
Methods 100.00% 4 / 4
Classes 100.00% 1 / 1
Name Lines Methods CRAP
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 recipients 100.00% 3 / 3 100.00% 1 / 1 3
 send 100.00% 6 / 6 100.00% 1 / 1 3
 sendTo 100.00% 7 / 7 100.00% 1 / 1 3
20final readonly class ChatSender
21{
22    public const string SLACK = 'slack';
23
24    public const string TELEGRAM = 'telegram';
25
26    public function __construct(
27        private ChatterInterface $chatter,
28        #[Autowire(env: 'SLACK_CHANNEL')]
29        private string $slackChannel,
30        #[Autowire(env: 'SLACK_ERRORS_CHANNEL')]
31        private string $slackErrorsChannel,
32        #[Autowire(env: 'TELEGRAM_CHAT_ID')]
33        private string $telegramChat,
34        #[Autowire(env: 'TELEGRAM_ERRORS_CHAT_ID')]
35        private string $telegramErrorsChat,
36    ) {
37    }
38
39    /**
40     * The chats a feed goes to, with their channel or chat ID.
41     *
42     * @return array<self::SLACK|self::TELEGRAM, string>
43     */
44    public function recipients(ChatFeed $feed): array
45    {
46        return \array_filter(match ($feed) {
47            ChatFeed::Activity => [self::SLACK => $this->slackChannel, self::TELEGRAM => $this->telegramChat],
48            ChatFeed::Errors => [self::SLACK => $this->slackErrorsChannel, self::TELEGRAM => $this->telegramErrorsChat],
49        }, static fn (string $recipient): bool => '' !== $recipient);
50    }
51
52    /**
53     * Sends the text to every chat of the feed, also when one of them fails.
54     *
55     * @return array<self::SLACK|self::TELEGRAM, TransportExceptionInterface|MessengerException> the failures
56     */
57    public function send(ChatFeed $feed, ChatText $text): array
58    {
59        $failures = [];
60        foreach ($this->recipients($feed) as $transport => $recipient) {
61            try {
62                $this->sendTo($transport, $recipient, $text);
63            } catch (TransportExceptionInterface|MessengerException $exception) {
64                $failures[$transport] = $exception;
65            }
66        }
67
68        return $failures;
69    }
70
71    /**
72     * @param self::SLACK|self::TELEGRAM $transport
73     *
74     * @throws TransportExceptionInterface|MessengerException
75     */
76    public function sendTo(string $transport, string $recipient, ChatText $text): void
77    {
78        $message = match ($transport) {
79            self::SLACK => new ChatMessage($text->forSlack(), new SlackOptions()->recipient($recipient)),
80            self::TELEGRAM => new ChatMessage($text->forTelegram(), new TelegramOptions()
81                ->chatId($recipient)
82                ->parseMode(TelegramOptions::PARSE_MODE_HTML)
83                ->disableWebPagePreview(true)),
84        };
85
86        $this->chatter->send($message->transport($transport));
87    }
88}