Skip to content

Commit 755ba47

Browse files
authored
Telegram notification channel (alexjustesen#265)
1 parent 81059d5 commit 755ba47

File tree

13 files changed

+322
-0
lines changed

13 files changed

+322
-0
lines changed

app/Filament/Pages/Settings/NotificationPage.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44

55
use App\Forms\Components\TestDatabaseNotification;
66
use App\Forms\Components\TestMailNotification;
7+
use App\Forms\Components\TestTelegramNotification;
78
use App\Mail\Test;
89
use App\Settings\NotificationSettings;
10+
use App\Telegram\TelegramNotification;
911
use Closure;
1012
use Filament\Forms\Components\Card;
1113
use Filament\Forms\Components\Fieldset;
@@ -113,6 +115,44 @@ protected function getFormSchema(): array
113115
'default' => 1,
114116
'md' => 2,
115117
]),
118+
Section::make('Telegram')
119+
->schema([
120+
Toggle::make('telegram_enabled')
121+
->label('Enable telegram notifications')
122+
->reactive()
123+
->columnSpan(2),
124+
Grid::make([
125+
'default' => 1, ])
126+
->hidden(fn (Closure $get) => $get('telegram_enabled') !== true)
127+
->schema([
128+
Fieldset::make('Triggers')
129+
->schema([
130+
Toggle::make('telegram_on_speedtest_run')
131+
->label('Notify on every speetest run')
132+
->columnSpan(2),
133+
Toggle::make('telegram_on_threshold_failure')
134+
->label('Notify on threshold failures')
135+
->columnSpan(2),
136+
]),
137+
]),
138+
Repeater::make('telegram_recipients')
139+
->label('Recipients')
140+
->schema([
141+
TextInput::make('telegram_chat_id')
142+
->maxLength(50)
143+
->required()
144+
->columnSpan(['md' => 2]),
145+
])
146+
->hidden(fn (Closure $get) => $get('telegram_enabled') !== true)
147+
->columnSpan(['md' => 2]),
148+
TestTelegramNotification::make('test channel')
149+
->hidden(fn (Closure $get) => $get('telegram_enabled') !== true),
150+
])
151+
->compact()
152+
->columns([
153+
'default' => 1,
154+
'md' => 2,
155+
]),
116156
])
117157
->columnSpan([
118158
'md' => 2,
@@ -169,4 +209,26 @@ public function sendTestMailNotification()
169209
->send();
170210
}
171211
}
212+
213+
public function sendTestTelegramNotification()
214+
{
215+
$notificationSettings = new (NotificationSettings::class);
216+
217+
if (count($notificationSettings->telegram_recipients)) {
218+
foreach ($notificationSettings->telegram_recipients as $recipient) {
219+
\Illuminate\Support\Facades\Notification::route('telegram_chat_id', $recipient['telegram_chat_id'])
220+
->notify(new TelegramNotification('Test notification channel *telegram*'));
221+
}
222+
223+
Notification::make()
224+
->title('Test telegram notification sent.')
225+
->success()
226+
->send();
227+
} else {
228+
Notification::make()
229+
->title('You need to add recipients to receive telegram notifications.')
230+
->warning()
231+
->send();
232+
}
233+
}
172234
}
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 TestTelegramNotification extends Field
8+
{
9+
protected string $view = 'forms.components.test-telegram-notification';
10+
}

app/Listeners/SpeedtestCompletedListener.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use App\Events\ResultCreated;
66
use App\Mail\SpeedtestCompletedMail;
77
use App\Settings\NotificationSettings;
8+
use App\Telegram\TelegramNotification;
89
use Filament\Notifications\Notification;
910
use Illuminate\Support\Facades\Mail;
1011

@@ -47,5 +48,25 @@ public function handle(ResultCreated $event)
4748
}
4849
}
4950
}
51+
52+
if ($this->notificationSettings->telegram_enabled) {
53+
if ($this->notificationSettings->telegram_on_speedtest_run && count($this->notificationSettings->telegram_recipients)) {
54+
foreach ($this->notificationSettings->telegram_recipients as $recipient) {
55+
$download_value = formatBits(formatBytesToBits($event->result->download)).'ps';
56+
$upload_value = formatBits(formatBytesToBits($event->result->upload)).'ps';
57+
$ping_value = round($event->result->ping, 2);
58+
59+
$message = view('telegram.speedtest-completed', [
60+
'id' => $event->result->id,
61+
'ping' => $ping_value,
62+
'download' => $download_value,
63+
'upload' => $upload_value,
64+
])->render();
65+
66+
\Illuminate\Support\Facades\Notification::route('telegram_chat_id', $recipient['telegram_chat_id'])
67+
->notify(new TelegramNotification($message));
68+
}
69+
}
70+
}
5071
}
5172
}

app/Listeners/Threshold/AbsoluteListener.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use App\Mail\Threshold\AbsoluteMail;
77
use App\Settings\NotificationSettings;
88
use App\Settings\ThresholdSettings;
9+
use App\Telegram\TelegramNotification;
910
use Filament\Notifications\Notification;
1011
use Illuminate\Contracts\Queue\ShouldQueue;
1112
use Illuminate\Support\Facades\Log;
@@ -52,6 +53,11 @@ public function handle(ResultCreated $event)
5253
if ($this->notificationSettings->mail_enabled == true && $this->notificationSettings->mail_on_threshold_failure == true) {
5354
$this->mailChannel($event);
5455
}
56+
57+
// Telegram notification channel
58+
if ($this->notificationSettings->telegram_enabled == true && $this->notificationSettings->telegram_on_threshold_failure == true) {
59+
$this->telegramChannel($event);
60+
}
5561
}
5662

5763
/**
@@ -150,4 +156,65 @@ protected function mailChannel(ResultCreated $event)
150156
}
151157
}
152158
}
159+
160+
/**
161+
* Handle telegram notifications.
162+
*
163+
* @param \App\Events\ResultCreated $event
164+
* @return void
165+
*/
166+
protected function telegramChannel(ResultCreated $event)
167+
{
168+
$failedThresholds = [];
169+
170+
if (! count($this->notificationSettings->telegram_recipients) > 0) {
171+
Log::info('Skipping sending telegram notification, no recipients.');
172+
}
173+
174+
// Download threshold
175+
if ($this->thresholdSettings->absolute_download > 0) {
176+
if (absoluteDownloadThresholdFailed($this->thresholdSettings->absolute_download, $event->result->download)) {
177+
array_push($failedThresholds, [
178+
'name' => 'Download',
179+
'threshold' => $this->thresholdSettings->absolute_download.' Mbps',
180+
'value' => formatBits(formatBytesToBits($event->result->download)).'ps',
181+
]);
182+
}
183+
}
184+
185+
// Upload threshold
186+
if ($this->thresholdSettings->absolute_upload > 0) {
187+
if (absoluteUploadThresholdFailed($this->thresholdSettings->absolute_upload, $event->result->upload)) {
188+
array_push($failedThresholds, [
189+
'name' => 'Upload',
190+
'threshold' => $this->thresholdSettings->absolute_upload.' Mbps',
191+
'value' => formatBits(formatBytesToBits($event->result->upload)).'ps',
192+
]);
193+
}
194+
}
195+
196+
// Ping threshold
197+
if ($this->thresholdSettings->absolute_ping > 0) {
198+
if (absolutePingThresholdFailed($this->thresholdSettings->absolute_ping, $event->result->ping)) {
199+
array_push($failedThresholds, [
200+
'name' => 'Ping',
201+
'threshold' => $this->thresholdSettings->absolute_ping.' Ms',
202+
'value' => round($event->result->ping, 2).' Ms',
203+
]);
204+
}
205+
}
206+
207+
if (count($failedThresholds)) {
208+
foreach ($this->notificationSettings->telegram_recipients as $recipient) {
209+
$message = view('telegram.threshold.absolute', [
210+
'id' => $event->result->id,
211+
'url' => url('/admin/results'),
212+
'metrics' => $failedThresholds,
213+
])->render();
214+
215+
\Illuminate\Support\Facades\Notification::route('telegram_chat_id', $recipient['telegram_chat_id'])
216+
->notify(new TelegramNotification($message));
217+
}
218+
}
219+
}
153220
}

app/Settings/NotificationSettings.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ class NotificationSettings extends Settings
2020

2121
public ?array $mail_recipients;
2222

23+
public bool $telegram_enabled;
24+
25+
public bool $telegram_on_speedtest_run;
26+
27+
public bool $telegram_on_threshold_failure;
28+
29+
public ?array $telegram_recipients;
30+
2331
public static function group(): string
2432
{
2533
return 'notification';
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
namespace App\Telegram;
4+
5+
use Illuminate\Bus\Queueable;
6+
use Illuminate\Notifications\Notification;
7+
use NotificationChannels\Telegram\TelegramMessage;
8+
9+
class TelegramNotification extends Notification
10+
{
11+
use Queueable;
12+
13+
protected $message;
14+
15+
/**
16+
* Create a new notification instance.
17+
*
18+
* @return void
19+
*/
20+
public function __construct($message)
21+
{
22+
$this->message = $message;
23+
}
24+
25+
/**
26+
* Get the notification's delivery channels.
27+
*
28+
* @param mixed $notifiable
29+
* @return array
30+
*/
31+
public function via($notifiable)
32+
{
33+
return ['telegram'];
34+
}
35+
36+
/**
37+
* Get the mail representation of the notification.
38+
*
39+
* @param mixed $notifiable
40+
* @return \Illuminate\Notifications\Messages\MailMessage
41+
*/
42+
public function toTelegram($notifiable)
43+
{
44+
return TelegramMessage::create()
45+
->to($notifiable->routes['telegram_chat_id'])
46+
->content($this->message);
47+
}
48+
}

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"filament/spatie-laravel-settings-plugin": "^2.0",
1414
"guzzlehttp/guzzle": "^7.2",
1515
"influxdata/influxdb-client-php": "^2.9",
16+
"laravel-notification-channels/telegram": "^3.0",
1617
"laravel/framework": "^9.19",
1718
"laravel/sanctum": "^3.0",
1819
"laravel/tinker": "^2.7",

composer.lock

Lines changed: 73 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/services.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,8 @@
3131
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
3232
],
3333

34+
'telegram-bot-api' => [
35+
'token' => env('TELEGRAM_BOT_TOKEN', 'YOUR BOT TOKEN HERE'),
36+
],
37+
3438
];
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
use Spatie\LaravelSettings\Migrations\SettingsMigration;
4+
5+
class CreateTelegramNotificationSettings extends SettingsMigration
6+
{
7+
public function up(): void
8+
{
9+
$this->migrator->add('notification.telegram_enabled', false);
10+
$this->migrator->add('notification.telegram_on_speedtest_run', false);
11+
$this->migrator->add('notification.telegram_on_threshold_failure', false);
12+
$this->migrator->add('notification.telegram_recipients', null);
13+
}
14+
}

0 commit comments

Comments
 (0)