Skip to content

Commit 8ae92e6

Browse files
authored
Mail notification channel (alexjustesen#142)
1 parent 67132b3 commit 8ae92e6

18 files changed

+486
-175
lines changed

app/Filament/Pages/Settings/NotificationPage.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,21 @@
33
namespace App\Filament\Pages\Settings;
44

55
use App\Forms\Components\TestDatabaseNotification;
6+
use App\Forms\Components\TestMailNotification;
7+
use App\Mail\Test;
68
use App\Settings\NotificationSettings;
79
use Closure;
810
use Filament\Forms\Components\Card;
911
use Filament\Forms\Components\Fieldset;
1012
use Filament\Forms\Components\Grid;
13+
use Filament\Forms\Components\Repeater;
1114
use Filament\Forms\Components\Section;
15+
use Filament\Forms\Components\TextInput;
1216
use Filament\Forms\Components\Toggle;
1317
use Filament\Forms\Components\View;
1418
use Filament\Notifications\Notification;
1519
use Filament\Pages\SettingsPage;
20+
use Illuminate\Support\Facades\Mail;
1621

1722
class NotificationPage extends SettingsPage
1823
{
@@ -69,6 +74,45 @@ protected function getFormSchema(): array
6974
'default' => 1,
7075
'md' => 2,
7176
]),
77+
78+
Section::make('Mail')
79+
->schema([
80+
Toggle::make('mail_enabled')
81+
->label('Enable mail notifications')
82+
->reactive()
83+
->columnSpan(2),
84+
Grid::make([
85+
'default' => 1,
86+
])
87+
->hidden(fn (Closure $get) => $get('mail_enabled') !== true)
88+
->schema([
89+
Fieldset::make('Triggers')
90+
->schema([
91+
Toggle::make('mail_on_speedtest_run')
92+
->label('Notify on every speetest run')
93+
->columnSpan(2),
94+
Toggle::make('mail_on_threshold_failure')
95+
->label('Notify on threshold failures')
96+
->columnSpan(2),
97+
]),
98+
]),
99+
Repeater::make('mail_recipients')
100+
->label('Recipients')
101+
->schema([
102+
TextInput::make('email_address')
103+
->email()
104+
->required(fn (Closure $get) => $get('mail_enabled') == true),
105+
])
106+
->hidden(fn (Closure $get) => $get('mail_enabled') !== true)
107+
->columnSpan(['md' => 2]),
108+
TestMailNotification::make('test channel')
109+
->hidden(fn (Closure $get) => $get('mail_enabled') !== true),
110+
])
111+
->compact()
112+
->columns([
113+
'default' => 1,
114+
'md' => 2,
115+
]),
72116
])
73117
->columnSpan([
74118
'md' => 2,
@@ -103,4 +147,19 @@ public function sendTestDatabaseNotification()
103147
->success()
104148
->send();
105149
}
150+
151+
public function sendTestMailNotification()
152+
{
153+
$notificationSettings = new (NotificationSettings::class);
154+
155+
foreach ($notificationSettings->mail_recipients as $recipient) {
156+
Mail::to($recipient)
157+
->send(new Test());
158+
}
159+
160+
Notification::make()
161+
->title('Test mail notification sent.')
162+
->success()
163+
->send();
164+
}
106165
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace App\Forms\Components;
4+
5+
use Filament\Forms\Components\Field;
6+
7+
class TestMailNotification extends Field
8+
{
9+
protected string $view = 'forms.components.test-mail-notification';
10+
}

app/Listeners/SpeedtestCompletedListener.php

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
namespace App\Listeners;
44

55
use App\Events\ResultCreated;
6+
use App\Mail\SpeedtestCompletedMail;
67
use App\Settings\NotificationSettings;
78
use Filament\Notifications\Notification;
9+
use Illuminate\Support\Facades\Mail;
810

911
class SpeedtestCompletedListener
1012
{
@@ -28,15 +30,22 @@ public function __construct()
2830
*/
2931
public function handle(ResultCreated $event)
3032
{
31-
if (! $this->notificationSettings->database_enabled) {
32-
return;
33+
if ($this->notificationSettings->database_enabled) {
34+
if ($this->notificationSettings->database_on_speedtest_run) {
35+
Notification::make()
36+
->title('Speedtest completed')
37+
->success()
38+
->sendToDatabase($event->user);
39+
}
3340
}
3441

35-
if ($this->notificationSettings->database_on_speedtest_run) {
36-
Notification::make()
37-
->title('Speedtest completed')
38-
->success()
39-
->sendToDatabase($event->user);
42+
if ($this->notificationSettings->mail_enabled) {
43+
if ($this->notificationSettings->mail_on_speedtest_run && count($this->notificationSettings->mail_recipients)) {
44+
foreach ($this->notificationSettings->mail_recipients as $recipient) {
45+
Mail::to($recipient)
46+
->send(new SpeedtestCompletedMail($event->result));
47+
}
48+
}
4049
}
4150
}
4251
}

app/Listeners/Threshold/AbsoluteDownloadListener.php

Lines changed: 0 additions & 49 deletions
This file was deleted.
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
<?php
2+
3+
namespace App\Listeners\Threshold;
4+
5+
use App\Events\ResultCreated;
6+
use App\Mail\Threshold\AbsoluteMail;
7+
use App\Settings\NotificationSettings;
8+
use App\Settings\ThresholdSettings;
9+
use Filament\Notifications\Notification;
10+
use Illuminate\Contracts\Queue\ShouldQueue;
11+
use Illuminate\Support\Facades\Log;
12+
use Illuminate\Support\Facades\Mail;
13+
14+
class AbsoluteListener implements ShouldQueue
15+
{
16+
public $notificationSettings;
17+
18+
public $thresholdSettings;
19+
20+
/**
21+
* Create the event listener.
22+
*
23+
* @return void
24+
*/
25+
public function __construct()
26+
{
27+
$this->notificationSettings = new (NotificationSettings::class);
28+
29+
$this->thresholdSettings = new (ThresholdSettings::class);
30+
}
31+
32+
/**
33+
* Handle the event.
34+
*
35+
* @param \App\Events\ResultCreated $event
36+
* @return void
37+
*/
38+
public function handle(ResultCreated $event)
39+
{
40+
if ($this->thresholdSettings->absolute_enabled !== true) {
41+
Log::info('Absolute threshold notifications disabled.');
42+
43+
return;
44+
}
45+
46+
// Database notification channel
47+
if ($this->notificationSettings->database_enabled == true && $this->notificationSettings->database_on_threshold_failure == true) {
48+
$this->databaseChannel($event);
49+
}
50+
51+
// Mail notification channel
52+
if ($this->notificationSettings->mail_enabled == true && $this->notificationSettings->mail_on_threshold_failure == true) {
53+
$this->mailChannel($event);
54+
}
55+
}
56+
57+
/**
58+
* Handle database notifications.
59+
*
60+
* @param \App\Events\ResultCreated $event
61+
* @return void
62+
*/
63+
protected function databaseChannel(ResultCreated $event)
64+
{
65+
// Download threshold
66+
if ($this->thresholdSettings->absolute_download > 0) {
67+
if (absoluteDownloadThresholdFailed($this->thresholdSettings->absolute_download, $event->result->download)) {
68+
Notification::make()
69+
->title('Threshold breached')
70+
->body('Speedtest #'.$event->result->id.' breached the download threshold of '.$this->thresholdSettings->absolute_download.'Mbps at '.formatBits(formatBytesToBits($event->result->download), 2, false).'Mbps.')
71+
->warning()
72+
->sendToDatabase($event->user);
73+
}
74+
}
75+
76+
// Upload threshold
77+
if ($this->thresholdSettings->absolute_upload > 0) {
78+
if (absoluteUploadThresholdFailed($this->thresholdSettings->absolute_upload, $event->result->upload)) {
79+
Notification::make()
80+
->title('Threshold breached')
81+
->body('Speedtest #'.$event->result->id.' breached the upload threshold of '.$this->thresholdSettings->absolute_upload.'Mbps at '.formatBits(formatBytesToBits($event->result->upload), 2, false).'Mbps.')
82+
->warning()
83+
->sendToDatabase($event->user);
84+
}
85+
}
86+
87+
// Ping threshold
88+
if ($this->thresholdSettings->absolute_ping > 0) {
89+
if (absolutePingThresholdFailed($this->thresholdSettings->absolute_ping, $event->result->ping)) {
90+
Notification::make()
91+
->title('Threshold breached')
92+
->body('Speedtest #'.$event->result->id.' breached the ping threshold of '.$this->thresholdSettings->absolute_ping.'ms at '.$event->result->ping.'ms.')
93+
->warning()
94+
->sendToDatabase($event->user);
95+
}
96+
}
97+
}
98+
99+
/**
100+
* Handle database notifications.
101+
*
102+
* @param \App\Events\ResultCreated $event
103+
* @return void
104+
*/
105+
protected function mailChannel(ResultCreated $event)
106+
{
107+
$failedThresholds = [];
108+
109+
if (! count($this->notificationSettings->mail_recipients) > 0) {
110+
Log::info('Skipping sending mail notification, no recipients.');
111+
}
112+
113+
// Download threshold
114+
if ($this->thresholdSettings->absolute_download > 0) {
115+
if (absoluteDownloadThresholdFailed($this->thresholdSettings->absolute_download, $event->result->download)) {
116+
array_push($failedThresholds, [
117+
'name' => 'Download',
118+
'threshold' => $this->thresholdSettings->absolute_download.' Mbps',
119+
'value' => formatBits(formatBytesToBits($event->result->download)).'ps',
120+
]);
121+
}
122+
}
123+
124+
// Upload threshold
125+
if ($this->thresholdSettings->absolute_upload > 0) {
126+
if (absoluteUploadThresholdFailed($this->thresholdSettings->absolute_upload, $event->result->upload)) {
127+
array_push($failedThresholds, [
128+
'name' => 'Upload',
129+
'threshold' => $this->thresholdSettings->absolute_upload.' Mbps',
130+
'value' => formatBits(formatBytesToBits($event->result->upload)).'ps',
131+
]);
132+
}
133+
}
134+
135+
// Ping threshold
136+
if ($this->thresholdSettings->absolute_ping > 0) {
137+
if (absolutePingThresholdFailed($this->thresholdSettings->absolute_ping, $event->result->ping)) {
138+
array_push($failedThresholds, [
139+
'name' => 'Ping',
140+
'threshold' => $this->thresholdSettings->absolute_ping.' Ms',
141+
'value' => round($event->result->ping, 2).' Ms',
142+
]);
143+
}
144+
}
145+
146+
if (count($failedThresholds)) {
147+
foreach ($this->notificationSettings->mail_recipients as $recipient) {
148+
Mail::to($recipient)
149+
->send(new AbsoluteMail($event->result, $failedThresholds));
150+
}
151+
}
152+
}
153+
}

app/Listeners/Threshold/AbsolutePingListener.php

Lines changed: 0 additions & 49 deletions
This file was deleted.

0 commit comments

Comments
 (0)