From 44476516f594b8728f0ac9bc346b8187f7eca6c8 Mon Sep 17 00:00:00 2001 From: Nils Uliczka Date: Mon, 11 Sep 2023 17:18:14 +0200 Subject: [PATCH 1/3] feat: add webhook notifications --- .../Pages/Settings/NotificationPage.php | 39 ++++++++++++ .../Components/TestWebhookNotification.php | 10 +++ app/Listeners/SpeedtestCompletedListener.php | 15 +++++ app/Listeners/Threshold/AbsoluteListener.php | 61 +++++++++++++++++++ app/Settings/NotificationSettings.php | 8 +++ ...8_create_webhook_notification_settings.php | 17 ++++++ .../test-webhook-notification.blade.php | 5 ++ 7 files changed, 155 insertions(+) create mode 100644 app/Forms/Components/TestWebhookNotification.php create mode 100644 database/migrations/2023_09_11_144858_create_webhook_notification_settings.php create mode 100644 resources/views/forms/components/test-webhook-notification.blade.php diff --git a/app/Filament/Pages/Settings/NotificationPage.php b/app/Filament/Pages/Settings/NotificationPage.php index 49dfaeaad..fa1164862 100755 --- a/app/Filament/Pages/Settings/NotificationPage.php +++ b/app/Filament/Pages/Settings/NotificationPage.php @@ -162,6 +162,45 @@ public function form(Form $form): Form 'default' => 1, 'md' => 2, ]), + + Forms\Components\Section::make('Webhook') + ->schema([ + Forms\Components\Toggle::make('webhook_enabled') + ->label('Enable webhook notifications') + ->reactive() + ->columnSpan(2), + Forms\Components\Grid::make([ + 'default' => 1, ]) + ->hidden(fn (Forms\Get $get) => $get('webhook_enabled') !== true) + ->schema([ + Forms\Components\Fieldset::make('Triggers') + ->schema([ + Forms\Components\Toggle::make('webhook_on_speedtest_run') + ->label('Notify on every speedtest run') + ->columnSpan(2), + Forms\Components\Toggle::make('webhook_on_threshold_failure') + ->label('Notify on threshold failures') + ->columnSpan(2), + ]), + ]), + Forms\Components\Repeater::make('webhook_urls') + ->label('Recipients') + ->schema([ + Forms\Components\TextInput::make('url') + ->maxLength(100) + ->required() + ->columnSpan(['md' => 2]), + ]) + ->hidden(fn (Forms\Get $get) => $get('webhook_enabled') !== true) + ->columnSpan(['md' => 2]), + TestTelegramNotification::make('test channel') + ->hidden(fn (Forms\Get $get) => $get('webhook_enabled') !== true), + ]) + ->compact() + ->columns([ + 'default' => 1, + 'md' => 2, + ]), ]) ->columnSpan([ 'md' => 2, diff --git a/app/Forms/Components/TestWebhookNotification.php b/app/Forms/Components/TestWebhookNotification.php new file mode 100644 index 000000000..bef9b34ee --- /dev/null +++ b/app/Forms/Components/TestWebhookNotification.php @@ -0,0 +1,10 @@ +notificationSettings->webhook_enabled) { + if ($this->notificationSettings->webhook_on_speedtest_run && count($this->notificationSettings->webhook_urls)) { + foreach ($this->notificationSettings->webhook_urls as $url) { + Http::post($url['url'], [ + 'result_id' => $event->result->id, + 'site_name' => $this->generalSettings->site_name, + 'ping' => $event->result->ping, + 'download' => toBits(convertSize($event->result->download)), + 'upload' => toBits(convertSize($event->result->upload)), + ]); + } + } + } } } diff --git a/app/Listeners/Threshold/AbsoluteListener.php b/app/Listeners/Threshold/AbsoluteListener.php index b5a4c3012..b588f0a9c 100644 --- a/app/Listeners/Threshold/AbsoluteListener.php +++ b/app/Listeners/Threshold/AbsoluteListener.php @@ -10,6 +10,7 @@ use App\Telegram\TelegramNotification; use Filament\Notifications\Notification; use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Mail; @@ -60,6 +61,11 @@ public function handle(ResultCreated $event): void if ($this->notificationSettings->telegram_enabled == true && $this->notificationSettings->telegram_on_threshold_failure == true) { $this->telegramChannel($event); } + + // Webhook notification channel + if ($this->notificationSettings->webhook_enabled == true && $this->notificationSettings->webhook_on_threshold_failure == true) { + $this->webhookChannel($event); + } } /** @@ -211,4 +217,59 @@ protected function telegramChannel(ResultCreated $event): void } } } + + /** + * Handle webhook notifications. + */ + protected function webhookChannel(ResultCreated $event): void + { + $failedThresholds = []; + + if (! count($this->notificationSettings->webhook_urls) > 0) { + Log::info('Skipping sending webhook notification, no urls.'); + } + + // Download threshold + if ($this->thresholdSettings->absolute_download > 0) { + if (absoluteDownloadThresholdFailed($this->thresholdSettings->absolute_download, $event->result->download)) { + array_push($failedThresholds, [ + 'name' => 'Download', + 'threshold' => $this->thresholdSettings->absolute_download, + 'value' => toBits(convertSize($event->result->download), 2), + ]); + } + } + + // Upload threshold + if ($this->thresholdSettings->absolute_upload > 0) { + if (absoluteUploadThresholdFailed($this->thresholdSettings->absolute_upload, $event->result->upload)) { + array_push($failedThresholds, [ + 'name' => 'Upload', + 'threshold' => $this->thresholdSettings->absolute_upload, + 'value' => toBits(convertSize($event->result->upload), 2), + ]); + } + } + + // Ping threshold + if ($this->thresholdSettings->absolute_ping > 0) { + if (absolutePingThresholdFailed($this->thresholdSettings->absolute_ping, $event->result->ping)) { + array_push($failedThresholds, [ + 'name' => 'Ping', + 'threshold' => $this->thresholdSettings->absolute_ping, + 'value' => round($event->result->ping, 2), + ]); + } + } + + if (count($failedThresholds)) { + foreach ($this->notificationSettings->webhook_urls as $url) { + Http::post($url['url'], [ + 'result_id' => $event->result->id, + 'site_name' => $this->generalSettings->site_name, + 'metrics' => $failedThresholds, + ]); + } + } + } } diff --git a/app/Settings/NotificationSettings.php b/app/Settings/NotificationSettings.php index 182794dc8..f23dfdbf6 100644 --- a/app/Settings/NotificationSettings.php +++ b/app/Settings/NotificationSettings.php @@ -28,6 +28,14 @@ class NotificationSettings extends Settings public ?array $telegram_recipients; + public bool $webhook_enabled; + + public bool $webhook_on_speedtest_run; + + public bool $webhook_on_threshold_failure; + + public ?array $webhook_urls; + public static function group(): string { return 'notification'; diff --git a/database/migrations/2023_09_11_144858_create_webhook_notification_settings.php b/database/migrations/2023_09_11_144858_create_webhook_notification_settings.php new file mode 100644 index 000000000..23d51c5dc --- /dev/null +++ b/database/migrations/2023_09_11_144858_create_webhook_notification_settings.php @@ -0,0 +1,17 @@ +migrator->add('notification.webhook_enabled', false); + $this->migrator->add('notification.webhook_on_speedtest_run', false); + $this->migrator->add('notification.webhook_on_threshold_failure', false); + $this->migrator->add('notification.webhook_urls', null); + } +}; diff --git a/resources/views/forms/components/test-webhook-notification.blade.php b/resources/views/forms/components/test-webhook-notification.blade.php new file mode 100644 index 000000000..f034fb7c3 --- /dev/null +++ b/resources/views/forms/components/test-webhook-notification.blade.php @@ -0,0 +1,5 @@ +
+ + Test webhook channel + +
From 298d753f83d880b846fbdfcd692c8188e98ff7e6 Mon Sep 17 00:00:00 2001 From: Alex Justesen Date: Sat, 3 Feb 2024 09:08:26 -0500 Subject: [PATCH 2/3] made string translatable --- .../views/forms/components/test-webhook-notification.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/forms/components/test-webhook-notification.blade.php b/resources/views/forms/components/test-webhook-notification.blade.php index f034fb7c3..8a382fc05 100644 --- a/resources/views/forms/components/test-webhook-notification.blade.php +++ b/resources/views/forms/components/test-webhook-notification.blade.php @@ -1,5 +1,5 @@
- Test webhook channel + {{ __('Test webhook channel') }}
From fe9252baa4fb70e31c8b1f1d50e163c5decbf4ae Mon Sep 17 00:00:00 2001 From: Alex Justesen Date: Sat, 3 Feb 2024 09:09:27 -0500 Subject: [PATCH 3/3] use webhook notification button --- app/Filament/Pages/Settings/NotificationPage.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Filament/Pages/Settings/NotificationPage.php b/app/Filament/Pages/Settings/NotificationPage.php index fa1164862..6688ecaff 100755 --- a/app/Filament/Pages/Settings/NotificationPage.php +++ b/app/Filament/Pages/Settings/NotificationPage.php @@ -5,6 +5,7 @@ use App\Forms\Components\TestDatabaseNotification; use App\Forms\Components\TestMailNotification; use App\Forms\Components\TestTelegramNotification; +use App\Forms\Components\TestWebhookNotification; use App\Mail\Test; use App\Notifications\Telegram\TestNotification as TelegramTestNotification; use App\Settings\NotificationSettings; @@ -193,7 +194,7 @@ public function form(Form $form): Form ]) ->hidden(fn (Forms\Get $get) => $get('webhook_enabled') !== true) ->columnSpan(['md' => 2]), - TestTelegramNotification::make('test channel') + TestWebhookNotification::make('test channel') ->hidden(fn (Forms\Get $get) => $get('webhook_enabled') !== true), ]) ->compact()