Skip to content

Commit

Permalink
Telegram notification channel (#265)
Browse files Browse the repository at this point in the history
  • Loading branch information
garanda21 authored Jan 12, 2023
1 parent 81059d5 commit 755ba47
Show file tree
Hide file tree
Showing 13 changed files with 322 additions and 0 deletions.
62 changes: 62 additions & 0 deletions app/Filament/Pages/Settings/NotificationPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

use App\Forms\Components\TestDatabaseNotification;
use App\Forms\Components\TestMailNotification;
use App\Forms\Components\TestTelegramNotification;
use App\Mail\Test;
use App\Settings\NotificationSettings;
use App\Telegram\TelegramNotification;
use Closure;
use Filament\Forms\Components\Card;
use Filament\Forms\Components\Fieldset;
Expand Down Expand Up @@ -113,6 +115,44 @@ protected function getFormSchema(): array
'default' => 1,
'md' => 2,
]),
Section::make('Telegram')
->schema([
Toggle::make('telegram_enabled')
->label('Enable telegram notifications')
->reactive()
->columnSpan(2),
Grid::make([
'default' => 1, ])
->hidden(fn (Closure $get) => $get('telegram_enabled') !== true)
->schema([
Fieldset::make('Triggers')
->schema([
Toggle::make('telegram_on_speedtest_run')
->label('Notify on every speetest run')
->columnSpan(2),
Toggle::make('telegram_on_threshold_failure')
->label('Notify on threshold failures')
->columnSpan(2),
]),
]),
Repeater::make('telegram_recipients')
->label('Recipients')
->schema([
TextInput::make('telegram_chat_id')
->maxLength(50)
->required()
->columnSpan(['md' => 2]),
])
->hidden(fn (Closure $get) => $get('telegram_enabled') !== true)
->columnSpan(['md' => 2]),
TestTelegramNotification::make('test channel')
->hidden(fn (Closure $get) => $get('telegram_enabled') !== true),
])
->compact()
->columns([
'default' => 1,
'md' => 2,
]),
])
->columnSpan([
'md' => 2,
Expand Down Expand Up @@ -169,4 +209,26 @@ public function sendTestMailNotification()
->send();
}
}

public function sendTestTelegramNotification()
{
$notificationSettings = new (NotificationSettings::class);

if (count($notificationSettings->telegram_recipients)) {
foreach ($notificationSettings->telegram_recipients as $recipient) {
\Illuminate\Support\Facades\Notification::route('telegram_chat_id', $recipient['telegram_chat_id'])
->notify(new TelegramNotification('Test notification channel *telegram*'));
}

Notification::make()
->title('Test telegram notification sent.')
->success()
->send();
} else {
Notification::make()
->title('You need to add recipients to receive telegram notifications.')
->warning()
->send();
}
}
}
10 changes: 10 additions & 0 deletions app/Forms/Components/TestTelegramNotification.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace App\Forms\Components;

use Filament\Forms\Components\Field;

class TestTelegramNotification extends Field
{
protected string $view = 'forms.components.test-telegram-notification';
}
21 changes: 21 additions & 0 deletions app/Listeners/SpeedtestCompletedListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use App\Events\ResultCreated;
use App\Mail\SpeedtestCompletedMail;
use App\Settings\NotificationSettings;
use App\Telegram\TelegramNotification;
use Filament\Notifications\Notification;
use Illuminate\Support\Facades\Mail;

Expand Down Expand Up @@ -47,5 +48,25 @@ public function handle(ResultCreated $event)
}
}
}

if ($this->notificationSettings->telegram_enabled) {
if ($this->notificationSettings->telegram_on_speedtest_run && count($this->notificationSettings->telegram_recipients)) {
foreach ($this->notificationSettings->telegram_recipients as $recipient) {
$download_value = formatBits(formatBytesToBits($event->result->download)).'ps';
$upload_value = formatBits(formatBytesToBits($event->result->upload)).'ps';
$ping_value = round($event->result->ping, 2);

$message = view('telegram.speedtest-completed', [
'id' => $event->result->id,
'ping' => $ping_value,
'download' => $download_value,
'upload' => $upload_value,
])->render();

\Illuminate\Support\Facades\Notification::route('telegram_chat_id', $recipient['telegram_chat_id'])
->notify(new TelegramNotification($message));
}
}
}
}
}
67 changes: 67 additions & 0 deletions app/Listeners/Threshold/AbsoluteListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use App\Mail\Threshold\AbsoluteMail;
use App\Settings\NotificationSettings;
use App\Settings\ThresholdSettings;
use App\Telegram\TelegramNotification;
use Filament\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Log;
Expand Down Expand Up @@ -52,6 +53,11 @@ public function handle(ResultCreated $event)
if ($this->notificationSettings->mail_enabled == true && $this->notificationSettings->mail_on_threshold_failure == true) {
$this->mailChannel($event);
}

// Telegram notification channel
if ($this->notificationSettings->telegram_enabled == true && $this->notificationSettings->telegram_on_threshold_failure == true) {
$this->telegramChannel($event);
}
}

/**
Expand Down Expand Up @@ -150,4 +156,65 @@ protected function mailChannel(ResultCreated $event)
}
}
}

/**
* Handle telegram notifications.
*
* @param \App\Events\ResultCreated $event
* @return void
*/
protected function telegramChannel(ResultCreated $event)
{
$failedThresholds = [];

if (! count($this->notificationSettings->telegram_recipients) > 0) {
Log::info('Skipping sending telegram notification, no recipients.');
}

// 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.' Mbps',
'value' => formatBits(formatBytesToBits($event->result->download)).'ps',
]);
}
}

// 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.' Mbps',
'value' => formatBits(formatBytesToBits($event->result->upload)).'ps',
]);
}
}

// 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.' Ms',
'value' => round($event->result->ping, 2).' Ms',
]);
}
}

if (count($failedThresholds)) {
foreach ($this->notificationSettings->telegram_recipients as $recipient) {
$message = view('telegram.threshold.absolute', [
'id' => $event->result->id,
'url' => url('/admin/results'),
'metrics' => $failedThresholds,
])->render();

\Illuminate\Support\Facades\Notification::route('telegram_chat_id', $recipient['telegram_chat_id'])
->notify(new TelegramNotification($message));
}
}
}
}
8 changes: 8 additions & 0 deletions app/Settings/NotificationSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ class NotificationSettings extends Settings

public ?array $mail_recipients;

public bool $telegram_enabled;

public bool $telegram_on_speedtest_run;

public bool $telegram_on_threshold_failure;

public ?array $telegram_recipients;

public static function group(): string
{
return 'notification';
Expand Down
48 changes: 48 additions & 0 deletions app/Telegram/TelegramNotification.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace App\Telegram;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use NotificationChannels\Telegram\TelegramMessage;

class TelegramNotification extends Notification
{
use Queueable;

protected $message;

/**
* Create a new notification instance.
*
* @return void
*/
public function __construct($message)
{
$this->message = $message;
}

/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return ['telegram'];
}

/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toTelegram($notifiable)
{
return TelegramMessage::create()
->to($notifiable->routes['telegram_chat_id'])
->content($this->message);
}
}
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"filament/spatie-laravel-settings-plugin": "^2.0",
"guzzlehttp/guzzle": "^7.2",
"influxdata/influxdb-client-php": "^2.9",
"laravel-notification-channels/telegram": "^3.0",
"laravel/framework": "^9.19",
"laravel/sanctum": "^3.0",
"laravel/tinker": "^2.7",
Expand Down
73 changes: 73 additions & 0 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,8 @@
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],

'telegram-bot-api' => [
'token' => env('TELEGRAM_BOT_TOKEN', 'YOUR BOT TOKEN HERE'),
],

];
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

use Spatie\LaravelSettings\Migrations\SettingsMigration;

class CreateTelegramNotificationSettings extends SettingsMigration
{
public function up(): void
{
$this->migrator->add('notification.telegram_enabled', false);
$this->migrator->add('notification.telegram_on_speedtest_run', false);
$this->migrator->add('notification.telegram_on_threshold_failure', false);
$this->migrator->add('notification.telegram_recipients', null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div>
<x-filament::button wire:click="sendTestTelegramNotification()">
Test telegram channel
</x-filament::button>
</div>
Loading

0 comments on commit 755ba47

Please sign in to comment.