Passed
Push — main ( df35b1...fc5716 )
by Tan
02:29
created

NotificationService::sendToRecipients()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 2
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace CSlant\LaravelTelegramGitNotifier\Services;
4
5
use CSlant\TelegramGitNotifier\Exceptions\{
6
    InvalidViewTemplateException,
7
    MessageIsEmptyException,
8
    SendNotificationException
9
};
10
use CSlant\TelegramGitNotifier\Models\Setting;
11
use CSlant\TelegramGitNotifier\Notifier;
12
use CSlant\TelegramGitNotifier\Objects\Validator;
13
use Symfony\Component\HttpFoundation\Request;
14
15
class NotificationService
16
{
17
    /** @var array<string, array<int|string>> */
18
    protected array $chatIds = [];
19
20
    public function __construct(
21
        protected Notifier $notifier,
22
        protected Setting $setting,
23
        protected Request $request = new Request()
24
    ) {
25
        $this->request = $request ?? Request::createFromGlobals();
26
        $this->chatIds = $notifier->parseNotifyChatIds();
27
    }
28
29
    /**
30
     * Handle sending notification from webhook event to Telegram.
31
     *
32
     * @throws InvalidViewTemplateException
33
     * @throws SendNotificationException
34
     * @throws MessageIsEmptyException
35
     */
36
    public function handle(): void
37
    {
38
        if ($eventName = $this->notifier->handleEventFromRequest($this->request)) {
39
            $this->sendNotification($eventName);
40
        }
41
    }
42
43
    /**
44
     * Send notification to all configured chat IDs and threads.
45
     *
46
     * @throws InvalidViewTemplateException
47
     * @throws SendNotificationException
48
     * @throws MessageIsEmptyException
49
     */
50
    private function sendNotification(string $event): void
51
    {
52
        if (!$this->isValidEvent($event)) {
53
            return;
54
        }
55
56
        foreach ($this->chatIds as $chatId => $threads) {
57
            if (empty($chatId)) {
58
                continue;
59
            }
60
61
            empty($threads) 
62
                ? $this->sendToChat($chatId)
63
                : $this->sendToThreads($chatId, $threads);
64
        }
65
    }
66
67
    /**
68
     * Send notification to a single chat.
69
     *
70
     * @throws SendNotificationException
71
     */
72
    private function sendToChat(string $chatId): void
73
    {
74
        $this->notifier->sendNotify(null, ['chat_id' => $chatId]);
75
    }
76
77
    /**
78
     * Send notification to multiple threads in a chat.
79
     *
80
     * @param  array<int|string>  $threads
81
     *
82
     * @throws SendNotificationException
83
     */
84
    private function sendToThreads(string $chatId, array $threads): void
85
    {
86
        foreach ($threads as $threadId) {
87
            $this->notifier->sendNotify(null, [
88
                'chat_id' => $chatId,
89
                'message_thread_id' => $threadId,
90
            ]);
91
        }
92
    }
93
94
    /**
95
     * Check if the event is valid and accessible.
96
     */
97
    private function isValidEvent(string $event): bool
98
    {
99
        $payload = $this->notifier->setPayload($this->request, $event);
100
        
101
        if (empty($payload) || !is_object($payload)) {
102
            return false;
103
        }
104
105
        $validator = new Validator($this->setting, $this->notifier->event);
106
        
107
        return $validator->isAccessEvent(
108
            $this->notifier->event->platform,
109
            $event,
110
            $payload
111
        );
112
    }
113
}
114