feat: scheduled task failed notification

This commit is contained in:
Andras Bacsai
2024-05-21 15:36:26 +02:00
parent 98b6aec203
commit a3d73634e7
16 changed files with 154 additions and 6 deletions

View File

@@ -6,14 +6,12 @@ use App\Actions\Database\StartDatabaseProxy;
use App\Actions\Proxy\CheckProxy;
use App\Actions\Proxy\StartProxy;
use App\Actions\Shared\ComplexStatusCheck;
use App\Models\Application;
use App\Models\ApplicationPreview;
use App\Models\Server;
use App\Models\ServiceDatabase;
use App\Notifications\Container\ContainerRestarted;
use App\Notifications\Container\ContainerStopped;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Log;
use Lorisleiva\Actions\Concerns\AsAction;
class GetContainersStatus

View File

@@ -8,14 +8,13 @@ use App\Models\Server;
use App\Models\Application;
use App\Models\Service;
use App\Models\Team;
use App\Notifications\ScheduledTask\TaskFailed;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\Middleware\WithoutOverlapping;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Collection;
use Throwable;
class ScheduledTaskJob implements ShouldQueue
{
@@ -114,6 +113,7 @@ class ScheduledTaskJob implements ShouldQueue
'message' => $this->task_output ?? $e->getMessage(),
]);
}
$this->team?->notify(new TaskFailed($this->task, $e->getMessage()));
// send_internal_notification('ScheduledTaskJob failed with: ' . $e->getMessage());
throw $e;
}

View File

@@ -41,7 +41,6 @@ class SendMessageToDiscordJob implements ShouldQueue, ShouldBeEncrypted
$payload = [
'content' => $this->text,
];
ray($payload);
Http::post($this->webhookUrl, $payload);
}
}

View File

@@ -16,6 +16,7 @@ class Discord extends Component
'team.discord_notifications_deployments' => 'nullable|boolean',
'team.discord_notifications_status_changes' => 'nullable|boolean',
'team.discord_notifications_database_backups' => 'nullable|boolean',
'team.discord_notifications_scheduled_tasks' => 'nullable|boolean',
];
protected $validationAttributes = [
'team.discord_webhook_url' => 'Discord Webhook',

View File

@@ -28,6 +28,7 @@ class Email extends Component
'team.smtp_notifications_deployments' => 'nullable|boolean',
'team.smtp_notifications_status_changes' => 'nullable|boolean',
'team.smtp_notifications_database_backups' => 'nullable|boolean',
'team.smtp_notifications_scheduled_tasks' => 'nullable|boolean',
'team.use_instance_email_settings' => 'boolean',
'team.resend_enabled' => 'nullable|boolean',
'team.resend_api_key' => 'nullable',

View File

@@ -18,10 +18,12 @@ class Telegram extends Component
'team.telegram_notifications_deployments' => 'nullable|boolean',
'team.telegram_notifications_status_changes' => 'nullable|boolean',
'team.telegram_notifications_database_backups' => 'nullable|boolean',
'team.telegram_notifications_scheduled_tasks' => 'nullable|boolean',
'team.telegram_notifications_test_message_thread_id' => 'nullable|string',
'team.telegram_notifications_deployments_message_thread_id' => 'nullable|string',
'team.telegram_notifications_status_changes_message_thread_id' => 'nullable|string',
'team.telegram_notifications_database_backups_message_thread_id' => 'nullable|string',
'team.telegram_notifications_scheduled_tasks_thread_id' => 'nullable|string',
];
protected $validationAttributes = [
'team.telegram_token' => 'Token',

View File

@@ -113,6 +113,18 @@ class Application extends BaseModel
}
return null;
}
public function failedTaskLink($task_uuid)
{
if (data_get($this, 'environment.project.uuid')) {
return route('project.application.scheduled-tasks', [
'project_uuid' => data_get($this, 'environment.project.uuid'),
'environment_name' => data_get($this, 'environment.name'),
'application_uuid' => data_get($this, 'uuid'),
'task_uuid' => $task_uuid
]);
}
return null;
}
public function settings()
{
return $this->hasOne(ApplicationSetting::class);

View File

@@ -653,6 +653,18 @@ class Service extends BaseModel
}
return null;
}
public function failedTaskLink($task_uuid)
{
if (data_get($this, 'environment.project.uuid')) {
return route('project.service.scheduled-tasks', [
'project_uuid' => data_get($this, 'environment.project.uuid'),
'environment_name' => data_get($this, 'environment.name'),
'application_uuid' => data_get($this, 'uuid'),
'task_uuid' => $task_uuid
]);
}
return null;
}
public function documentation()
{
$services = getServiceTemplates();

View File

@@ -32,6 +32,9 @@ class TelegramChannel
case 'App\Notifications\Database\BackupFailed':
$topicId = data_get($notifiable, 'telegram_notifications_database_backups_message_thread_id');
break;
case 'App\Notifications\ScheduledTask\TaskFailed':
$topicId = data_get($notifiable, 'telegram_notifications_scheduled_tasks_thread_id');
break;
}
if (!$telegramToken || !$chatId || !$message) {
return;

View File

@@ -31,7 +31,7 @@ class ContainerRestarted extends Notification implements ShouldQueue
$mail->view('emails.container-restarted', [
'containerName' => $this->name,
'serverName' => $this->server->name,
'url' => $this->url ,
'url' => $this->url,
]);
return $mail;
}

View File

@@ -0,0 +1,64 @@
<?php
namespace App\Notifications\ScheduledTask;
use App\Models\ScheduledTask;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class TaskFailed extends Notification implements ShouldQueue
{
use Queueable;
public $backoff = 10;
public $tries = 2;
public ?string $url = null;
public function __construct(public ScheduledTask $task, public string $output)
{
if ($task->application) {
$this->url = $task->application->failedTaskLink($task->uuid);
} else if ($task->service) {
$this->url = $task->service->failedTaskLink($task->uuid);
}
}
public function via(object $notifiable): array
{
return setNotificationChannels($notifiable, 'scheduled_tasks');
}
public function toMail(): MailMessage
{
$mail = new MailMessage();
$mail->subject("Coolify: [ACTION REQUIRED] Scheduled task ({$this->task->name}) failed.");
$mail->view('emails.scheduled-task-failed', [
'task' => $this->task,
'url' => $this->url,
'output' => $this->output,
]);
return $mail;
}
public function toDiscord(): string
{
return "Coolify: Scheduled task ({$this->task->name}, [link]({$this->url})) failed with output: {$this->output}";
}
public function toTelegram(): array
{
$message = "Coolify: Scheduled task ({$this->task->name}) failed with output: {$this->output}";
if ($this->url) {
$buttons[] = [
"text" => "Open task in Coolify",
"url" => (string) $this->url
];
}
return [
"message" => $message,
];
}
}