diff --git a/app/Jobs/SendMessageToSlackJob.php b/app/Jobs/SendMessageToSlackJob.php new file mode 100644 index 0000000000..8d1887a0f1 --- /dev/null +++ b/app/Jobs/SendMessageToSlackJob.php @@ -0,0 +1,47 @@ + $this->text, + ]; + Http::post($this->webhookUrl, $payload); + } +} diff --git a/app/Livewire/Notifications/Slack.php b/app/Livewire/Notifications/Slack.php new file mode 100644 index 0000000000..748b5bfcb0 --- /dev/null +++ b/app/Livewire/Notifications/Slack.php @@ -0,0 +1,67 @@ + 'nullable|boolean', + 'team.slack_webhook_url' => 'required|url', + 'team.slack_notifications_test' => 'nullable|boolean', + 'team.slack_notifications_deployments' => 'nullable|boolean', + 'team.slack_notifications_status_changes' => 'nullable|boolean', + 'team.slack_notifications_database_backups' => 'nullable|boolean', + 'team.slack_notifications_scheduled_tasks' => 'nullable|boolean', + ]; + + protected $validationAttributes = [ + 'team.slack_webhook_url' => 'Slack Web API', + ]; + + public function mount() + { + $this->team = auth()->user()->currentTeam(); + } + + public function instantSave() + { + try { + $this->submit(); + } catch (\Throwable $e) { + ray($e->getMessage()); + $this->team->slack_enabled = false; + $this->validate(); + } + } + + public function submit() + { + $this->resetErrorBag(); + $this->validate(); + $this->saveModel(); + } + + public function saveModel() + { + $this->team->save(); + refreshSession(); + $this->dispatch('success', 'Settings saved.'); + } + + public function sendTestNotification() + { + $this->team?->notify(new Test()); + $this->dispatch('success', 'Test notification sent.'); + } + + public function render() + { + return view('livewire.notifications.slack'); + } +} diff --git a/app/Models/Team.php b/app/Models/Team.php index fe5995a1b8..54fb8d1469 100644 --- a/app/Models/Team.php +++ b/app/Models/Team.php @@ -4,11 +4,12 @@ use App\Notifications\Channels\SendsDiscord; use App\Notifications\Channels\SendsEmail; +use App\Notifications\Channels\SendsSlack; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Model; use Illuminate\Notifications\Notifiable; -class Team extends Model implements SendsDiscord, SendsEmail +class Team extends Model implements SendsDiscord, SendsEmail, SendsSlack { use Notifiable; @@ -62,6 +63,11 @@ public function routeNotificationForDiscord() return data_get($this, 'discord_webhook_url', null); } + public function routeNotificationForSlack() + { + return data_get($this, 'slack_webhook_url', null); + } + public function routeNotificationForTelegram() { return [ @@ -225,7 +231,7 @@ public function isAnyNotificationEnabled() if (isCloud()) { return true; } - if ($this->smtp_enabled || $this->resend_enabled || $this->discord_enabled || $this->telegram_enabled || $this->use_instance_email_settings) { + if ($this->smtp_enabled || $this->resend_enabled || $this->discord_enabled || $this->telegram_enabled || $this->slack_enabled || $this->use_instance_email_settings) { return true; } diff --git a/app/Notifications/Application/DeploymentFailed.php b/app/Notifications/Application/DeploymentFailed.php index 1858f31e0b..96c2143f64 100644 --- a/app/Notifications/Application/DeploymentFailed.php +++ b/app/Notifications/Application/DeploymentFailed.php @@ -86,6 +86,18 @@ public function toDiscord(): string return $message; } + public function toSlack(): string + { + if ($this->preview) { + $message = 'Coolify: Pull request #'.$this->preview->pull_request_id.' of '.$this->application_name.' ('.$this->preview->fqdn.') deployment failed: '; + } else { + $message = 'Coolify: Deployment failed of '.$this->application_name.' ('.$this->fqdn.'): '; + } + $message .= '<'.$this->deployment_url.'|Deployment logs>'; + + return $message; + } + public function toTelegram(): array { if ($this->preview) { diff --git a/app/Notifications/Application/DeploymentSuccess.php b/app/Notifications/Application/DeploymentSuccess.php index 0cac6cbab3..70a2efbd3f 100644 --- a/app/Notifications/Application/DeploymentSuccess.php +++ b/app/Notifications/Application/DeploymentSuccess.php @@ -102,6 +102,24 @@ public function toDiscord(): string return $message; } + public function toSlack(): string + { + if ($this->preview) { + $message = 'New PR'.$this->preview->pull_request_id.' version successfully deployed of '.$this->application_name.''; + if ($this->preview->fqdn) { + $message .= ' | <'.$this->preview->fqdn.'|Open Application>'; + } + } else { + $message = 'New version successfully deployed of '.$this->application_name.''; + if ($this->fqdn) { + $message .= ' | <'.$this->fqdn.'|Open Application>'; + } + } + $message .= ' | <'.$this->deployment_url.'|Deployment logs>'; + + return $message; + } + public function toTelegram(): array { if ($this->preview) { diff --git a/app/Notifications/Application/StatusChanged.php b/app/Notifications/Application/StatusChanged.php index baf508895c..baa7c791aa 100644 --- a/app/Notifications/Application/StatusChanged.php +++ b/app/Notifications/Application/StatusChanged.php @@ -66,6 +66,21 @@ public function toDiscord(): string return $message; } + public function toSlack(): array + { + $message = 'Coolify: '.$this->resource_name.' has been stopped.'; + + return [ + 'text' => $message, + 'attachments' => [ + [ + 'text' => $message, + 'color' => '#FF0000', + ], + ], + ]; + } + public function toTelegram(): array { $message = 'Coolify: '.$this->resource_name.' has been stopped.'; diff --git a/app/Notifications/Channels/SendsSlack.php b/app/Notifications/Channels/SendsSlack.php new file mode 100644 index 0000000000..ab2dd6f116 --- /dev/null +++ b/app/Notifications/Channels/SendsSlack.php @@ -0,0 +1,8 @@ +toSlack($notifiable); + $webhookUrl = $notifiable->routeNotificationForSlack(); + if (! $webhookUrl) { + return; + } + dispatch(new SendMessageToSlackJob($message, $webhookUrl)); + } +} diff --git a/app/Notifications/Container/ContainerRestarted.php b/app/Notifications/Container/ContainerRestarted.php index a55f16a83f..1f517f30e9 100644 --- a/app/Notifications/Container/ContainerRestarted.php +++ b/app/Notifications/Container/ContainerRestarted.php @@ -43,6 +43,13 @@ public function toDiscord(): string return $message; } + public function toSlack(): string + { + $message = "Coolify: A resource ({$this->name}) has been restarted automatically on {$this->server->name}"; + + return $message; + } + public function toTelegram(): array { $message = "Coolify: A resource ({$this->name}) has been restarted automatically on {$this->server->name}"; diff --git a/app/Notifications/Container/ContainerStopped.php b/app/Notifications/Container/ContainerStopped.php index d9dc57b981..7c8d726ced 100644 --- a/app/Notifications/Container/ContainerStopped.php +++ b/app/Notifications/Container/ContainerStopped.php @@ -43,6 +43,13 @@ public function toDiscord(): string return $message; } + public function toSlack(): string + { + $message = "Coolify: A resource ($this->name) has been stopped unexpectedly on {$this->server->name}"; + + return $message; + } + public function toTelegram(): array { $message = "Coolify: A resource ($this->name) has been stopped unexpectedly on {$this->server->name}"; diff --git a/app/Notifications/Database/BackupFailed.php b/app/Notifications/Database/BackupFailed.php index c6403ab716..0746c60636 100644 --- a/app/Notifications/Database/BackupFailed.php +++ b/app/Notifications/Database/BackupFailed.php @@ -50,6 +50,11 @@ public function toDiscord(): string return "Coolify: Database backup for {$this->name} (db:{$this->database_name}) with frequency of {$this->frequency} was FAILED.\n\nReason:\n{$this->output}"; } + public function toSlack(): string + { + return "Coolify: Database backup for {$this->name} (db:{$this->database_name}) with frequency of {$this->frequency} was FAILED.\n\nReason:\n{$this->output}"; + } + public function toTelegram(): array { $message = "Coolify: Database backup for {$this->name} (db:{$this->database_name}) with frequency of {$this->frequency} was FAILED.\n\nReason:\n{$this->output}"; diff --git a/app/Notifications/Database/BackupSuccess.php b/app/Notifications/Database/BackupSuccess.php index f3a3d5943d..4cd2a6bb87 100644 --- a/app/Notifications/Database/BackupSuccess.php +++ b/app/Notifications/Database/BackupSuccess.php @@ -49,6 +49,11 @@ public function toDiscord(): string return "Coolify: Database backup for {$this->name} (db:{$this->database_name}) with frequency of {$this->frequency} was successful."; } + public function toSlack(): string + { + return "Coolify: Database backup for {$this->name} (db:{$this->database_name}) with frequency of {$this->frequency} was successful."; + } + public function toTelegram(): array { $message = "Coolify: Database backup for {$this->name} (db:{$this->database_name}) with frequency of {$this->frequency} was successful."; diff --git a/app/Notifications/Database/DailyBackup.php b/app/Notifications/Database/DailyBackup.php index c74676eb74..f2949410d9 100644 --- a/app/Notifications/Database/DailyBackup.php +++ b/app/Notifications/Database/DailyBackup.php @@ -3,6 +3,7 @@ namespace App\Notifications\Database; use App\Notifications\Channels\DiscordChannel; +use App\Notifications\Channels\SlackChannel; use App\Notifications\Channels\TelegramChannel; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; @@ -22,7 +23,7 @@ public function __construct(public $databases) public function via(object $notifiable): array { - return [DiscordChannel::class, TelegramChannel::class, MailChannel::class]; + return [DiscordChannel::class, TelegramChannel::class, MailChannel::class, SlackChannel::class]; } public function toMail(): MailMessage @@ -41,6 +42,11 @@ public function toDiscord(): string return 'Coolify: Daily backup statuses'; } + public function toSlack(): string + { + return 'Coolify: Daily backup statuses'; + } + public function toTelegram(): array { $message = 'Coolify: Daily backup statuses'; diff --git a/app/Notifications/Internal/GeneralNotification.php b/app/Notifications/Internal/GeneralNotification.php index 6acd770f64..175fc1ac59 100644 --- a/app/Notifications/Internal/GeneralNotification.php +++ b/app/Notifications/Internal/GeneralNotification.php @@ -3,6 +3,7 @@ namespace App\Notifications\Internal; use App\Notifications\Channels\DiscordChannel; +use App\Notifications\Channels\SlackChannel; use App\Notifications\Channels\TelegramChannel; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; @@ -23,6 +24,7 @@ public function via(object $notifiable): array $channels = []; $isDiscordEnabled = data_get($notifiable, 'discord_enabled'); $isTelegramEnabled = data_get($notifiable, 'telegram_enabled'); + $isSlackEnabled = data_get($notifiable, 'slack_enabled'); if ($isDiscordEnabled) { $channels[] = DiscordChannel::class; @@ -30,7 +32,9 @@ public function via(object $notifiable): array if ($isTelegramEnabled) { $channels[] = TelegramChannel::class; } - + if ($isSlackEnabled) { + $channels[] = SlackChannel::class; + } return $channels; } @@ -39,6 +43,11 @@ public function toDiscord(): string return $this->message; } + public function toSlack(): string + { + return $this->message; + } + public function toTelegram(): array { return [ diff --git a/app/Notifications/ScheduledTask/TaskFailed.php b/app/Notifications/ScheduledTask/TaskFailed.php index 3a41fb687e..b1649c6a30 100644 --- a/app/Notifications/ScheduledTask/TaskFailed.php +++ b/app/Notifications/ScheduledTask/TaskFailed.php @@ -51,6 +51,11 @@ public function toDiscord(): string return "Coolify: Scheduled task ({$this->task->name}, [link]({$this->url})) failed with output: {$this->output}"; } + public function toSlack(): string + { + return "Coolify: Scheduled task ({$this->task->name}) failed with output: {$this->output}"; + } + public function toTelegram(): array { $message = "Coolify: Scheduled task ({$this->task->name}) failed with output: {$this->output}"; diff --git a/app/Notifications/Server/DockerCleanup.php b/app/Notifications/Server/DockerCleanup.php index 0e445f035a..9644d3a550 100644 --- a/app/Notifications/Server/DockerCleanup.php +++ b/app/Notifications/Server/DockerCleanup.php @@ -4,6 +4,7 @@ use App\Models\Server; use App\Notifications\Channels\DiscordChannel; +use App\Notifications\Channels\SlackChannel; use App\Notifications\Channels\TelegramChannel; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; @@ -25,6 +26,7 @@ public function via(object $notifiable): array // $isEmailEnabled = isEmailEnabled($notifiable); $isDiscordEnabled = data_get($notifiable, 'discord_enabled'); $isTelegramEnabled = data_get($notifiable, 'telegram_enabled'); + $isSlackEnabled = data_get($notifiable, 'slack_enabled'); if ($isDiscordEnabled) { $channels[] = DiscordChannel::class; @@ -35,6 +37,9 @@ public function via(object $notifiable): array if ($isTelegramEnabled) { $channels[] = TelegramChannel::class; } + if ($isSlackEnabled) { + $channels[] = SlackChannel::class; + } return $channels; } @@ -58,6 +63,11 @@ public function toDiscord(): string return $message; } + public function toSlack(): string + { + return "Coolify: Server '{$this->server->name}' cleanup job done!\n\n{$this->message}"; + } + public function toTelegram(): array { return [ diff --git a/app/Notifications/Server/ForceDisabled.php b/app/Notifications/Server/ForceDisabled.php index 960a7c79f7..e5c214b152 100644 --- a/app/Notifications/Server/ForceDisabled.php +++ b/app/Notifications/Server/ForceDisabled.php @@ -5,6 +5,7 @@ use App\Models\Server; use App\Notifications\Channels\DiscordChannel; use App\Notifications\Channels\EmailChannel; +use App\Notifications\Channels\SlackChannel; use App\Notifications\Channels\TelegramChannel; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; @@ -27,6 +28,7 @@ public function via(object $notifiable): array $isEmailEnabled = isEmailEnabled($notifiable); $isDiscordEnabled = data_get($notifiable, 'discord_enabled'); $isTelegramEnabled = data_get($notifiable, 'telegram_enabled'); + $isSlackEnabled = data_get($notifiable, 'slack_enabled'); if ($isDiscordEnabled) { $channels[] = DiscordChannel::class; @@ -37,6 +39,9 @@ public function via(object $notifiable): array if ($isTelegramEnabled) { $channels[] = TelegramChannel::class; } + if ($isSlackEnabled) { + $channels[] = SlackChannel::class; + } return $channels; } @@ -59,6 +64,11 @@ public function toDiscord(): string return $message; } + public function toSlack(): string + { + return "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/subsciprtions)."; + } + public function toTelegram(): array { return [ diff --git a/app/Notifications/Server/ForceEnabled.php b/app/Notifications/Server/ForceEnabled.php index 6a4b5d74bd..ec8f6e3866 100644 --- a/app/Notifications/Server/ForceEnabled.php +++ b/app/Notifications/Server/ForceEnabled.php @@ -5,6 +5,7 @@ use App\Models\Server; use App\Notifications\Channels\DiscordChannel; use App\Notifications\Channels\EmailChannel; +use App\Notifications\Channels\SlackChannel; use App\Notifications\Channels\TelegramChannel; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; @@ -27,6 +28,7 @@ public function via(object $notifiable): array $isEmailEnabled = isEmailEnabled($notifiable); $isDiscordEnabled = data_get($notifiable, 'discord_enabled'); $isTelegramEnabled = data_get($notifiable, 'telegram_enabled'); + $isSlackEnabled = data_get($notifiable, 'slack_enabled'); if ($isDiscordEnabled) { $channels[] = DiscordChannel::class; @@ -37,6 +39,9 @@ public function via(object $notifiable): array if ($isTelegramEnabled) { $channels[] = TelegramChannel::class; } + if ($isSlackEnabled) { + $channels[] = SlackChannel::class; + } return $channels; } @@ -59,6 +64,13 @@ public function toDiscord(): string return $message; } + public function toSlack(): string + { + $message = "Coolify: Server ({$this->server->name}) enabled again!"; + + return $message; + } + public function toTelegram(): array { return [ diff --git a/app/Notifications/Server/HighDiskUsage.php b/app/Notifications/Server/HighDiskUsage.php index 5f63ef8f1a..a11470090b 100644 --- a/app/Notifications/Server/HighDiskUsage.php +++ b/app/Notifications/Server/HighDiskUsage.php @@ -5,6 +5,7 @@ use App\Models\Server; use App\Notifications\Channels\DiscordChannel; use App\Notifications\Channels\EmailChannel; +use App\Notifications\Channels\SlackChannel; use App\Notifications\Channels\TelegramChannel; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; @@ -27,6 +28,7 @@ public function via(object $notifiable): array $isEmailEnabled = isEmailEnabled($notifiable); $isDiscordEnabled = data_get($notifiable, 'discord_enabled'); $isTelegramEnabled = data_get($notifiable, 'telegram_enabled'); + $isSlackEnabled = data_get($notifiable, 'slack_enabled'); if ($isDiscordEnabled) { $channels[] = DiscordChannel::class; @@ -37,6 +39,9 @@ public function via(object $notifiable): array if ($isTelegramEnabled) { $channels[] = TelegramChannel::class; } + if ($isSlackEnabled) { + $channels[] = SlackChannel::class; + } return $channels; } @@ -61,6 +66,13 @@ public function toDiscord(): string return $message; } + public function toSlack(): string + { + $message = "Coolify: Server '{$this->server->name}' high disk usage detected!\nDisk usage: {$this->disk_usage}%. Threshold: {$this->cleanup_after_percentage}%.\nPlease cleanup your disk to prevent data-loss.\nHere are some tips: https://coolify.io/docs/knowledge-base/server/automated-cleanup."; + + return $message; + } + public function toTelegram(): array { return [ diff --git a/app/Notifications/Server/Revived.php b/app/Notifications/Server/Revived.php index e7d3baf3ec..ff570b445d 100644 --- a/app/Notifications/Server/Revived.php +++ b/app/Notifications/Server/Revived.php @@ -7,6 +7,7 @@ use App\Models\Server; use App\Notifications\Channels\DiscordChannel; use App\Notifications\Channels\EmailChannel; +use App\Notifications\Channels\SlackChannel; use App\Notifications\Channels\TelegramChannel; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; @@ -34,6 +35,7 @@ public function via(object $notifiable): array $isEmailEnabled = isEmailEnabled($notifiable); $isDiscordEnabled = data_get($notifiable, 'discord_enabled'); $isTelegramEnabled = data_get($notifiable, 'telegram_enabled'); + $isSlackEnabled = data_get($notifiable, 'slack_enabled'); if ($isDiscordEnabled) { $channels[] = DiscordChannel::class; @@ -44,6 +46,9 @@ public function via(object $notifiable): array if ($isTelegramEnabled) { $channels[] = TelegramChannel::class; } + if ($isSlackEnabled) { + $channels[] = SlackChannel::class; + } return $channels; } @@ -66,6 +71,11 @@ public function toDiscord(): string return $message; } + public function toSlack(): string + { + return "Coolify: Server '{$this->server->name}' revived. All automations & integrations are turned on again!"; + } + public function toTelegram(): array { return [ diff --git a/app/Notifications/Server/Unreachable.php b/app/Notifications/Server/Unreachable.php index 2dcfe28b85..313663161a 100644 --- a/app/Notifications/Server/Unreachable.php +++ b/app/Notifications/Server/Unreachable.php @@ -5,6 +5,7 @@ use App\Models\Server; use App\Notifications\Channels\DiscordChannel; use App\Notifications\Channels\EmailChannel; +use App\Notifications\Channels\SlackChannel; use App\Notifications\Channels\TelegramChannel; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; @@ -28,6 +29,7 @@ public function via(object $notifiable): array $isEmailEnabled = isEmailEnabled($notifiable); $isDiscordEnabled = data_get($notifiable, 'discord_enabled'); $isTelegramEnabled = data_get($notifiable, 'telegram_enabled'); + $isSlackEnabled = data_get($notifiable, 'slack_enabled'); if ($isDiscordEnabled) { $channels[] = DiscordChannel::class; @@ -38,6 +40,9 @@ public function via(object $notifiable): array if ($isTelegramEnabled) { $channels[] = TelegramChannel::class; } + if ($isSlackEnabled) { + $channels[] = SlackChannel::class; + } return $channels; } @@ -60,6 +65,11 @@ public function toDiscord(): string return $message; } + public function toSlack(): string + { + return "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 toTelegram(): array { return [ diff --git a/app/Notifications/Test.php b/app/Notifications/Test.php index 925859aba8..438a9fc3f9 100644 --- a/app/Notifications/Test.php +++ b/app/Notifications/Test.php @@ -40,6 +40,15 @@ public function toDiscord(): string return $message; } + public function toSlack(): string + { + $message = 'Coolify: This is a test Slack notification from Coolify.'; + $message .= "\n\n"; + $message .= '<'.base_url().'|Go to your dashboard>'; + + return $message; + } + public function toTelegram(): array { return [ diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index 7994c10af1..84dfd3cfab 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -25,6 +25,7 @@ use App\Models\User; use App\Notifications\Channels\DiscordChannel; use App\Notifications\Channels\EmailChannel; +use App\Notifications\Channels\SlackChannel; use App\Notifications\Channels\TelegramChannel; use App\Notifications\Internal\GeneralNotification; use DanHarrin\LivewireRateLimiting\Exceptions\TooManyRequestsException; @@ -420,6 +421,7 @@ function setNotificationChannels($notifiable, $event) $channels = []; $isEmailEnabled = isEmailEnabled($notifiable); $isDiscordEnabled = data_get($notifiable, 'discord_enabled'); + $isSlackEnabled = data_get($notifiable, 'slack_enabled'); $isTelegramEnabled = data_get($notifiable, 'telegram_enabled'); $isSubscribedToEmailEvent = data_get($notifiable, "smtp_notifications_$event"); $isSubscribedToDiscordEvent = data_get($notifiable, "discord_notifications_$event"); @@ -434,6 +436,9 @@ function setNotificationChannels($notifiable, $event) if ($isTelegramEnabled && $isSubscribedToTelegramEvent) { $channels[] = TelegramChannel::class; } + if ($isSlackEnabled) { + $channels[] = SlackChannel::class; + } return $channels; } diff --git a/database/migrations/2024_06_18_132630_add_slack.php b/database/migrations/2024_06_18_132630_add_slack.php new file mode 100644 index 0000000000..6653f9a2fd --- /dev/null +++ b/database/migrations/2024_06_18_132630_add_slack.php @@ -0,0 +1,69 @@ +boolean('slack_enabled')->default(false); + $table->string('slack_webhook_url')->nullable(); + $table->boolean('slack_notifications_test')->default(true); + $table->boolean('slack_notifications_deployments')->default(true); + $table->boolean('slack_notifications_status_changes')->default(true); + $table->boolean('slack_notifications_database_backups')->default(true)->after('slack_notifications_status_changes'); + $table->boolean('slack_notifications_scheduled_tasks')->default(true)->after('slack_notifications_status_changes'); + + }); + $teams = Team::all(); + foreach ($teams as $team) { + $team->slack_enabled = data_get($team, 'slack.enabled', false); + $team->slack_webhook_url = data_get($team, 'slack.webhook_url'); + $team->slack_notifications_test = data_get($team, 'slack_notifications.test', true); + $team->slack_notifications_deployments = data_get($team, 'slack_notifications.deployments', true); + $team->slack_notifications_status_changes = data_get($team, 'slack_notifications.status_changes', true); + + $team->save(); + } + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('teams', function (Blueprint $table) { + $table->schemalessAttributes('slack'); + $table->schemalessAttributes('slack_notifications'); + }); + $teams = Team::all(); + foreach ($teams as $team) { + $team->slack = [ + 'enabled' => $team->slack_enabled, + 'webhook_url' => $team->slack_webhook_url, + ]; + $team->slack_notifications = [ + 'test' => $team->slack_notifications_test, + 'deployments' => $team->slack_notifications_deployments, + 'status_changes' => $team->slack_notifications_status_changes, + ]; + $team->save(); + } + Schema::table('teams', function (Blueprint $table) { + $table->dropColumn('slack_enabled'); + $table->dropColumn('slack_webhook_url'); + $table->dropColumn('slack_notifications_test'); + $table->dropColumn('slack_notifications_deployments'); + $table->dropColumn('slack_notifications_status_changes'); + $table->dropColumn('slack_notifications_scheduled_tasks'); + $table->dropColumn('slack_notifications_database_backups'); + }); + } +}; diff --git a/resources/views/components/notification/navbar.blade.php b/resources/views/components/notification/navbar.blade.php index 0fbbc69a23..12bbf68a2b 100644 --- a/resources/views/components/notification/navbar.blade.php +++ b/resources/views/components/notification/navbar.blade.php @@ -15,6 +15,10 @@ href="{{ route('notifications.discord') }}"> + + + diff --git a/resources/views/livewire/notifications/slack.blade.php b/resources/views/livewire/notifications/slack.blade.php new file mode 100644 index 0000000000..4c5853d692 --- /dev/null +++ b/resources/views/livewire/notifications/slack.blade.php @@ -0,0 +1,42 @@ +
+ + Notifications | Coolify + + +
+
+

Slack

+ + Save + + @if ($team->slack_enabled) + + Send Test Notifications + + @endif +
+
+ +
+ + + @if (data_get($team, 'slack_enabled')) +

Subscribe to events

+
+ @if (isDev()) + + @endif + + + + +
+ @endif +
diff --git a/routes/web.php b/routes/web.php index 0c012fd342..61bf6a86b2 100644 --- a/routes/web.php +++ b/routes/web.php @@ -11,6 +11,7 @@ use App\Livewire\Dev\Compose as Compose; use App\Livewire\ForcePasswordReset; use App\Livewire\Notifications\Discord as NotificationDiscord; +use App\Livewire\Notifications\Slack as NotificationSlack; use App\Livewire\Notifications\Email as NotificationEmail; use App\Livewire\Notifications\Telegram as NotificationTelegram; use App\Livewire\Profile\Index as ProfileIndex; @@ -126,6 +127,8 @@ Route::get('/email', NotificationEmail::class)->name('notifications.email'); Route::get('/telegram', NotificationTelegram::class)->name('notifications.telegram'); Route::get('/discord', NotificationDiscord::class)->name('notifications.discord'); + Route::get('/slack', NotificationSlack::class)->name('notifications.slack'); + }); Route::prefix('storages')->group(function () {