Skip to content

Commit

Permalink
feat(notification): add Pushover
Browse files Browse the repository at this point in the history
  • Loading branch information
zaosoula committed Dec 11, 2024
1 parent 1908d8a commit 4d972f1
Show file tree
Hide file tree
Showing 30 changed files with 745 additions and 4 deletions.
3 changes: 2 additions & 1 deletion app/Console/Commands/NotifyDemo.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ private function showHelp()
<li>slack</li>
<li>discord</li>
<li>telegram</li>
<li>pushover</li>
</ul>
</div>
</div>
Expand All @@ -72,6 +73,6 @@ private function showHelp()
<div class="mr-1">
In which manner you wish a <strong class="text-coolify">coolified</strong> notification?
</div>
HTML, ['email', 'slack', 'discord', 'telegram']);
HTML, ['email', 'slack', 'discord', 'telegram', 'pushover']);
}
}
47 changes: 47 additions & 0 deletions app/Jobs/SendMessageToPushoverJob.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace App\Jobs;

use App\Notifications\Dto\PushoverMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Http;

class SendMessageToPushoverJob implements ShouldBeEncrypted, ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

/**
* The number of times the job may be attempted.
*
* @var int
*/
public $tries = 5;

public $backoff = 10;

/**
* The maximum number of unhandled exceptions to allow before failing.
*/
public int $maxExceptions = 5;

public function __construct(
public PushoverMessage $message,
public string $token,
public string $user,
) {
$this->onQueue('high');
}

/**
* Execute the job.
*/
public function handle(): void
{
Http::post('https://api.pushover.net/1/messages.json', $this->message->toPayload($this->token, $this->user));
}
}
173 changes: 173 additions & 0 deletions app/Livewire/Notifications/Pushover.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
<?php

namespace App\Livewire\Notifications;

use App\Models\PushoverNotificationSettings;
use App\Models\Team;
use App\Notifications\Test;
use Livewire\Attributes\Validate;
use Livewire\Component;

class Pushover extends Component
{
public Team $team;

public PushoverNotificationSettings $settings;

#[Validate(['boolean'])]
public bool $pushoverEnabled = false;

#[Validate(['string', 'nullable'])]
public ?string $pushoverToken = null;

#[Validate(['string', 'nullable'])]
public ?string $pushoverUser = null;

#[Validate(['boolean'])]
public bool $deploymentSuccessPushoverNotifications = false;

#[Validate(['boolean'])]
public bool $deploymentFailurePushoverNotifications = true;

#[Validate(['boolean'])]
public bool $statusChangePushoverNotifications = false;

#[Validate(['boolean'])]
public bool $backupSuccessPushoverNotifications = false;

#[Validate(['boolean'])]
public bool $backupFailurePushoverNotifications = true;

#[Validate(['boolean'])]
public bool $scheduledTaskSuccessPushoverNotifications = false;

#[Validate(['boolean'])]
public bool $scheduledTaskFailurePushoverNotifications = true;

#[Validate(['boolean'])]
public bool $dockerCleanupSuccessPushoverNotifications = false;

#[Validate(['boolean'])]
public bool $dockerCleanupFailurePushoverNotifications = true;

#[Validate(['boolean'])]
public bool $serverDiskUsagePushoverNotifications = true;

#[Validate(['boolean'])]
public bool $serverReachablePushoverNotifications = false;

#[Validate(['boolean'])]
public bool $serverUnreachablePushoverNotifications = true;


public function mount()
{
try {
$this->team = auth()->user()->currentTeam();
$this->syncData();
} catch (\Throwable $e) {
return handleError($e, $this);
}
}

public function syncData(bool $toModel = false)
{
if ($toModel) {
$this->validate();
$this->team->pushover_enabled = $this->pushoverEnabled;
$this->team->pushover_user = $this->pushoverUser;
$this->team->pushover_token = $this->pushoverToken;
$this->settings->deployment_success_pushover_notifications = $this->deploymentSuccessPushoverNotifications;
$this->settings->deployment_failure_pushover_notifications = $this->deploymentFailurePushoverNotifications;
$this->settings->status_change_pushover_notifications = $this->statusChangePushoverNotifications;
$this->settings->backup_success_pushover_notifications = $this->backupSuccessPushoverNotifications;
$this->settings->backup_failure_pushover_notifications = $this->backupFailurePushoverNotifications;
$this->settings->scheduled_task_success_pushover_notifications = $this->scheduledTaskSuccessPushoverNotifications;
$this->settings->scheduled_task_failure_pushover_notifications = $this->scheduledTaskFailurePushoverNotifications;
$this->settings->docker_cleanup_success_pushover_notifications = $this->dockerCleanupSuccessPushoverNotifications;
$this->settings->docker_cleanup_failure_pushover_notifications = $this->dockerCleanupFailurePushoverNotifications;
$this->settings->server_disk_usage_pushover_notifications = $this->serverDiskUsagePushoverNotifications;
$this->settings->server_reachable_pushover_notifications = $this->serverReachablePushoverNotifications;
$this->settings->server_unreachable_pushover_notifications = $this->serverUnreachablePushoverNotifications;
$this->settings->save();
refreshSession();
} else {
$this->pushoverEnabled = $this->team->pushover_enabled;
$this->pushoverUser = $this->team->pushover_user;
$this->pushoverToken = $this->team->pushover_token;

$this->deploymentSuccessPushoverNotifications = $this->settings->deployment_success_pushover_notifications;
$this->deploymentFailurePushoverNotifications = $this->settings->deployment_failure_pushover_notifications;
$this->statusChangePushoverNotifications = $this->settings->status_change_pushover_notifications;
$this->backupSuccessPushoverNotifications = $this->settings->backup_success_pushover_notifications;
$this->backupFailurePushoverNotifications = $this->settings->backup_failure_pushover_notifications;
$this->scheduledTaskSuccessPushoverNotifications = $this->settings->scheduled_task_success_pushover_notifications;
$this->scheduledTaskFailurePushoverNotifications = $this->settings->scheduled_task_failure_pushover_notifications;
$this->dockerCleanupSuccessPushoverNotifications = $this->settings->docker_cleanup_success_pushover_notifications;
$this->dockerCleanupFailurePushoverNotifications = $this->settings->docker_cleanup_failure_pushover_notifications;
$this->serverDiskUsagePushoverNotifications = $this->settings->server_disk_usage_pushover_notifications;
$this->serverReachablePushoverNotifications = $this->settings->server_reachable_pushover_notifications;
$this->serverUnreachablePushoverNotifications = $this->settings->server_unreachable_pushover_notifications;
}
}

public function instantSavePushoverEnabled()
{
try {
$this->validate([
'pushoverUser' => 'required',
'pushoverToken' => 'required',
], [
'pushoverUser.required' => 'Pushover User is required.',
'pushoverToken.required' => 'Pushover Token is required.',
]);
$this->saveModel();
} catch (\Throwable $e) {
$this->pushoverEnabled = false;

return handleError($e, $this);
}
}

public function instantSave()
{
try {
$this->syncData(true);
} catch (\Throwable $e) {
return handleError($e, $this);
}
}

public function submit()
{
try {
$this->resetErrorBag();
$this->syncData(true);
$this->saveModel();
} catch (\Throwable $e) {
return handleError($e, $this);
}
}

public function saveModel()
{
$this->syncData(true);
refreshSession();
$this->dispatch('success', 'Settings saved.');
}

public function sendTestNotification()
{
try {
$this->team->notify(new Test(channel: 'pushover'));
$this->dispatch('success', 'Test notification sent.');
} catch (\Throwable $e) {
return handleError($e, $this);
}
}

public function render()
{
return view('livewire.notifications.pushover');
}
}
61 changes: 61 additions & 0 deletions app/Models/PushoverNotificationSettings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;

class PushoverNotificationSettings extends Model
{
use Notifiable;

public $timestamps = false;

protected $fillable = [
'team_id',

'pushover_enabled',
'pushover_user',
'pushover_token',

'deployment_success_pushover_notifications',
'deployment_failure_pushover_notifications',
'status_change_pushover_notifications',
'backup_success_pushover_notifications',
'backup_failure_pushover_notifications',
'scheduled_task_success_pushover_notifications',
'scheduled_task_failure_pushover_notifications',
'docker_cleanup_pushover_notifications',
'server_disk_usage_pushover_notifications',
'server_reachable_pushover_notifications',
'server_unreachable_pushover_notifications',
];

protected $casts = [
'pushover_enabled' => 'boolean',
'pushover_user' => 'encrypted',
'pushover_token' => 'encrypted',

'deployment_success_pushover_notifications' => 'boolean',
'deployment_failure_pushover_notifications' => 'boolean',
'status_change_pushover_notifications' => 'boolean',
'backup_success_pushover_notifications' => 'boolean',
'backup_failure_pushover_notifications' => 'boolean',
'scheduled_task_success_pushover_notifications' => 'boolean',
'scheduled_task_failure_pushover_notifications' => 'boolean',
'docker_cleanup_pushover_notifications' => 'boolean',
'server_disk_usage_pushover_notifications' => 'boolean',
'server_reachable_pushover_notifications' => 'boolean',
'server_unreachable_pushover_notifications' => 'boolean',
];

public function team()
{
return $this->belongsTo(Team::class);
}

public function isEnabled()
{
return $this->pushover_enabled;
}
}
19 changes: 17 additions & 2 deletions app/Models/Team.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use App\Notifications\Channels\SendsDiscord;
use App\Notifications\Channels\SendsEmail;
use App\Notifications\Channels\SendsSlack;
use App\Notifications\Channels\SendsPushover;
use App\Traits\HasNotificationSettings;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
Expand Down Expand Up @@ -32,7 +33,7 @@
]
)]

class Team extends Model implements SendsDiscord, SendsEmail, SendsSlack
class Team extends Model implements SendsDiscord, SendsEmail, SendsSlack, SendsPushover
{
use HasNotificationSettings, Notifiable;

Expand Down Expand Up @@ -154,6 +155,14 @@ public function routeNotificationForSlack()
{
return data_get($this, 'slack_webhook_url', null);
}

public function routeNotificationForPushover()
{
return [
'user' => data_get($this, 'pushover_user', null),
'token' => data_get($this, 'pushover_token', null),
];
}

public function getRecipients($notification)
{
Expand All @@ -174,7 +183,8 @@ public function isAnyNotificationEnabled()
return $this->getNotificationSettings('email')?->isEnabled() ||
$this->getNotificationSettings('discord')?->isEnabled() ||
$this->getNotificationSettings('slack')?->isEnabled() ||
$this->getNotificationSettings('telegram')?->isEnabled();
$this->getNotificationSettings('telegram')?->isEnabled() ||
$this->getNotificationSettings('pushover')?->isEnabled();
}

public function subscriptionEnded()
Expand Down Expand Up @@ -276,4 +286,9 @@ public function slackNotificationSettings()
{
return $this->hasOne(SlackNotificationSettings::class);
}

public function pushoverNotificationSettings()
{
return $this->hasOne(PushoverNotificationSettings::class);
}
}
21 changes: 21 additions & 0 deletions app/Notifications/Application/DeploymentFailed.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use App\Models\ApplicationPreview;
use App\Notifications\CustomEmailNotification;
use App\Notifications\Dto\DiscordMessage;
use App\Notifications\Dto\PushoverMessage;
use App\Notifications\Dto\SlackMessage;
use Illuminate\Notifications\Messages\MailMessage;

Expand Down Expand Up @@ -130,6 +131,26 @@ public function toTelegram(): array
];
}

public function toPushover(): PushoverMessage
{
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 . '): ';
}
$buttons[] = [
'text' => 'Deployment logs',
'url' => $this->deployment_url,
];

return new PushoverMessage(
message: $message,
buttons: [
...$buttons,
],
);
}

public function toSlack(): SlackMessage
{
if ($this->preview) {
Expand Down
Loading

0 comments on commit 4d972f1

Please sign in to comment.