Starts Notifications feature. Missing to send email with runtime configs.

This commit is contained in:
Joao Patricio
2023-05-19 18:01:56 +01:00
parent cd5655bd3f
commit 13fda50aac
16 changed files with 334 additions and 35 deletions

View File

@@ -0,0 +1,38 @@
<?php
namespace App\Http\Livewire\Settings;
use App\Models\InstanceSettings as ModelsInstanceSettings;
use App\Notifications\TestMessage;
use Illuminate\Support\Facades\Notification;
use Livewire\Component;
class DiscordNotifications extends Component
{
public ModelsInstanceSettings $settings;
protected $rules = [
'settings.extra_attributes.discord_webhook' => 'nullable|url',
];
protected $validationAttributes = [
'settings.extra_attributes.discord_webhook' => 'Discord Webhook',
];
public function mount($settings)
{
//
}
public function submit()
{
$this->resetErrorBag();
$this->validate();
$this->settings->save();
}
public function sentTestMessage()
{
// @TODO figure out how to do it in runtime
}
public function render()
{
return view('livewire.settings.discord-notifications');
}
}

View File

@@ -0,0 +1,49 @@
<?php
namespace App\Http\Livewire\Settings;
use App\Models\InstanceSettings as ModelsInstanceSettings;
use App\Notifications\TestMessage;
use Illuminate\Support\Facades\Notification;
use Livewire\Component;
class EmailNotifications extends Component
{
public ModelsInstanceSettings $settings;
protected $rules = [
'settings.extra_attributes.smtp_host' => 'nullable',
'settings.extra_attributes.smtp_port' => 'nullable',
'settings.extra_attributes.smtp_encryption' => 'nullable',
'settings.extra_attributes.smtp_username' => 'nullable',
'settings.extra_attributes.smtp_password' => 'nullable',
'settings.extra_attributes.smtp_timeout' => 'nullable',
];
protected $validationAttributes = [
'settings.extra_attributes.smtp_host' => 'Host',
'settings.extra_attributes.smtp_port' => 'Port',
'settings.extra_attributes.smtp_encryption' => 'Encryption',
'settings.extra_attributes.smtp_username' => 'Username',
'settings.extra_attributes.smtp_password' => 'Password',
'settings.extra_attributes.smtp_timeout' => 'Timeout',
];
public function mount($settings)
{
ray($settings);
//
}
public function submit()
{
$this->resetErrorBag();
$this->validate();
$this->settings->save();
}
public function sentTestMessage()
{
Notification::send(auth()->user(), new TestMessage);
}
public function render()
{
return view('livewire.settings.email-notifications');
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Http;
class SendMessageToDiscordJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* The number of times the job may be attempted.
*
* @var int
*/
public $tries = 5;
/**
* The maximum number of unhandled exceptions to allow before failing.
*/
public int $maxExceptions = 3;
public function __construct(
public string $text,
public string $webhookUrl
) {}
/**
* Execute the job.
*/
public function handle(): void
{
$payload = [
'content' => $this->text,
];
Http::post($this->webhookUrl, $payload);
}
}

View File

@@ -2,10 +2,21 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Spatie\SchemalessAttributes\Casts\SchemalessAttributes;
class InstanceSettings extends Model
{
public $casts = [
'extra_attributes' => SchemalessAttributes::class,
];
public function scopeWithExtraAttributes(): Builder
{
return $this->extra_attributes->modelScope();
}
public static function get()
{
return InstanceSettings::findOrFail(0);

View File

@@ -0,0 +1,25 @@
<?php
namespace App\Notifications\Channels;
use App\Jobs\SendMessageToDiscordJob;
use App\Models\InstanceSettings;
use Illuminate\Notifications\Notification;
class DiscordChannel
{
/**
* Send the given notification.
*/
public function send(object $notifiable, Notification $notification): void
{
$message = $notification->toDiscord($notifiable);
$webhookUrl = data_get(
InstanceSettings::get(),
'extra_attributes.discord_webhook'
);
dispatch(new SendMessageToDiscordJob($message, $webhookUrl));
}
}

View File

@@ -0,0 +1,60 @@
<?php
namespace App\Notifications;
use App\Notifications\Channels\DiscordChannel;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class TestMessage extends Notification
{
use Queueable;
/**
* Create a new notification instance.
*/
public function __construct()
{
//
}
/**
* Get the notification's delivery channels.
*
* @return array<int, string>
*/
public function via(object $notifiable): array
{
return ['mail', DiscordChannel::class];
}
/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->line('Welcome to Coolify!')
->action('Go to dashboard', url('/'))
->line('We need your attention for disk usage.');
}
public function toDiscord(object $notifiable): string
{
return 'Welcome to Coolify! We need your attention for disk usage. [Go to dashboard]('.url('/').')';
}
/**
* Get the array representation of the notification.
*
* @return array<string, mixed>
*/
public function toArray(object $notifiable): array
{
return [
//
];
}
}

View File

@@ -3,11 +3,13 @@
namespace App\Providers;
use App\Jobs\CoolifyTask;
use Illuminate\Mail\MailManager;
use Illuminate\Queue\Events\JobProcessed;
use Illuminate\Support\Facades\Process;
use Illuminate\Support\Facades\Queue;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
use Symfony\Component\Mailer\Transport\Smtp\SmtpTransport;
class AppServiceProvider extends ServiceProvider
{
@@ -26,6 +28,10 @@ class AppServiceProvider extends ServiceProvider
*/
public function boot(): void
{
if (! $this->app->environment('production')) {
\Illuminate\Support\Facades\Mail::alwaysTo('noone@example.com');
}
Queue::after(function (JobProcessed $event) {
// @TODO: Remove `coolify-builder` container after the remoteProcess job is finishged and remoteProcess->type == `deployment`.
if ($event->job->resolveName() === CoolifyTask::class) {