mirror of
https://github.com/alexjustesen/speedtest-tracker.git
synced 2026-06-23 07:20:09 +00:00
[Feature] Discord Webhook Functionality (#1196)
Co-authored-by: Alex Justesen <alexjustesen@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Notifications;
|
||||
|
||||
use Filament\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Lorisleiva\Actions\Concerns\AsAction;
|
||||
|
||||
class SendDiscordTestNotification
|
||||
{
|
||||
use AsAction;
|
||||
|
||||
public function handle(array $webhooks)
|
||||
{
|
||||
if (! count($webhooks)) {
|
||||
Notification::make()
|
||||
->title('You need to add webhook urls!')
|
||||
->warning()
|
||||
->send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($webhooks as $webhook) {
|
||||
$payload = [
|
||||
'content' => '👋 Testing the Webhook notification channel.',
|
||||
];
|
||||
// Send the request using Laravel's HTTP client
|
||||
$response = Http::post($webhook['discord_webhook_url'], $payload);
|
||||
}
|
||||
|
||||
Notification::make()
|
||||
->title('Test webhook notification sent.')
|
||||
->success()
|
||||
->send();
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Filament\Pages\Settings;
|
||||
|
||||
use App\Actions\Notifications\SendDatabaseTestNotification;
|
||||
use App\Actions\Notifications\SendDiscordTestNotification;
|
||||
use App\Actions\Notifications\SendMailTestNotification;
|
||||
use App\Actions\Notifications\SendTelegramTestNotification;
|
||||
use App\Actions\Notifications\SendWebhookTestNotification;
|
||||
@@ -85,6 +86,48 @@ class NotificationPage extends SettingsPage
|
||||
'md' => 2,
|
||||
]),
|
||||
|
||||
Forms\Components\Section::make('Discord')
|
||||
->schema([
|
||||
Forms\Components\Toggle::make('discord_enabled')
|
||||
->label('Enable Discord webhook notifications')
|
||||
->reactive()
|
||||
->columnSpanFull(),
|
||||
Forms\Components\Grid::make([
|
||||
'default' => 1,
|
||||
])
|
||||
->hidden(fn (Forms\Get $get) => $get('discord_enabled') !== true)
|
||||
->schema([
|
||||
Forms\Components\Fieldset::make('Triggers')
|
||||
->schema([
|
||||
Forms\Components\Toggle::make('discord_on_speedtest_run')
|
||||
->label('Notify on every speedtest run')
|
||||
->columnSpanFull(),
|
||||
Forms\Components\Toggle::make('discord_on_threshold_failure')
|
||||
->label('Notify on threshold failures')
|
||||
->columnSpanFull(),
|
||||
]),
|
||||
Forms\Components\Repeater::make('discord_webhooks')
|
||||
->label('Webhooks')
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('discord_webhook_url')
|
||||
->label('Webhook URL')
|
||||
->required(),
|
||||
])
|
||||
->columnSpanFull(),
|
||||
Forms\Components\Actions::make([
|
||||
Forms\Components\Actions\Action::make('test discord')
|
||||
->label('Test Discord webhook')
|
||||
->action(fn (Forms\Get $get) => SendDiscordTestNotification::run(webhooks: $get('discord_webhooks')))
|
||||
->hidden(fn (Forms\Get $get) => ! count($get('discord_webhooks'))),
|
||||
]),
|
||||
]),
|
||||
])
|
||||
->compact()
|
||||
->columns([
|
||||
'default' => 1,
|
||||
'md' => 2,
|
||||
]),
|
||||
|
||||
Forms\Components\Section::make('Mail')
|
||||
->schema([
|
||||
Forms\Components\Toggle::make('mail_enabled')
|
||||
|
||||
@@ -8,6 +8,7 @@ use App\Settings\GeneralSettings;
|
||||
use App\Settings\NotificationSettings;
|
||||
use App\Telegram\TelegramNotification;
|
||||
use Filament\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Spatie\WebhookServer\WebhookCall;
|
||||
|
||||
@@ -75,6 +76,24 @@ class SpeedtestCompletedListener
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->notificationSettings->discord_enabled) {
|
||||
if ($this->notificationSettings->discord_on_speedtest_run && count($this->notificationSettings->discord_webhooks)) {
|
||||
foreach ($this->notificationSettings->discord_webhooks as $webhook) {
|
||||
// Construct the payload
|
||||
$payload = [
|
||||
'content' => 'There are new speedtest results for your network.'.
|
||||
"\nResult ID: ".$event->result->id.
|
||||
"\nSite Name: ".$this->generalSettings->site_name.
|
||||
"\nPing: ".$event->result->ping.' ms'.
|
||||
"\nDownload: ".($event->result->downloadBits / 1000000).' (Mbps)'.
|
||||
"\nUpload: ".($event->result->uploadBits / 1000000).' (Mbps)',
|
||||
];
|
||||
// Send the request using Laravel's HTTP client
|
||||
$response = Http::post($webhook['discord_webhook_url'], $payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->notificationSettings->webhook_enabled) {
|
||||
if ($this->notificationSettings->webhook_on_speedtest_run && count($this->notificationSettings->webhook_urls)) {
|
||||
foreach ($this->notificationSettings->webhook_urls as $url) {
|
||||
|
||||
@@ -63,6 +63,11 @@ class AbsoluteListener implements ShouldQueue
|
||||
$this->telegramChannel($event);
|
||||
}
|
||||
|
||||
// Discord notification channel
|
||||
if ($this->notificationSettings->discord_enabled == true && $this->notificationSettings->discord_on_threshold_failure == true) {
|
||||
$this->discordChannel($event);
|
||||
}
|
||||
|
||||
// Webhook notification channel
|
||||
if ($this->notificationSettings->webhook_enabled == true && $this->notificationSettings->webhook_on_threshold_failure == true) {
|
||||
$this->webhookChannel($event);
|
||||
@@ -219,6 +224,55 @@ class AbsoluteListener implements ShouldQueue
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Discord notifications.
|
||||
*/
|
||||
protected function discordChannel(ResultCreated $event): void
|
||||
{
|
||||
if ($this->notificationSettings->discord_enabled) {
|
||||
$failedThresholds = []; // Initialize an array to keep track of failed thresholds
|
||||
|
||||
// Check Download threshold
|
||||
if ($this->thresholdSettings->absolute_download > 0 && absoluteDownloadThresholdFailed($this->thresholdSettings->absolute_download, $event->result->downloadBits)) {
|
||||
$failedThresholds['Download'] = ($event->result->downloadBits / 1000000).' (Mbps)';
|
||||
}
|
||||
|
||||
// Check Upload threshold
|
||||
if ($this->thresholdSettings->absolute_upload > 0 && absoluteUploadThresholdFailed($this->thresholdSettings->absolute_upload, $event->result->uploadBits)) {
|
||||
$failedThresholds['Upload'] = ($event->result->uploadBits / 1000000).' (Mbps)';
|
||||
}
|
||||
|
||||
// Check Ping threshold
|
||||
if ($this->thresholdSettings->absolute_ping > 0 && absolutePingThresholdFailed($this->thresholdSettings->absolute_ping, $event->result->ping)) {
|
||||
$failedThresholds['Ping'] = $event->result->ping.' ms';
|
||||
}
|
||||
|
||||
// Proceed with sending notifications only if there are any failed thresholds
|
||||
if (count($failedThresholds) > 0) {
|
||||
if ($this->notificationSettings->discord_on_threshold_failure && count($this->notificationSettings->discord_webhooks)) {
|
||||
foreach ($this->notificationSettings->discord_webhooks as $webhook) {
|
||||
// Construct the payload with the failed thresholds information
|
||||
$contentLines = [
|
||||
'Result ID: '.$event->result->id,
|
||||
'Site Name: '.$this->generalSettings->site_name,
|
||||
];
|
||||
|
||||
foreach ($failedThresholds as $metric => $result) {
|
||||
$contentLines[] = "{$metric} threshold failed with result: {$result}.";
|
||||
}
|
||||
|
||||
$payload = [
|
||||
'content' => implode("\n", $contentLines),
|
||||
];
|
||||
|
||||
// Send the request using Laravel's HTTP client
|
||||
$response = Http::post($webhook['discord_webhook_url'], $payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle webhook notifications.
|
||||
*
|
||||
|
||||
@@ -38,6 +38,14 @@ class NotificationSettings extends Settings
|
||||
|
||||
public ?array $webhook_urls;
|
||||
|
||||
public bool $discord_enabled;
|
||||
|
||||
public bool $discord_on_speedtest_run;
|
||||
|
||||
public bool $discord_on_threshold_failure;
|
||||
|
||||
public ?array $discord_webhooks;
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'notification';
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
use Spatie\LaravelSettings\Migrations\SettingsMigration;
|
||||
|
||||
return new class extends SettingsMigration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
$this->migrator->add('notification.discord_enabled', false);
|
||||
$this->migrator->add('notification.discord_on_speedtest_run', false);
|
||||
$this->migrator->add('notification.discord_on_threshold_failure', false);
|
||||
$this->migrator->add('notification.discord_webhooks', null);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user