Merge pull request #3907 from jnovakdev/main

Embedded messages for Discord notifications
This commit is contained in:
Andras Bacsai
2024-10-21 22:41:40 +02:00
committed by GitHub
20 changed files with 247 additions and 63 deletions

View File

@@ -2,6 +2,7 @@
namespace App\Jobs;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
use Illuminate\Contracts\Queue\ShouldQueue;
@@ -29,7 +30,7 @@ class SendMessageToDiscordJob implements ShouldBeEncrypted, ShouldQueue
public int $maxExceptions = 5;
public function __construct(
public string $text,
public DiscordMessage $message,
public string $webhookUrl
) {}
@@ -38,9 +39,6 @@ class SendMessageToDiscordJob implements ShouldBeEncrypted, ShouldQueue
*/
public function handle(): void
{
$payload = [
'content' => $this->text,
];
Http::post($this->webhookUrl, $payload);
Http::post($this->webhookUrl, $this->message->toPayload());
}
}

View File

@@ -4,6 +4,7 @@ namespace App\Notifications\Application;
use App\Models\Application;
use App\Models\ApplicationPreview;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@@ -72,14 +73,26 @@ class DeploymentFailed extends Notification implements ShouldQueue
return $mail;
}
public function toDiscord(): string
public function toDiscord(): DiscordMessage
{
if ($this->preview) {
$message = 'Coolify: Pull request #'.$this->preview->pull_request_id.' of '.$this->application_name.' ('.$this->preview->fqdn.') deployment failed: ';
$message .= '[View Deployment Logs]('.$this->deployment_url.')';
$message = new DiscordMessage(
title: 'Coolify: Deployment failed of pull request #'.$this->preview->pull_request_id.' of '.$this->application_name,
description: 'Check in the link below',
color: DiscordMessage::errorColor(),
isCritical: true,
);
$message->addField('Deployment Logs', '[Here]('.$this->deployment_url.')');
} else {
$message = 'Coolify: Deployment failed of '.$this->application_name.' ('.$this->fqdn.'): ';
$message .= '[View Deployment Logs]('.$this->deployment_url.')';
$message = new DiscordMessage(
title: 'Coolify: Deployment failed of '.$this->application_name,
description: 'Check in the link below',
color: DiscordMessage::errorColor(),
isCritical: true,
);
$message->addField('Deployment Logs', '[Here]('.$this->deployment_url.')');
}
return $message;

View File

@@ -4,6 +4,7 @@ namespace App\Notifications\Application;
use App\Models\Application;
use App\Models\ApplicationPreview;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@@ -78,24 +79,32 @@ class DeploymentSuccess extends Notification implements ShouldQueue
return $mail;
}
public function toDiscord(): string
public function toDiscord(): DiscordMessage
{
if ($this->preview) {
$message = 'Coolify: New PR'.$this->preview->pull_request_id.' version successfully deployed of '.$this->application_name.'
$message = new DiscordMessage(
title: "Coolify: New PR{$this->preview->pull_request_id} version successfully deployed of {$this->application_name}",
description: 'Check in the links below.',
color: DiscordMessage::successColor(),
);
';
if ($this->preview->fqdn) {
$message .= '[Open Application]('.$this->preview->fqdn.') | ';
$message->addField('Open Application', '[Here]('.$this->preview->fqdn.')');
}
$message .= '[Deployment logs]('.$this->deployment_url.')';
} else {
$message = 'Coolify: New version successfully deployed of '.$this->application_name.'
';
$message->addField('Deployment logs', '[Here]('.$this->deployment_url.')');
} else {
$message = new DiscordMessage(
title: "Coolify: New version successfully deployed of {$this->application_name}",
description: 'Check in the links below.',
color: DiscordMessage::successColor(),
);
if ($this->fqdn) {
$message .= '[Open Application]('.$this->fqdn.') | ';
$message->addField('Open Application', '[Here]('.$this->fqdn.')');
}
$message .= '[Deployment logs]('.$this->deployment_url.')';
$message->addField('Deployment logs', '[Here]('.$this->deployment_url.')');
}
return $message;

View File

@@ -3,6 +3,7 @@
namespace App\Notifications\Application;
use App\Models\Application;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@@ -55,12 +56,16 @@ class StatusChanged extends Notification implements ShouldQueue
return $mail;
}
public function toDiscord(): string
public function toDiscord(): DiscordMessage
{
$message = 'Coolify: '.$this->resource_name.' has been stopped.
$message = new DiscordMessage(
title: "Coolify: {$this->resource_name} has been stopped",
description: 'Check the application in Coolify',
color: DiscordMessage::errorColor(),
isCritical: true,
);
';
$message .= '[Open Application in Coolify]('.$this->resource_url.')';
$message->addField('Link', '[Open Application in Coolify]('.$this->resource_url.')');
return $message;
}

View File

@@ -12,7 +12,7 @@ class DiscordChannel
*/
public function send(SendsDiscord $notifiable, Notification $notification): void
{
$message = $notification->toDiscord($notifiable);
$message = $notification->toDiscord();
$webhookUrl = $notifiable->routeNotificationForDiscord();
if (! $webhookUrl) {
return;

View File

@@ -3,6 +3,7 @@
namespace App\Notifications\Container;
use App\Models\Server;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@@ -34,9 +35,13 @@ class ContainerRestarted extends Notification implements ShouldQueue
return $mail;
}
public function toDiscord(): string
public function toDiscord(): DiscordMessage
{
$message = "Coolify: A resource ({$this->name}) has been restarted automatically on {$this->server->name}";
$message = new DiscordMessage(
title: "Coolify: A resource ({$this->name}) has been restarted automatically on {$this->server->name}",
description: 'Please check the output below for more information.',
color: DiscordMessage::infoColor(),
);
return $message;
}

View File

@@ -3,6 +3,7 @@
namespace App\Notifications\Container;
use App\Models\Server;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@@ -34,11 +35,13 @@ class ContainerStopped extends Notification implements ShouldQueue
return $mail;
}
public function toDiscord(): string
public function toDiscord(): DiscordMessage
{
$message = "Coolify: A resource ($this->name) has been stopped unexpectedly on {$this->server->name}";
return $message;
return new DiscordMessage(
title: "Coolify: A resource ($this->name) has been stopped unexpectedly on {$this->server->name}",
description: 'Please check the output below for more information.',
color: DiscordMessage::errorColor(),
);
}
public function toTelegram(): array

View File

@@ -3,6 +3,7 @@
namespace App\Notifications\Database;
use App\Models\ScheduledDatabaseBackup;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@@ -45,9 +46,19 @@ class BackupFailed extends Notification implements ShouldQueue
return $mail;
}
public function toDiscord(): string
public function toDiscord(): DiscordMessage
{
return "Coolify: Database backup for {$this->name} (db:{$this->database_name}) with frequency of {$this->frequency} was FAILED.\n\nReason:\n{$this->output}";
$message = new DiscordMessage(
title: "Coolify: Database backup for {$this->name} (db:{$this->database_name}) has FAILED.",
description: 'Please check the output below for more information.',
color: DiscordMessage::errorColor(),
isCritical: true,
);
$message->addField('Frequency', $this->frequency);
$message->addField('Output', $this->output);
return $message;
}
public function toTelegram(): array

View File

@@ -3,6 +3,7 @@
namespace App\Notifications\Database;
use App\Models\ScheduledDatabaseBackup;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@@ -44,9 +45,17 @@ class BackupSuccess extends Notification implements ShouldQueue
return $mail;
}
public function toDiscord(): string
public function toDiscord(): DiscordMessage
{
return "Coolify: Database backup for {$this->name} (db:{$this->database_name}) with frequency of {$this->frequency} was successful.";
$message = new DiscordMessage(
title: "Coolify: Database backup for {$this->name} (db:{$this->database_name}) was successful.",
description: 'Please check the output below for more information.',
color: DiscordMessage::successColor(),
);
$message->addField('Frequency', $this->frequency);
return $message;
}
public function toTelegram(): array

View File

@@ -4,6 +4,7 @@ namespace App\Notifications\Database;
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\Channels\MailChannel;
@@ -34,9 +35,13 @@ class DailyBackup extends Notification implements ShouldQueue
return $mail;
}
public function toDiscord(): string
public function toDiscord(): DiscordMessage
{
return 'Coolify: Daily backup statuses';
return new DiscordMessage(
title: 'Coolify: Daily backup statuses',
description: 'Nothing to report.',
color: DiscordMessage::infoColor(),
); // todo: is this necessary notification? what is the purpose of this notification?
}
public function toTelegram(): array

View File

@@ -0,0 +1,75 @@
<?php
namespace App\Notifications\Dto;
class DiscordMessage
{
private array $fields = [];
public function __construct(
public string $title,
public string $description,
public int $color,
public bool $isCritical = false,
) {}
public static function successColor(): int
{
return hexdec('a1ffa5');
}
public static function warningColor(): int
{
return hexdec('ffa743');
}
public static function errorColor(): int
{
return hexdec('ff705f');
}
public static function infoColor(): int
{
return hexdec('4f545c');
}
public function addField(string $name, string $value): self
{
$this->fields[] = [
'name' => $name,
'value' => $value,
];
return $this;
}
public function toPayload(): array
{
$payload = [
'embeds' => [
[
'title' => $this->title,
'description' => $this->description,
'color' => $this->color,
'fields' => $this->addTimestampToFields($this->fields),
],
],
];
if ($this->isCritical) {
$payload['content'] = '@here';
}
return $payload;
}
private function addTimestampToFields(array $fields): array
{
$fields[] = [
'name' => 'Time',
'value' => '<t:'.now()->timestamp.':R>',
];
return $fields;
}
}

View File

@@ -4,6 +4,7 @@ namespace App\Notifications\Internal;
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;
@@ -32,9 +33,13 @@ class GeneralNotification extends Notification implements ShouldQueue
return $channels;
}
public function toDiscord(): string
public function toDiscord(): DiscordMessage
{
return $this->message;
return new DiscordMessage(
title: 'Coolify: General Notification',
description: $this->message,
color: DiscordMessage::infoColor(),
);
}
public function toTelegram(): array

View File

@@ -3,6 +3,7 @@
namespace App\Notifications\ScheduledTask;
use App\Models\ScheduledTask;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@@ -46,9 +47,17 @@ class TaskFailed extends Notification implements ShouldQueue
return $mail;
}
public function toDiscord(): string
public function toDiscord(): DiscordMessage
{
return "Coolify: Scheduled task ({$this->task->name}, [link]({$this->url})) failed with output: {$this->output}";
$message = new DiscordMessage(
title: "Coolify: Scheduled task ({$this->task->name}) failed.",
description: "Output: {$this->output}",
color: DiscordMessage::errorColor(),
);
$message->addField('Link', '[Open task in Coolify]('.$this->url.')');
return $message;
}
public function toTelegram(): array

View File

@@ -5,6 +5,7 @@ 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;
@@ -49,11 +50,13 @@ class DockerCleanup extends Notification implements ShouldQueue
// return $mail;
// }
public function toDiscord(): string
public function toDiscord(): DiscordMessage
{
$message = "Coolify: Server '{$this->server->name}' cleanup job done!\n\n{$this->message}";
return $message;
return new DiscordMessage(
title: "Coolify: Server '{$this->server->name}' cleanup job done!",
description: $this->message,
color: DiscordMessage::successColor(),
);
}
public function toTelegram(): array

View File

@@ -6,6 +6,7 @@ use App\Models\Server;
use App\Notifications\Channels\DiscordChannel;
use App\Notifications\Channels\EmailChannel;
use App\Notifications\Channels\TelegramChannel;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@@ -50,9 +51,15 @@ class ForceDisabled extends Notification implements ShouldQueue
return $mail;
}
public function toDiscord(): string
public function toDiscord(): DiscordMessage
{
$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).";
$message = new DiscordMessage(
title: "Coolify: Server ({$this->server->name}) disabled because it is not paid!",
description: 'All automations and integrations are stopped.',
color: DiscordMessage::errorColor(),
);
$message->addField('Link', 'Please update your subscription to enable the server again [here](https://app.coolify.io/subscriptions).');
return $message;
}

View File

@@ -6,6 +6,7 @@ use App\Models\Server;
use App\Notifications\Channels\DiscordChannel;
use App\Notifications\Channels\EmailChannel;
use App\Notifications\Channels\TelegramChannel;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@@ -50,11 +51,13 @@ class ForceEnabled extends Notification implements ShouldQueue
return $mail;
}
public function toDiscord(): string
public function toDiscord(): DiscordMessage
{
$message = "Coolify: Server ({$this->server->name}) enabled again!";
return $message;
return new DiscordMessage(
title: "Coolify: Server '{$this->server->name}' enabled again!",
description: 'All automations and integrations are started.',
color: DiscordMessage::successColor(),
);
}
public function toTelegram(): array

View File

@@ -6,6 +6,7 @@ use App\Models\Server;
use App\Notifications\Channels\DiscordChannel;
use App\Notifications\Channels\EmailChannel;
use App\Notifications\Channels\TelegramChannel;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@@ -52,9 +53,17 @@ class HighDiskUsage extends Notification implements ShouldQueue
return $mail;
}
public function toDiscord(): string
public function toDiscord(): DiscordMessage
{
$message = "Coolify: Server '{$this->server->name}' high disk usage detected!\nDisk usage: {$this->disk_usage}%. Threshold: {$this->docker_cleanup_threshold}%.\nPlease cleanup your disk to prevent data-loss.\nHere are some tips: https://coolify.io/docs/knowledge-base/server/automated-cleanup.";
$message = new DiscordMessage(
title: "Coolify: Server '{$this->server->name}' high disk usage detected!",
description: 'Please cleanup your disk to prevent data-loss.',
color: DiscordMessage::errorColor(),
);
$message->addField('Disk usage', "{$this->disk_usage}%");
$message->addField('Threshold', "{$this->docker_cleanup_threshold}%");
$message->addField('Link', 'Here are some tips: https://coolify.io/docs/knowledge-base/server/automated-cleanup.');
return $message;
}

View File

@@ -8,6 +8,7 @@ use App\Models\Server;
use App\Notifications\Channels\DiscordChannel;
use App\Notifications\Channels\EmailChannel;
use App\Notifications\Channels\TelegramChannel;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@@ -72,11 +73,13 @@ class Revived extends Notification implements ShouldQueue
return $mail;
}
public function toDiscord(): string
public function toDiscord(): DiscordMessage
{
$message = "Coolify: Server '{$this->server->name}' revived. All automations & integrations are turned on again!";
return $message;
return new DiscordMessage(
title: "Coolify: Server '{$this->server->name}' revived.",
description: 'All automations & integrations are turned on again!',
color: DiscordMessage::successColor(),
);
}
public function toTelegram(): array

View File

@@ -6,6 +6,7 @@ use App\Models\Server;
use App\Notifications\Channels\DiscordChannel;
use App\Notifications\Channels\EmailChannel;
use App\Notifications\Channels\TelegramChannel;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@@ -63,9 +64,15 @@ class Unreachable extends Notification implements ShouldQueue
return $mail;
}
public function toDiscord(): string
public function toDiscord(): DiscordMessage
{
$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.";
$message = new DiscordMessage(
title: "Coolify: Your server '{$this->server->name}' is unreachable.",
description: 'All automations & integrations are turned off! Please check your server!',
color: DiscordMessage::errorColor(),
);
$message->addField('IMPORTANT', 'We automatically try to revive your server and turn on all automations & integrations.');
return $message;
}

View File

@@ -2,6 +2,7 @@
namespace App\Notifications;
use App\Notifications\Dto\DiscordMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@@ -29,11 +30,15 @@ class Test extends Notification implements ShouldQueue
return $mail;
}
public function toDiscord(): string
public function toDiscord(): DiscordMessage
{
$message = 'Coolify: This is a test Discord notification from Coolify.';
$message .= "\n\n";
$message .= '[Go to your dashboard]('.base_url().')';
$message = new DiscordMessage(
title: 'Coolify: This is a test Discord notification from Coolify.',
description: 'This is a test Discord notification from Coolify.',
color: DiscordMessage::successColor(),
);
$message->addField('Link', '[Go to your dashboard]('.base_url().')');
return $message;
}