WIP notifications and other refactors (#88)

* WIP notifications and other refactors
- refactor notification channels
- send notifications on events related to the servers and sites
- delete server log files on server deletion
- add telegram notification channel
- add new icons
- cache configs and icons on installation and updates
- new navbar for dark mode and settings

* discord channel

* build assets

* pint
This commit is contained in:
Saeed Vaziry
2024-01-07 09:54:08 +01:00
committed by GitHub
parent f06b8f7d20
commit e997d0deea
72 changed files with 1153 additions and 480 deletions

View File

@ -0,0 +1,13 @@
<?php
namespace App\NotificationChannels;
use App\Contracts\NotificationChannel as NotificationChannelInterface;
use App\Models\NotificationChannel;
abstract class AbstractNotificationChannel implements NotificationChannelInterface
{
public function __construct(protected NotificationChannel $notificationChannel)
{
}
}

View File

@ -1,16 +0,0 @@
<?php
namespace App\NotificationChannels;
use App\Contracts\NotificationChannel as NotificationChannelContract;
use App\Models\NotificationChannel;
abstract class AbstractProvider implements NotificationChannelContract
{
protected NotificationChannel $notificationChannel;
public function __construct(NotificationChannel $notificationChannel)
{
$this->notificationChannel = $notificationChannel;
}
}

View File

@ -2,21 +2,34 @@
namespace App\NotificationChannels;
use App\Contracts\Notification;
use Illuminate\Support\Facades\Http;
class Discord extends AbstractProvider
class Discord extends AbstractNotificationChannel
{
public function validationRules(): array
public function channel(): string
{
return 'discord';
}
public function createRules(array $input): array
{
return [
'webhook_url' => 'required|url',
];
}
public function data(array $input): array
public function createData(array $input): array
{
return [
'webhook_url' => $input['webhook_url'],
'webhook_url' => $input['webhook_url'] ?? '',
];
}
public function data(): array
{
return [
'webhook_url' => $this->notificationChannel->data['webhook_url'] ?? '',
];
}
@ -24,35 +37,37 @@ public function connect(): bool
{
$connect = $this->checkConnection(
__('Congratulations! 🎉'),
__("You've connected your Discord to Vito")."\n".
__("You've connected your Discord to :app", ['app' => config('app.name')])."\n".
__('Manage your notification channels')."\n".
route('notification-channels')
);
if (! $connect) {
$this->notificationChannel->delete();
return false;
}
$this->notificationChannel->connected = true;
$this->notificationChannel->save();
return true;
}
public function sendMessage(string $subject, string $text): void
{
dispatch(function () use ($subject, $text) {
$data = $this->notificationChannel->data;
Http::post($data['webhook_url'], [
'content' => '*'.$subject.'*'."\n".$text,
]);
});
}
private function checkConnection(string $subject, string $text): bool
{
$data = $this->notificationChannel->data;
$connect = Http::post($data['webhook_url'], [
$connect = Http::post($this->data()['webhook_url'], [
'content' => '*'.$subject.'*'."\n".$text,
]);
return $connect->ok();
}
public function send(object $notifiable, Notification $notification): void
{
$data = $this->notificationChannel->data;
Http::post($data['webhook_url'], [
'content' => $notification->toSlack($notifiable),
]);
}
}

View File

@ -2,36 +2,56 @@
namespace App\NotificationChannels;
use App\Mail\NotificationChannelMessage;
use App\Contracts\Notification;
use App\Mail\NotificationMail;
use App\Models\NotificationChannel;
use Illuminate\Support\Facades\Mail;
use Throwable;
class Email extends AbstractProvider
class Email extends AbstractNotificationChannel
{
public function validationRules(): array
public function createRules(array $input): array
{
return [
'email' => 'required|email',
];
}
public function data(array $input): array
public function createData(array $input): array
{
return [
'email' => $input['email'],
];
}
public function data(): array
{
return [
'email' => $this->notificationChannel->data['email'] ?? '',
];
}
public function connect(): bool
{
$this->notificationChannel->connected = true;
$this->notificationChannel->save();
try {
Mail::to($this->data()['email'])->send(
new NotificationMail('Test VitoDeploy', 'This is a test email!')
);
} catch (Throwable) {
return false;
}
return true;
}
public function sendMessage(string $subject, mixed $text): void
public function send(object $notifiable, Notification $notification): void
{
$data = $this->notificationChannel->data;
Mail::to($data['email'])->send(new NotificationChannelMessage($subject, $text));
/** @var NotificationChannel $notifiable */
$this->notificationChannel = $notifiable;
$message = $notification->toMail($notifiable);
Mail::to($this->data()['email'])->send(
new NotificationMail($message->subject, $message->render())
);
}
}

View File

@ -2,21 +2,34 @@
namespace App\NotificationChannels;
use App\Contracts\Notification;
use Illuminate\Support\Facades\Http;
class Slack extends AbstractProvider
class Slack extends AbstractNotificationChannel
{
public function validationRules(): array
public function channel(): string
{
return 'slack';
}
public function createRules(array $input): array
{
return [
'webhook_url' => 'required|url',
];
}
public function data(array $input): array
public function createData(array $input): array
{
return [
'webhook_url' => $input['webhook_url'],
'webhook_url' => $input['webhook_url'] ?? '',
];
}
public function data(): array
{
return [
'webhook_url' => $this->notificationChannel->data['webhook_url'] ?? '',
];
}
@ -24,35 +37,37 @@ public function connect(): bool
{
$connect = $this->checkConnection(
__('Congratulations! 🎉'),
__("You've connected your Slack to Vito")."\n".
__("You've connected your Slack to :app", ['app' => config('app.name')])."\n".
__('Manage your notification channels')."\n".
route('notification-channels')
);
if (! $connect) {
$this->notificationChannel->delete();
return false;
}
$this->notificationChannel->connected = true;
$this->notificationChannel->save();
return true;
}
public function sendMessage(string $subject, string $text): void
{
dispatch(function () use ($subject, $text) {
$data = $this->notificationChannel->data;
Http::post($data['webhook_url'], [
'text' => '*'.$subject.'*'."\n".$text,
]);
});
}
private function checkConnection(string $subject, string $text): bool
{
$data = $this->notificationChannel->data;
$connect = Http::post($data['webhook_url'], [
$connect = Http::post($this->data()['webhook_url'], [
'text' => '*'.$subject.'*'."\n".$text,
]);
return $connect->ok();
}
public function send(object $notifiable, Notification $notification): void
{
$data = $this->notificationChannel->data;
Http::post($data['webhook_url'], [
'text' => $notification->toSlack($notifiable),
]);
}
}

View File

@ -0,0 +1,67 @@
<?php
namespace App\NotificationChannels;
use App\Contracts\Notification;
use Illuminate\Support\Facades\Http;
use Throwable;
class Telegram extends AbstractNotificationChannel
{
protected string $apiUrl = 'https://api.telegram.org/bot';
public function channel(): string
{
return 'telegram';
}
public function createRules(array $input): array
{
return [
'bot_token' => 'required|string',
'chat_id' => 'required',
];
}
public function createData(array $input): array
{
return [
'bot_token' => $input['bot_token'],
'chat_id' => $input['chat_id'],
];
}
public function data(): array
{
return [
'bot_token' => $this->notificationChannel->data['bot_token'] ?? '',
'chat_id' => $this->notificationChannel->data['chat_id'] ?? '',
];
}
public function connect(): bool
{
try {
$this->sendToTelegram(__('Connected!'));
} catch (Throwable) {
return false;
}
return true;
}
public function send(object $notifiable, Notification $notification): void
{
$this->sendToTelegram($notification->toTelegram($notifiable));
}
private function sendToTelegram(string $text): void
{
Http::post($this->apiUrl.$this->data()['bot_token'].'/sendMessage', [
'chat_id' => $this->data()['chat_id'],
'text' => $text,
'parse_mode' => 'markdown',
'disable_web_page_preview' => true,
]);
}
}