Merge branch 'next' into fix-environement-route

This commit is contained in:
Andras Bacsai
2024-12-17 12:17:50 +01:00
committed by GitHub
426 changed files with 11051 additions and 5406 deletions

View File

@@ -4,18 +4,14 @@ namespace App\Notifications\Application;
use App\Models\Application;
use App\Models\ApplicationPreview;
use App\Notifications\CustomEmailNotification;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Notifications\Dto\PushoverMessage;
use App\Notifications\Dto\SlackMessage;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class DeploymentFailed extends Notification implements ShouldQueue
class DeploymentFailed extends CustomEmailNotification
{
use Queueable;
public $tries = 1;
public Application $application;
public ?ApplicationPreview $preview = null;
@@ -53,7 +49,7 @@ class DeploymentFailed extends Notification implements ShouldQueue
public function via(object $notifiable): array
{
return setNotificationChannels($notifiable, 'deployments');
return $notifiable->getEnabledChannels('deployment_failure');
}
public function toMail(): MailMessage
@@ -137,4 +133,56 @@ class DeploymentFailed extends Notification implements ShouldQueue
],
];
}
public function toPushover(): PushoverMessage
{
if ($this->preview) {
$title = "Pull request #{$this->preview->pull_request_id} deployment failed";
$message = "Pull request deployment failed for {$this->application_name}";
} else {
$title = 'Deployment failed';
$message = "Deployment failed for {$this->application_name}";
}
$buttons[] = [
'text' => 'Deployment logs',
'url' => $this->deployment_url,
];
return new PushoverMessage(
title: $title,
level: 'error',
message: $message,
buttons: [
...$buttons,
],
);
}
public function toSlack(): SlackMessage
{
if ($this->preview) {
$title = "Pull request #{$this->preview->pull_request_id} deployment failed";
$description = "Pull request deployment failed for {$this->application_name}";
if ($this->preview->fqdn) {
$description .= "\nPreview URL: {$this->preview->fqdn}";
}
} else {
$title = 'Deployment failed';
$description = "Deployment failed for {$this->application_name}";
if ($this->fqdn) {
$description .= "\nApplication URL: {$this->fqdn}";
}
}
$description .= "\n\n**Project:** ".data_get($this->application, 'environment.project.name');
$description .= "\n**Environment:** {$this->environment_name}";
$description .= "\n**Deployment Logs:** {$this->deployment_url}";
return new SlackMessage(
title: $title,
description: $description,
color: SlackMessage::errorColor()
);
}
}

View File

@@ -4,18 +4,14 @@ namespace App\Notifications\Application;
use App\Models\Application;
use App\Models\ApplicationPreview;
use App\Notifications\CustomEmailNotification;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Notifications\Dto\PushoverMessage;
use App\Notifications\Dto\SlackMessage;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class DeploymentSuccess extends Notification implements ShouldQueue
class DeploymentSuccess extends CustomEmailNotification
{
use Queueable;
public $tries = 1;
public Application $application;
public ?ApplicationPreview $preview = null;
@@ -53,13 +49,7 @@ class DeploymentSuccess extends Notification implements ShouldQueue
public function via(object $notifiable): array
{
$channels = setNotificationChannels($notifiable, 'deployments');
if (isCloud()) {
// TODO: Make batch notifications work with email
$channels = array_diff($channels, [\App\Notifications\Channels\EmailChannel::class]);
}
return $channels;
return $notifiable->getEnabledChannels('deployment_success');
}
public function toMail(): MailMessage
@@ -152,4 +142,67 @@ class DeploymentSuccess extends Notification implements ShouldQueue
],
];
}
public function toPushover(): PushoverMessage
{
if ($this->preview) {
$title = "Pull request #{$this->preview->pull_request_id} successfully deployed";
$message = 'New PR' . $this->preview->pull_request_id . ' version successfully deployed of ' . $this->application_name . '';
if ($this->preview->fqdn) {
$buttons[] = [
'text' => 'Open Application',
'url' => $this->preview->fqdn,
];
}
} else {
$title = 'New version successfully deployed';
$message = 'New version successfully deployed of ' . $this->application_name . '';
if ($this->fqdn) {
$buttons[] = [
'text' => 'Open Application',
'url' => $this->fqdn,
];
}
}
$buttons[] = [
'text' => 'Deployment logs',
'url' => $this->deployment_url,
];
return new PushoverMessage(
title: $title,
level: 'success',
message: $message,
buttons: [
...$buttons,
],
);
}
public function toSlack(): SlackMessage
{
if ($this->preview) {
$title = "Pull request #{$this->preview->pull_request_id} successfully deployed";
$description = "New version successfully deployed for {$this->application_name}";
if ($this->preview->fqdn) {
$description .= "\nPreview URL: {$this->preview->fqdn}";
}
} else {
$title = 'New version successfully deployed';
$description = "New version successfully deployed for {$this->application_name}";
if ($this->fqdn) {
$description .= "\nApplication URL: {$this->fqdn}";
}
}
$description .= "\n\n**Project:** ".data_get($this->application, 'environment.project.name');
$description .= "\n**Environment:** {$this->environment_name}";
$description .= "\n**Deployment Logs:** {$this->deployment_url}";
return new SlackMessage(
title: $title,
description: $description,
color: SlackMessage::successColor()
);
}
}

View File

@@ -3,18 +3,14 @@
namespace App\Notifications\Application;
use App\Models\Application;
use App\Notifications\CustomEmailNotification;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Notifications\Dto\PushoverMessage;
use App\Notifications\Dto\SlackMessage;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class StatusChanged extends Notification implements ShouldQueue
class StatusChanged extends CustomEmailNotification
{
use Queueable;
public $tries = 1;
public string $resource_name;
public string $project_uuid;
@@ -40,7 +36,7 @@ class StatusChanged extends Notification implements ShouldQueue
public function via(object $notifiable): array
{
return setNotificationChannels($notifiable, 'status_changes');
return $notifiable->getEnabledChannels('status_change');
}
public function toMail(): MailMessage
@@ -81,4 +77,37 @@ class StatusChanged extends Notification implements ShouldQueue
],
];
}
public function toPushover(): PushoverMessage
{
$message = $this->resource_name . ' has been stopped.';
return new PushoverMessage(
title: 'Application stopped',
level: 'error',
message: $message,
buttons: [
[
'text' => 'Open Application in Coolify',
'url' => $this->resource_url,
],
],
);
}
public function toSlack(): SlackMessage
{
$title = 'Application stopped';
$description = "{$this->resource_name} has been stopped";
$description .= "\n\n**Project:** ".data_get($this->resource, 'environment.project.name');
$description .= "\n**Environment:** {$this->environment_name}";
$description .= "\n**Application URL:** {$this->resource_url}";
return new SlackMessage(
title: $title,
description: $description,
color: SlackMessage::errorColor()
);
}
}

View File

@@ -13,10 +13,13 @@ class DiscordChannel
public function send(SendsDiscord $notifiable, Notification $notification): void
{
$message = $notification->toDiscord();
$webhookUrl = $notifiable->routeNotificationForDiscord();
if (! $webhookUrl) {
$discordSettings = $notifiable->discordNotificationSettings;
if (! $discordSettings || ! $discordSettings->isEnabled() || ! $discordSettings->discord_webhook_url) {
return;
}
SendMessageToDiscordJob::dispatch($message, $webhookUrl);
SendMessageToDiscordJob::dispatch($message, $discordSettings->discord_webhook_url);
}
}

View File

@@ -13,7 +13,7 @@ class EmailChannel
{
try {
$this->bootConfigs($notifiable);
$recipients = $notifiable->getRecepients($notification);
$recipients = $notifiable->getRecipients($notification);
if (count($recipients) === 0) {
throw new Exception('No email recipients found');
}
@@ -46,7 +46,9 @@ class EmailChannel
private function bootConfigs($notifiable): void
{
if (data_get($notifiable, 'use_instance_email_settings')) {
$emailSettings = $notifiable->emailNotificationSettings;
if ($emailSettings->use_instance_email_settings) {
$type = set_transanctional_email_settings();
if (! $type) {
throw new Exception('No email settings found.');
@@ -54,23 +56,27 @@ class EmailChannel
return;
}
config()->set('mail.from.address', data_get($notifiable, 'smtp_from_address', 'test@example.com'));
config()->set('mail.from.name', data_get($notifiable, 'smtp_from_name', 'Test'));
if (data_get($notifiable, 'resend_enabled')) {
config()->set('mail.from.address', $emailSettings->smtp_from_address ?? 'test@example.com');
config()->set('mail.from.name', $emailSettings->smtp_from_name ?? 'Test');
if ($emailSettings->resend_enabled) {
config()->set('mail.default', 'resend');
config()->set('resend.api_key', data_get($notifiable, 'resend_api_key'));
config()->set('resend.api_key', $emailSettings->resend_api_key);
}
if (data_get($notifiable, 'smtp_enabled')) {
if ($emailSettings->smtp_enabled) {
config()->set('mail.default', 'smtp');
config()->set('mail.mailers.smtp', [
'transport' => 'smtp',
'host' => data_get($notifiable, 'smtp_host'),
'port' => data_get($notifiable, 'smtp_port'),
'encryption' => data_get($notifiable, 'smtp_encryption'),
'username' => data_get($notifiable, 'smtp_username'),
'password' => data_get($notifiable, 'smtp_password'),
'timeout' => data_get($notifiable, 'smtp_timeout'),
'host' => $emailSettings->smtp_host,
'port' => $emailSettings->smtp_port,
'encryption' => $emailSettings->smtp_encryption === 'none' ? null : $emailSettings->smtp_encryption,
'username' => $emailSettings->smtp_username,
'password' => $emailSettings->smtp_password,
'timeout' => $emailSettings->smtp_timeout,
'local_domain' => null,
'auto_tls' => $emailSettings->smtp_encryption === 'none' ? '0' : '',
]);
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace App\Notifications\Channels;
use App\Jobs\SendMessageToPushoverJob;
use Illuminate\Notifications\Notification;
class PushoverChannel
{
public function send(SendsPushover $notifiable, Notification $notification): void
{
$message = $notification->toPushover();
$pushoverSettings = $notifiable->pushoverNotificationSettings;
if (! $pushoverSettings || ! $pushoverSettings->isEnabled() || ! $pushoverSettings->pushover_user_key || ! $pushoverSettings->pushover_api_token) {
return;
}
SendMessageToPushoverJob::dispatch($message, $pushoverSettings->pushover_api_token, $pushoverSettings->pushover_user_key);
}
}

View File

@@ -4,5 +4,5 @@ namespace App\Notifications\Channels;
interface SendsEmail
{
public function getRecepients($notification);
public function getRecipients($notification);
}

View File

@@ -0,0 +1,8 @@
<?php
namespace App\Notifications\Channels;
interface SendsPushover
{
public function routeNotificationForPushover();
}

View File

@@ -0,0 +1,8 @@
<?php
namespace App\Notifications\Channels;
interface SendsSlack
{
public function routeNotificationForSlack();
}

View File

@@ -0,0 +1,24 @@
<?php
namespace App\Notifications\Channels;
use App\Jobs\SendMessageToSlackJob;
use Illuminate\Notifications\Notification;
class SlackChannel
{
/**
* Send the given notification.
*/
public function send(SendsSlack $notifiable, Notification $notification): void
{
$message = $notification->toSlack();
$slackSettings = $notifiable->slackNotificationSettings;
if (! $slackSettings || ! $slackSettings->isEnabled() || ! $slackSettings->slack_webhook_url) {
return;
}
SendMessageToSlackJob::dispatch($message, $slackSettings->slack_webhook_url);
}
}

View File

@@ -9,38 +9,39 @@ class TelegramChannel
public function send($notifiable, $notification): void
{
$data = $notification->toTelegram($notifiable);
$telegramData = $notifiable->routeNotificationForTelegram();
$settings = $notifiable->telegramNotificationSettings;
$message = data_get($data, 'message');
$buttons = data_get($data, 'buttons', []);
$telegramToken = data_get($telegramData, 'token');
$chatId = data_get($telegramData, 'chat_id');
$topicId = null;
$topicsInstance = get_class($notification);
$telegramToken = $settings->telegram_token;
$chatId = $settings->telegram_chat_id;
$threadId = match (get_class($notification)) {
\App\Notifications\Application\DeploymentSuccess::class => $settings->telegram_notifications_deployment_success_thread_id,
\App\Notifications\Application\DeploymentFailed::class => $settings->telegram_notifications_deployment_failure_thread_id,
\App\Notifications\Application\StatusChanged::class,
\App\Notifications\Container\ContainerRestarted::class,
\App\Notifications\Container\ContainerStopped::class => $settings->telegram_notifications_status_change_thread_id,
\App\Notifications\Database\BackupSuccess::class => $settings->telegram_notifications_backup_success_thread_id,
\App\Notifications\Database\BackupFailed::class => $settings->telegram_notifications_backup_failure_thread_id,
\App\Notifications\ScheduledTask\TaskSuccess::class => $settings->telegram_notifications_scheduled_task_success_thread_id,
\App\Notifications\ScheduledTask\TaskFailed::class => $settings->telegram_notifications_scheduled_task_failure_thread_id,
\App\Notifications\Server\DockerCleanupSuccess::class => $settings->telegram_notifications_docker_cleanup_success_thread_id,
\App\Notifications\Server\DockerCleanupFailed::class => $settings->telegram_notifications_docker_cleanup_failure_thread_id,
\App\Notifications\Server\HighDiskUsage::class => $settings->telegram_notifications_server_disk_usage_thread_id,
\App\Notifications\Server\Unreachable::class => $settings->telegram_notifications_server_unreachable_thread_id,
\App\Notifications\Server\Reachable::class => $settings->telegram_notifications_server_reachable_thread_id,
default => null,
};
switch ($topicsInstance) {
case \App\Notifications\Test::class:
$topicId = data_get($notifiable, 'telegram_notifications_test_message_thread_id');
break;
case \App\Notifications\Application\StatusChanged::class:
case \App\Notifications\Container\ContainerRestarted::class:
case \App\Notifications\Container\ContainerStopped::class:
$topicId = data_get($notifiable, 'telegram_notifications_status_changes_message_thread_id');
break;
case \App\Notifications\Application\DeploymentSuccess::class:
case \App\Notifications\Application\DeploymentFailed::class:
$topicId = data_get($notifiable, 'telegram_notifications_deployments_message_thread_id');
break;
case \App\Notifications\Database\BackupSuccess::class:
case \App\Notifications\Database\BackupFailed::class:
$topicId = data_get($notifiable, 'telegram_notifications_database_backups_message_thread_id');
break;
case \App\Notifications\ScheduledTask\TaskFailed::class:
$topicId = data_get($notifiable, 'telegram_notifications_scheduled_tasks_thread_id');
break;
}
if (! $telegramToken || ! $chatId || ! $message) {
return;
}
SendMessageToTelegramJob::dispatch($message, $buttons, $telegramToken, $chatId, $topicId);
SendMessageToTelegramJob::dispatch($message, $buttons, $telegramToken, $chatId, $threadId);
}
}

View File

@@ -7,7 +7,6 @@ use Exception;
use Illuminate\Mail\Message;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Mail;
use Log;
class TransactionalEmailChannel
{
@@ -15,8 +14,6 @@ class TransactionalEmailChannel
{
$settings = instanceSettings();
if (! data_get($settings, 'smtp_enabled') && ! data_get($settings, 'resend_enabled')) {
Log::info('SMTP/Resend not enabled');
return;
}
$email = $notifiable->email;

View File

@@ -3,18 +3,14 @@
namespace App\Notifications\Container;
use App\Models\Server;
use App\Notifications\CustomEmailNotification;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Notifications\Dto\PushoverMessage;
use App\Notifications\Dto\SlackMessage;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class ContainerRestarted extends Notification implements ShouldQueue
class ContainerRestarted extends CustomEmailNotification
{
use Queueable;
public $tries = 1;
public function __construct(public string $name, public Server $server, public ?string $url = null)
{
$this->onQueue('high');
@@ -22,7 +18,7 @@ class ContainerRestarted extends Notification implements ShouldQueue
public function via(object $notifiable): array
{
return setNotificationChannels($notifiable, 'status_changes');
return $notifiable->getEnabledChannels('status_change');
}
public function toMail(): MailMessage
@@ -72,4 +68,38 @@ class ContainerRestarted extends Notification implements ShouldQueue
return $payload;
}
public function toPushover(): PushoverMessage
{
$buttons = [];
if ($this->url) {
$buttons[] = [
'text' => 'Check Proxy in Coolify',
'url' => $this->url,
];
}
return new PushoverMessage(
title: 'Resource restarted',
level: 'warning',
message: "A resource ({$this->name}) has been restarted automatically on {$this->server->name}",
buttons: $buttons,
);
}
public function toSlack(): SlackMessage
{
$title = 'Resource restarted';
$description = "A resource ({$this->name}) has been restarted automatically on {$this->server->name}";
if ($this->url) {
$description .= "\n**Resource URL:** {$this->url}";
}
return new SlackMessage(
title: $title,
description: $description,
color: SlackMessage::warningColor()
);
}
}

View File

@@ -3,18 +3,14 @@
namespace App\Notifications\Container;
use App\Models\Server;
use App\Notifications\CustomEmailNotification;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Notifications\Dto\PushoverMessage;
use App\Notifications\Dto\SlackMessage;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class ContainerStopped extends Notification implements ShouldQueue
class ContainerStopped extends CustomEmailNotification
{
use Queueable;
public $tries = 1;
public function __construct(public string $name, public Server $server, public ?string $url = null)
{
$this->onQueue('high');
@@ -22,7 +18,7 @@ class ContainerStopped extends Notification implements ShouldQueue
public function via(object $notifiable): array
{
return setNotificationChannels($notifiable, 'status_changes');
return $notifiable->getEnabledChannels('status_change');
}
public function toMail(): MailMessage
@@ -72,4 +68,39 @@ class ContainerStopped extends Notification implements ShouldQueue
return $payload;
}
public function toPushover(): PushoverMessage
{
$buttons = [];
if ($this->url) {
$buttons[] = [
'text' => 'Open Application in Coolify',
'url' => $this->url,
];
}
return new PushoverMessage(
title: 'Resource stopped',
level: 'error',
message: "A resource ({$this->name}) has been stopped unexpectedly on {$this->server->name}",
buttons: $buttons,
);
}
public function toSlack(): SlackMessage
{
$title = 'Resource stopped';
$description = "A resource ({$this->name}) has been stopped unexpectedly on {$this->server->name}";
if ($this->url) {
$description .= "\n**Resource URL:** {$this->url}";
}
return new SlackMessage(
title: $title,
description: $description,
color: SlackMessage::errorColor()
);
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
class CustomEmailNotification extends Notification implements ShouldQueue
{
use Queueable;
public $backoff = [10, 20, 30, 40, 50];
public $tries = 5;
public $maxExceptions = 5;
}

View File

@@ -3,20 +3,14 @@
namespace App\Notifications\Database;
use App\Models\ScheduledDatabaseBackup;
use App\Notifications\CustomEmailNotification;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Notifications\Dto\PushoverMessage;
use App\Notifications\Dto\SlackMessage;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class BackupFailed extends Notification implements ShouldQueue
class BackupFailed extends CustomEmailNotification
{
use Queueable;
public $backoff = 10;
public $tries = 2;
public string $name;
public string $frequency;
@@ -30,13 +24,13 @@ class BackupFailed extends Notification implements ShouldQueue
public function via(object $notifiable): array
{
return setNotificationChannels($notifiable, 'database_backups');
return $notifiable->getEnabledChannels('backup_failure');
}
public function toMail(): MailMessage
{
$mail = new MailMessage;
$mail->subject("Coolify: [ACTION REQUIRED] Backup FAILED for {$this->database->name}");
$mail->subject("Coolify: [ACTION REQUIRED] Database Backup FAILED for {$this->database->name}");
$mail->view('emails.backup-failed', [
'name' => $this->name,
'database_name' => $this->database_name,
@@ -70,4 +64,28 @@ class BackupFailed extends Notification implements ShouldQueue
'message' => $message,
];
}
public function toPushover(): PushoverMessage
{
return new PushoverMessage(
title: 'Database backup failed',
level: 'error',
message: "Database backup for {$this->name} (db:{$this->database_name}) was FAILED<br/><br/><b>Frequency:</b> {$this->frequency} .<br/><b>Reason:</b> {$this->output}",
);
}
public function toSlack(): SlackMessage
{
$title = 'Database backup failed';
$description = "Database backup for {$this->name} (db:{$this->database_name}) has FAILED.";
$description .= "\n\n**Frequency:** {$this->frequency}";
$description .= "\n\n**Error Output:**\n{$this->output}";
return new SlackMessage(
title: $title,
description: $description,
color: SlackMessage::errorColor()
);
}
}

View File

@@ -3,20 +3,14 @@
namespace App\Notifications\Database;
use App\Models\ScheduledDatabaseBackup;
use App\Notifications\CustomEmailNotification;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Notifications\Dto\PushoverMessage;
use App\Notifications\Dto\SlackMessage;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class BackupSuccess extends Notification implements ShouldQueue
class BackupSuccess extends CustomEmailNotification
{
use Queueable;
public $backoff = 10;
public $tries = 3;
public string $name;
public string $frequency;
@@ -24,13 +18,14 @@ class BackupSuccess extends Notification implements ShouldQueue
public function __construct(ScheduledDatabaseBackup $backup, public $database, public $database_name)
{
$this->onQueue('high');
$this->name = $database->name;
$this->frequency = $backup->frequency;
}
public function via(object $notifiable): array
{
return setNotificationChannels($notifiable, 'database_backups');
return $notifiable->getEnabledChannels('backup_success');
}
public function toMail(): MailMessage
@@ -67,4 +62,29 @@ class BackupSuccess extends Notification implements ShouldQueue
'message' => $message,
];
}
public function toPushover(): PushoverMessage
{
return new PushoverMessage(
title: 'Database backup successful',
level: 'success',
message: "Database backup for {$this->name} (db:{$this->database_name}) was successful.<br/><br/><b>Frequency:</b> {$this->frequency}.",
);
}
public function toSlack(): SlackMessage
{
$title = 'Database backup successful';
$description = "Database backup for {$this->name} (db:{$this->database_name}) was successful.";
$description .= "\n\n**Frequency:** {$this->frequency}";
return new SlackMessage(
title: $title,
description: $description,
color: SlackMessage::successColor()
);
}
}

View File

@@ -46,7 +46,7 @@ class DiscordMessage
public function toPayload(): array
{
$footerText = 'Coolify v'.config('version');
$footerText = 'Coolify v'.config('constants.coolify.version');
if (isCloud()) {
$footerText = 'Coolify Cloud';
}

View File

@@ -0,0 +1,50 @@
<?php
namespace App\Notifications\Dto;
use Illuminate\Support\Facades\Log;
class PushoverMessage
{
public function __construct(
public string $title,
public string $message,
public array $buttons = [],
public string $level = 'info',
) {}
public function getLevelIcon(): string
{
return match ($this->level) {
'info' => '',
'error' => '❌',
'success' => '✅ ',
'warning' => '⚠️',
};
}
public function toPayload(string $token, string $user): array
{
$levelIcon = $this->getLevelIcon();
$payload = [
'token' => $token,
'user' => $user,
'title' => "{$levelIcon} {$this->title}",
'message' => $this->message,
'html' => 1,
];
foreach ($this->buttons as $button) {
$buttonUrl = data_get($button, 'url');
$text = data_get($button, 'text', 'Click here');
if ($buttonUrl && str_contains($buttonUrl, 'http://localhost')) {
$buttonUrl = str_replace('http://localhost', config('app.url'), $buttonUrl);
}
$payload['message'] .= "&nbsp;<a href='" . $buttonUrl . "'>" . $text . '</a>';
}
Log::info('Pushover message', $payload);
return $payload;
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace App\Notifications\Dto;
class SlackMessage
{
public function __construct(
public string $title,
public string $description,
public string $color = '#0099ff'
) {}
public static function infoColor(): string
{
return '#0099ff';
}
public static function errorColor(): string
{
return '#ff0000';
}
public static function successColor(): string
{
return '#00ff00';
}
public static function warningColor(): string
{
return '#ffa500';
}
}

View File

@@ -2,9 +2,9 @@
namespace App\Notifications\Internal;
use App\Notifications\Channels\DiscordChannel;
use App\Notifications\Channels\TelegramChannel;
use App\Notifications\Dto\DiscordMessage;
use App\Notifications\Dto\PushoverMessage;
use App\Notifications\Dto\SlackMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
@@ -22,18 +22,7 @@ class GeneralNotification extends Notification implements ShouldQueue
public function via(object $notifiable): array
{
$channels = [];
$isDiscordEnabled = data_get($notifiable, 'discord_enabled');
$isTelegramEnabled = data_get($notifiable, 'telegram_enabled');
if ($isDiscordEnabled) {
$channels[] = DiscordChannel::class;
}
if ($isTelegramEnabled) {
$channels[] = TelegramChannel::class;
}
return $channels;
return $notifiable->getEnabledChannels('general');
}
public function toDiscord(): DiscordMessage
@@ -51,4 +40,22 @@ class GeneralNotification extends Notification implements ShouldQueue
'message' => $this->message,
];
}
public function toPushover(): PushoverMessage
{
return new PushoverMessage(
title: 'General Notification',
level: 'info',
message: $this->message,
);
}
public function toSlack(): SlackMessage
{
return new SlackMessage(
title: 'Coolify: General Notification',
description: $this->message,
color: SlackMessage::infoColor(),
);
}
}

View File

@@ -3,35 +3,29 @@
namespace App\Notifications\ScheduledTask;
use App\Models\ScheduledTask;
use App\Notifications\CustomEmailNotification;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Notifications\Dto\PushoverMessage;
use App\Notifications\Dto\SlackMessage;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class TaskFailed extends Notification implements ShouldQueue
class TaskFailed extends CustomEmailNotification
{
use Queueable;
public $backoff = 10;
public $tries = 2;
public ?string $url = null;
public function __construct(public ScheduledTask $task, public string $output)
{
$this->onQueue('high');
if ($task->application) {
$this->url = $task->application->failedTaskLink($task->uuid);
$this->url = $task->application->taskLink($task->uuid);
} elseif ($task->service) {
$this->url = $task->service->failedTaskLink($task->uuid);
$this->url = $task->service->taskLink($task->uuid);
}
}
public function via(object $notifiable): array
{
return setNotificationChannels($notifiable, 'scheduled_tasks');
return $notifiable->getEnabledChannels('scheduled_task_failure');
}
public function toMail(): MailMessage
@@ -76,4 +70,48 @@ class TaskFailed extends Notification implements ShouldQueue
'message' => $message,
];
}
public function toPushover(): PushoverMessage
{
$message = "Scheduled task ({$this->task->name}) failed<br/>";
if ($this->output) {
$message .= "<br/><b>Error Output:</b>{$this->output}";
}
$buttons = [];
if ($this->url) {
$buttons[] = [
'text' => 'Open task in Coolify',
'url' => (string) $this->url,
];
}
return new PushoverMessage(
title: 'Scheduled task failed',
level: 'error',
message: $message,
buttons: $buttons,
);
}
public function toSlack(): SlackMessage
{
$title = 'Scheduled task failed';
$description = "Scheduled task ({$this->task->name}) failed.";
if ($this->output) {
$description .= "\n\n**Error Output:**\n{$this->output}";
}
if ($this->url) {
$description .= "\n\n**Task URL:** {$this->url}";
}
return new SlackMessage(
title: $title,
description: $description,
color: SlackMessage::errorColor()
);
}
}

View File

@@ -0,0 +1,108 @@
<?php
namespace App\Notifications\ScheduledTask;
use App\Models\ScheduledTask;
use App\Notifications\CustomEmailNotification;
use App\Notifications\Dto\DiscordMessage;
use App\Notifications\Dto\PushoverMessage;
use App\Notifications\Dto\SlackMessage;
use Illuminate\Notifications\Messages\MailMessage;
class TaskSuccess extends CustomEmailNotification
{
public ?string $url = null;
public function __construct(public ScheduledTask $task, public string $output)
{
$this->onQueue('high');
if ($task->application) {
$this->url = $task->application->taskLink($task->uuid);
} elseif ($task->service) {
$this->url = $task->service->taskLink($task->uuid);
}
}
public function via(object $notifiable): array
{
return $notifiable->getEnabledChannels('scheduled_task_success');
}
public function toMail(): MailMessage
{
$mail = new MailMessage;
$mail->subject("Coolify: Scheduled task ({$this->task->name}) succeeded.");
$mail->view('emails.scheduled-task-success', [
'task' => $this->task,
'url' => $this->url,
'output' => $this->output,
]);
return $mail;
}
public function toDiscord(): DiscordMessage
{
$message = new DiscordMessage(
title: ':white_check_mark: Scheduled task succeeded',
description: "Scheduled task ({$this->task->name}) succeeded.",
color: DiscordMessage::successColor(),
);
if ($this->url) {
$message->addField('Scheduled task', '[Link]('.$this->url.')');
}
return $message;
}
public function toTelegram(): array
{
$message = "Coolify: Scheduled task ({$this->task->name}) succeeded.";
if ($this->url) {
$buttons[] = [
'text' => 'Open task in Coolify',
'url' => (string) $this->url,
];
}
return [
'message' => $message,
];
}
public function toPushover(): PushoverMessage
{
$message = "Coolify: Scheduled task ({$this->task->name}) succeeded.";
$buttons = [];
if ($this->url) {
$buttons[] = [
'text' => 'Open task in Coolify',
'url' => (string) $this->url,
];
}
return new PushoverMessage(
title: 'Scheduled task succeeded',
level: 'success',
message: $message,
buttons: $buttons,
);
}
public function toSlack(): SlackMessage
{
$title = 'Scheduled task succeeded';
$description = "Scheduled task ({$this->task->name}) succeeded.";
if ($this->url) {
$description .= "\n\n**Task URL:** {$this->url}";
}
return new SlackMessage(
title: $title,
description: $description,
color: SlackMessage::successColor()
);
}
}

View File

@@ -1,71 +0,0 @@
<?php
namespace App\Notifications\Server;
use App\Models\Server;
use App\Notifications\Channels\DiscordChannel;
use App\Notifications\Channels\TelegramChannel;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
class DockerCleanup extends Notification implements ShouldQueue
{
use Queueable;
public $tries = 1;
public function __construct(public Server $server, public string $message)
{
$this->onQueue('high');
}
public function via(object $notifiable): array
{
$channels = [];
// $isEmailEnabled = isEmailEnabled($notifiable);
$isDiscordEnabled = data_get($notifiable, 'discord_enabled');
$isTelegramEnabled = data_get($notifiable, 'telegram_enabled');
if ($isDiscordEnabled) {
$channels[] = DiscordChannel::class;
}
// if ($isEmailEnabled) {
// $channels[] = EmailChannel::class;
// }
if ($isTelegramEnabled) {
$channels[] = TelegramChannel::class;
}
return $channels;
}
// public function toMail(): MailMessage
// {
// $mail = new MailMessage();
// $mail->subject("Coolify: Server ({$this->server->name}) high disk usage detected!");
// $mail->view('emails.high-disk-usage', [
// 'name' => $this->server->name,
// 'disk_usage' => $this->disk_usage,
// 'threshold' => $this->docker_cleanup_threshold,
// ]);
// return $mail;
// }
public function toDiscord(): DiscordMessage
{
return new DiscordMessage(
title: ':white_check_mark: Server cleanup job done',
description: $this->message,
color: DiscordMessage::successColor(),
);
}
public function toTelegram(): array
{
return [
'message' => "Coolify: Server '{$this->server->name}' cleanup job done!\n\n{$this->message}",
];
}
}

View File

@@ -0,0 +1,69 @@
<?php
namespace App\Notifications\Server;
use App\Models\Server;
use App\Notifications\CustomEmailNotification;
use App\Notifications\Dto\DiscordMessage;
use App\Notifications\Dto\PushoverMessage;
use App\Notifications\Dto\SlackMessage;
use Illuminate\Notifications\Messages\MailMessage;
class DockerCleanupFailed extends CustomEmailNotification
{
public function __construct(public Server $server, public string $message)
{
$this->onQueue('high');
}
public function via(object $notifiable): array
{
return $notifiable->getEnabledChannels('docker_cleanup_failure');
}
public function toMail(): MailMessage
{
$mail = new MailMessage;
$mail->subject("Coolify: [ACTION REQUIRED] Docker cleanup job failed on {$this->server->name}");
$mail->view('emails.docker-cleanup-failed', [
'name' => $this->server->name,
'text' => $this->message,
]);
return $mail;
}
public function toDiscord(): DiscordMessage
{
return new DiscordMessage(
title: ':cross_mark: Coolify: [ACTION REQUIRED] Docker cleanup job failed on '.$this->server->name,
description: $this->message,
color: DiscordMessage::errorColor(),
);
}
public function toTelegram(): array
{
return [
'message' => "Coolify: [ACTION REQUIRED] Docker cleanup job failed on {$this->server->name}!\n\n{$this->message}",
];
}
public function toPushover(): PushoverMessage
{
return new PushoverMessage(
title: 'Docker cleanup job failed',
level: 'error',
message: "[ACTION REQUIRED] Docker cleanup job failed on {$this->server->name}!\n\n{$this->message}",
);
}
public function toSlack(): SlackMessage
{
return new SlackMessage(
title: 'Coolify: [ACTION REQUIRED] Docker cleanup job failed',
description: "Docker cleanup job failed on '{$this->server->name}'!\n\n{$this->message}",
color: SlackMessage::errorColor()
);
}
}

View File

@@ -0,0 +1,69 @@
<?php
namespace App\Notifications\Server;
use App\Models\Server;
use App\Notifications\CustomEmailNotification;
use App\Notifications\Dto\DiscordMessage;
use App\Notifications\Dto\PushoverMessage;
use App\Notifications\Dto\SlackMessage;
use Illuminate\Notifications\Messages\MailMessage;
class DockerCleanupSuccess extends CustomEmailNotification
{
public function __construct(public Server $server, public string $message)
{
$this->onQueue('high');
}
public function via(object $notifiable): array
{
return $notifiable->getEnabledChannels('docker_cleanup_success');
}
public function toMail(): MailMessage
{
$mail = new MailMessage;
$mail->subject("Coolify: Docker cleanup job succeeded on {$this->server->name}");
$mail->view('emails.docker-cleanup-success', [
'name' => $this->server->name,
'text' => $this->message,
]);
return $mail;
}
public function toDiscord(): DiscordMessage
{
return new DiscordMessage(
title: ':white_check_mark: Coolify: Docker cleanup job succeeded on '.$this->server->name,
description: $this->message,
color: DiscordMessage::successColor(),
);
}
public function toTelegram(): array
{
return [
'message' => "Coolify: Docker cleanup job succeeded on {$this->server->name}!\n\n{$this->message}",
];
}
public function toPushover(): PushoverMessage
{
return new PushoverMessage(
title: 'Docker cleanup job succeeded',
level: 'success',
message: "Docker cleanup job succeeded on {$this->server->name}!\n\n{$this->message}",
);
}
public function toSlack(): SlackMessage
{
return new SlackMessage(
title: 'Coolify: Docker cleanup job succeeded',
description: "Docker cleanup job succeeded on '{$this->server->name}'!\n\n{$this->message}",
color: SlackMessage::successColor()
);
}
}

View File

@@ -3,21 +3,14 @@
namespace App\Notifications\Server;
use App\Models\Server;
use App\Notifications\Channels\DiscordChannel;
use App\Notifications\Channels\EmailChannel;
use App\Notifications\Channels\TelegramChannel;
use App\Notifications\CustomEmailNotification;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Notifications\Dto\PushoverMessage;
use App\Notifications\Dto\SlackMessage;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class ForceDisabled extends Notification implements ShouldQueue
class ForceDisabled extends CustomEmailNotification
{
use Queueable;
public $tries = 1;
public function __construct(public Server $server)
{
$this->onQueue('high');
@@ -25,22 +18,7 @@ class ForceDisabled extends Notification implements ShouldQueue
public function via(object $notifiable): array
{
$channels = [];
$isEmailEnabled = isEmailEnabled($notifiable);
$isDiscordEnabled = data_get($notifiable, 'discord_enabled');
$isTelegramEnabled = data_get($notifiable, 'telegram_enabled');
if ($isDiscordEnabled) {
$channels[] = DiscordChannel::class;
}
if ($isEmailEnabled) {
$channels[] = EmailChannel::class;
}
if ($isTelegramEnabled) {
$channels[] = TelegramChannel::class;
}
return $channels;
return $notifiable->getEnabledChannels('server_force_disabled');
}
public function toMail(): MailMessage
@@ -73,4 +51,27 @@ class ForceDisabled extends Notification implements ShouldQueue
'message' => "Coolify: Server ({$this->server->name}) disabled because it is not paid!\n All automations and integrations are stopped.\nPlease update your subscription to enable the server again [here](https://app.coolify.io/subscriptions).",
];
}
public function toPushover(): PushoverMessage
{
return new PushoverMessage(
title: 'Server disabled',
level: 'error',
message: "Server ({$this->server->name}) disabled because it is not paid!\n All automations and integrations are stopped.<br/>Please update your subscription to enable the server again [here](https://app.coolify.io/subscriptions).",
);
}
public function toSlack(): SlackMessage
{
$title = 'Server disabled';
$description = "Server ({$this->server->name}) disabled because it is not paid!\n";
$description .= "All automations and integrations are stopped.\n\n";
$description .= 'Please update your subscription to enable the server again: https://app.coolify.io/subscriptions';
return new SlackMessage(
title: $title,
description: $description,
color: SlackMessage::errorColor()
);
}
}

View File

@@ -3,21 +3,14 @@
namespace App\Notifications\Server;
use App\Models\Server;
use App\Notifications\Channels\DiscordChannel;
use App\Notifications\Channels\EmailChannel;
use App\Notifications\Channels\TelegramChannel;
use App\Notifications\CustomEmailNotification;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Notifications\Dto\PushoverMessage;
use App\Notifications\Dto\SlackMessage;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class ForceEnabled extends Notification implements ShouldQueue
class ForceEnabled extends CustomEmailNotification
{
use Queueable;
public $tries = 1;
public function __construct(public Server $server)
{
$this->onQueue('high');
@@ -25,22 +18,7 @@ class ForceEnabled extends Notification implements ShouldQueue
public function via(object $notifiable): array
{
$channels = [];
$isEmailEnabled = isEmailEnabled($notifiable);
$isDiscordEnabled = data_get($notifiable, 'discord_enabled');
$isTelegramEnabled = data_get($notifiable, 'telegram_enabled');
if ($isDiscordEnabled) {
$channels[] = DiscordChannel::class;
}
if ($isEmailEnabled) {
$channels[] = EmailChannel::class;
}
if ($isTelegramEnabled) {
$channels[] = TelegramChannel::class;
}
return $channels;
return $notifiable->getEnabledChannels('server_force_enabled');
}
public function toMail(): MailMessage
@@ -69,4 +47,22 @@ class ForceEnabled extends Notification implements ShouldQueue
'message' => "Coolify: Server ({$this->server->name}) enabled again!",
];
}
public function toPushover(): PushoverMessage
{
return new PushoverMessage(
title: 'Server enabled',
level: 'success',
message: "Server ({$this->server->name}) enabled again!",
);
}
public function toSlack(): SlackMessage
{
return new SlackMessage(
title: 'Server enabled',
description: "Server '{$this->server->name}' enabled again!",
color: SlackMessage::successColor()
);
}
}

View File

@@ -3,18 +3,14 @@
namespace App\Notifications\Server;
use App\Models\Server;
use App\Notifications\CustomEmailNotification;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Notifications\Dto\PushoverMessage;
use App\Notifications\Dto\SlackMessage;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class HighDiskUsage extends Notification implements ShouldQueue
class HighDiskUsage extends CustomEmailNotification
{
use Queueable;
public $tries = 1;
public function __construct(public Server $server, public int $disk_usage, public int $server_disk_usage_notification_threshold)
{
$this->onQueue('high');
@@ -22,7 +18,7 @@ class HighDiskUsage extends Notification implements ShouldQueue
public function via(object $notifiable): array
{
return setNotificationChannels($notifiable, 'server_disk_usage');
return $notifiable->getEnabledChannels('server_disk_usage');
}
public function toMail(): MailMessage
@@ -61,4 +57,35 @@ class HighDiskUsage extends Notification implements ShouldQueue
'message' => "Coolify: Server '{$this->server->name}' high disk usage detected!\nDisk usage: {$this->disk_usage}%. Threshold: {$this->server_disk_usage_notification_threshold}%.\nPlease cleanup your disk to prevent data-loss.\nHere are some tips: https://coolify.io/docs/knowledge-base/server/automated-cleanup.",
];
}
public function toPushover(): PushoverMessage
{
return new PushoverMessage(
title: 'High disk usage detected',
level: 'warning',
message: "Server '{$this->server->name}' high disk usage detected!<br/><br/><b>Disk usage:</b> {$this->disk_usage}%.<br/><b>Threshold:</b> {$this->server_disk_usage_notification_threshold}%.<br/>Please cleanup your disk to prevent data-loss.",
buttons: [
'Change settings' => base_url().'/server/'.$this->server->uuid."#advanced",
'Tips for cleanup' => "https://coolify.io/docs/knowledge-base/server/automated-cleanup",
],
);
}
public function toSlack(): SlackMessage
{
$description = "Server '{$this->server->name}' high disk usage detected!\n";
$description .= "Disk usage: {$this->disk_usage}%\n";
$description .= "Threshold: {$this->server_disk_usage_notification_threshold}%\n\n";
$description .= "Please cleanup your disk to prevent data-loss.\n";
$description .= "Tips for cleanup: https://coolify.io/docs/knowledge-base/server/automated-cleanup\n";
$description .= "Change settings:\n";
$description .= '- Threshold: '.base_url().'/server/'.$this->server->uuid."#advanced\n";
$description .= '- Notifications: '.base_url().'/notifications/discord';
return new SlackMessage(
title: 'High disk usage detected',
description: $description,
color: SlackMessage::errorColor()
);
}
}

View File

@@ -3,21 +3,14 @@
namespace App\Notifications\Server;
use App\Models\Server;
use App\Notifications\Channels\DiscordChannel;
use App\Notifications\Channels\EmailChannel;
use App\Notifications\Channels\TelegramChannel;
use App\Notifications\CustomEmailNotification;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Notifications\Dto\PushoverMessage;
use App\Notifications\Dto\SlackMessage;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class Reachable extends Notification implements ShouldQueue
class Reachable extends CustomEmailNotification
{
use Queueable;
public $tries = 1;
protected bool $isRateLimited = false;
public function __construct(public Server $server)
@@ -34,22 +27,7 @@ class Reachable extends Notification implements ShouldQueue
return [];
}
$channels = [];
$isEmailEnabled = isEmailEnabled($notifiable);
$isDiscordEnabled = data_get($notifiable, 'discord_enabled');
$isTelegramEnabled = data_get($notifiable, 'telegram_enabled');
if ($isDiscordEnabled) {
$channels[] = DiscordChannel::class;
}
if ($isEmailEnabled) {
$channels[] = EmailChannel::class;
}
if ($isTelegramEnabled) {
$channels[] = TelegramChannel::class;
}
return $channels;
return $notifiable->getEnabledChannels('server_reachable');
}
public function toMail(): MailMessage
@@ -72,10 +50,28 @@ class Reachable extends Notification implements ShouldQueue
);
}
public function toPushover(): PushoverMessage
{
return new PushoverMessage(
title: 'Server revived',
message: "Server '{$this->server->name}' revived. All automations & integrations are turned on again!",
level: 'success',
);
}
public function toTelegram(): array
{
return [
'message' => "Coolify: Server '{$this->server->name}' revived. All automations & integrations are turned on again!",
];
}
public function toSlack(): SlackMessage
{
return new SlackMessage(
title: 'Server revived',
description: "Server '{$this->server->name}' revived.\nAll automations & integrations are turned on again!",
color: SlackMessage::successColor()
);
}
}

View File

@@ -3,21 +3,14 @@
namespace App\Notifications\Server;
use App\Models\Server;
use App\Notifications\Channels\DiscordChannel;
use App\Notifications\Channels\EmailChannel;
use App\Notifications\Channels\TelegramChannel;
use App\Notifications\CustomEmailNotification;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Notifications\Dto\PushoverMessage;
use App\Notifications\Dto\SlackMessage;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class Unreachable extends Notification implements ShouldQueue
class Unreachable extends CustomEmailNotification
{
use Queueable;
public $tries = 1;
protected bool $isRateLimited = false;
public function __construct(public Server $server)
@@ -34,22 +27,7 @@ class Unreachable extends Notification implements ShouldQueue
return [];
}
$channels = [];
$isEmailEnabled = isEmailEnabled($notifiable);
$isDiscordEnabled = data_get($notifiable, 'discord_enabled');
$isTelegramEnabled = data_get($notifiable, 'telegram_enabled');
if ($isDiscordEnabled) {
$channels[] = DiscordChannel::class;
}
if ($isEmailEnabled) {
$channels[] = EmailChannel::class;
}
if ($isTelegramEnabled) {
$channels[] = TelegramChannel::class;
}
return $channels;
return $notifiable->getEnabledChannels('server_unreachable');
}
public function toMail(): ?MailMessage
@@ -82,4 +60,26 @@ class Unreachable extends Notification implements ShouldQueue
'message' => "Coolify: Your server '{$this->server->name}' is unreachable. All automations & integrations are turned off! Please check your server! IMPORTANT: We automatically try to revive your server and turn on all automations & integrations.",
];
}
public function toPushover(): PushoverMessage
{
return new PushoverMessage(
title: 'Server unreachable',
level: 'error',
message: "Your server '{$this->server->name}' is unreachable.<br/>All automations & integrations are turned off!<br/><br/><b>IMPORTANT:</b> We automatically try to revive your server and turn on all automations & integrations.",
);
}
public function toSlack(): SlackMessage
{
$description = "Your server '{$this->server->name}' is unreachable.\n";
$description .= "All automations & integrations are turned off!\n\n";
$description .= '*IMPORTANT:* We automatically try to revive your server and turn on all automations & integrations.';
return new SlackMessage(
title: 'Server unreachable',
description: $description,
color: SlackMessage::errorColor()
);
}
}

View File

@@ -2,7 +2,14 @@
namespace App\Notifications;
use App\Notifications\Channels\DiscordChannel;
use App\Notifications\Channels\EmailChannel;
use App\Notifications\Channels\SlackChannel;
use App\Notifications\Channels\TelegramChannel;
use App\Notifications\Channels\PushoverChannel;
use App\Notifications\Dto\DiscordMessage;
use App\Notifications\Dto\PushoverMessage;
use App\Notifications\Dto\SlackMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@@ -15,20 +22,33 @@ class Test extends Notification implements ShouldQueue
public $tries = 5;
public function __construct(public ?string $emails = null)
public function __construct(public ?string $emails = null, public ?string $channel = null)
{
$this->onQueue('high');
}
public function via(object $notifiable): array
{
return setNotificationChannels($notifiable, 'test');
if ($this->channel) {
$channels = match ($this->channel) {
'email' => [EmailChannel::class],
'discord' => [DiscordChannel::class],
'telegram' => [TelegramChannel::class],
'slack' => [SlackChannel::class],
'pushover' => [PushoverChannel::class],
default => [],
};
} else {
$channels = $notifiable->getEnabledChannels('test');
}
return $channels;
}
public function middleware(object $notifiable, string $channel)
{
return match ($channel) {
\App\Notifications\Channels\EmailChannel::class => [new RateLimited('email')],
EmailChannel::class => [new RateLimited('email')],
default => [],
};
}
@@ -67,4 +87,26 @@ class Test extends Notification implements ShouldQueue
],
];
}
public function toPushover(): PushoverMessage
{
return new PushoverMessage(
title: 'Test Pushover Notification',
message: 'This is a test Pushover notification from Coolify.',
buttons: [
[
'text' => 'Go to your dashboard',
'url' => base_url(),
],
],
);
}
public function toSlack(): SlackMessage
{
return new SlackMessage(
title: 'Test Slack Notification',
description: 'This is a test Slack notification from Coolify.'
);
}
}

View File

@@ -6,17 +6,11 @@ use App\Models\Team;
use App\Models\TeamInvitation;
use App\Models\User;
use App\Notifications\Channels\TransactionalEmailChannel;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Notifications\CustomEmailNotification;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class InvitationLink extends Notification implements ShouldQueue
class InvitationLink extends CustomEmailNotification
{
use Queueable;
public $tries = 5;
public function via(): array
{
return [TransactionalEmailChannel::class];

View File

@@ -3,17 +3,11 @@
namespace App\Notifications\TransactionalEmails;
use App\Notifications\Channels\EmailChannel;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Notifications\CustomEmailNotification;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class Test extends Notification implements ShouldQueue
class Test extends CustomEmailNotification
{
use Queueable;
public $tries = 5;
public function __construct(public string $emails)
{
$this->onQueue('high');