lasthourcloud/app/Console/Commands/Emails.php

318 lines
13 KiB
PHP
Raw Normal View History

2023-09-01 13:52:18 +00:00
<?php
namespace App\Console\Commands;
use App\Jobs\SendConfirmationForWaitlistJob;
2023-09-01 13:52:18 +00:00
use App\Models\Application;
use App\Models\ApplicationPreview;
use App\Models\ScheduledDatabaseBackup;
2023-09-13 09:05:10 +00:00
use App\Models\Server;
2023-09-01 13:52:18 +00:00
use App\Models\StandalonePostgresql;
2023-09-12 10:03:17 +00:00
use App\Models\Team;
use App\Models\Waitlist;
2023-09-01 13:52:18 +00:00
use App\Notifications\Application\DeploymentFailed;
use App\Notifications\Application\DeploymentSuccess;
use App\Notifications\Application\StatusChanged;
use App\Notifications\Database\BackupFailed;
use App\Notifications\Database\BackupSuccess;
use App\Notifications\Database\DailyBackup;
2023-09-01 13:52:18 +00:00
use App\Notifications\Test;
use Exception;
use Illuminate\Console\Command;
use Illuminate\Mail\Message;
use Illuminate\Notifications\Messages\MailMessage;
use Mail;
2023-09-12 11:19:55 +00:00
use function Laravel\Prompts\confirm;
2023-09-01 13:52:18 +00:00
use function Laravel\Prompts\select;
2023-09-08 15:42:08 +00:00
use function Laravel\Prompts\text;
2023-09-01 13:52:18 +00:00
2023-09-12 11:19:55 +00:00
class Emails extends Command
2023-09-01 13:52:18 +00:00
{
/**
* The name and signature of the console command.
*
* @var string
*/
2023-09-12 11:19:55 +00:00
protected $signature = 'emails';
2023-09-01 13:52:18 +00:00
/**
* The console command description.
*
* @var string
*/
2023-09-12 11:19:55 +00:00
protected $description = 'Send out test / prod emails';
2023-09-01 13:52:18 +00:00
/**
* Execute the console command.
*/
private ?MailMessage $mail = null;
2024-06-10 20:43:34 +00:00
2023-09-12 11:19:55 +00:00
private ?string $email = null;
2024-06-10 20:43:34 +00:00
2023-09-01 13:52:18 +00:00
public function handle()
{
2023-09-08 15:42:08 +00:00
$type = select(
2023-09-01 13:52:18 +00:00
'Which Email should be sent?',
options: [
2023-09-25 18:57:52 +00:00
'updates' => 'Send Update Email to all users',
2023-09-01 13:52:18 +00:00
'emails-test' => 'Test',
'database-backup-statuses-daily' => 'Database - Backup Statuses (Daily)',
'application-deployment-success-daily' => 'Application - Deployment Success (Daily)',
2023-09-01 13:52:18 +00:00
'application-deployment-success' => 'Application - Deployment Success',
'application-deployment-failed' => 'Application - Deployment Failed',
'application-status-changed' => 'Application - Status Changed',
'backup-success' => 'Database - Backup Success',
'backup-failed' => 'Database - Backup Failed',
2023-09-15 09:19:36 +00:00
// 'invitation-link' => 'Invitation Link',
2023-09-01 13:52:18 +00:00
'waitlist-invitation-link' => 'Waitlist Invitation Link',
'waitlist-confirmation' => 'Waitlist Confirmation',
2023-09-12 10:03:17 +00:00
'realusers-before-trial' => 'REAL - Registered Users Before Trial without Subscription',
2023-09-13 09:05:10 +00:00
'realusers-server-lost-connection' => 'REAL - Server Lost Connection',
2023-09-01 13:52:18 +00:00
],
);
2023-09-25 18:57:52 +00:00
$emailsGathered = ['realusers-before-trial', 'realusers-server-lost-connection'];
if (isDev()) {
2024-06-10 20:43:34 +00:00
$this->email = 'test@example.com';
} else {
2024-06-10 20:43:34 +00:00
if (! in_array($type, $emailsGathered)) {
$this->email = text('Email Address to send to:');
}
2023-09-12 10:03:17 +00:00
}
2023-09-08 15:42:08 +00:00
set_transanctional_email_settings();
2024-07-24 12:27:21 +00:00
$this->mail = new MailMessage;
2024-06-10 20:43:34 +00:00
$this->mail->subject('Test Email');
2023-09-08 15:42:08 +00:00
switch ($type) {
2023-09-25 18:57:52 +00:00
case 'updates':
$teams = Team::all();
2024-06-10 20:43:34 +00:00
if (! $teams || $teams->isEmpty()) {
echo 'No teams found.'.PHP_EOL;
2023-09-25 18:57:52 +00:00
return;
}
$emails = [];
foreach ($teams as $team) {
foreach ($team->members as $member) {
if ($member->email && $member->marketing_emails) {
$emails[] = $member->email;
}
}
}
$emails = array_unique($emails);
2024-06-10 20:43:34 +00:00
$this->info('Sending to '.count($emails).' emails.');
2023-09-25 18:57:52 +00:00
foreach ($emails as $email) {
$this->info($email);
}
$confirmed = confirm('Are you sure?');
if ($confirmed) {
foreach ($emails as $email) {
2024-07-24 12:27:21 +00:00
$this->mail = new MailMessage;
2023-09-25 18:57:52 +00:00
$this->mail->subject('One-click Services, Docker Compose support');
$unsubscribeUrl = route('unsubscribe.marketing.emails', [
'token' => encrypt($email),
]);
2024-06-10 20:43:34 +00:00
$this->mail->view('emails.updates', ['unsubscribeUrl' => $unsubscribeUrl]);
2023-09-25 18:57:52 +00:00
$this->sendEmail($email);
}
}
break;
2023-09-01 13:52:18 +00:00
case 'emails-test':
2024-07-24 12:27:21 +00:00
$this->mail = (new Test)->toMail();
2023-09-08 15:42:08 +00:00
$this->sendEmail();
2023-09-01 13:52:18 +00:00
break;
case 'database-backup-statuses-daily':
$scheduled_backups = ScheduledDatabaseBackup::all();
$databases = collect();
foreach ($scheduled_backups as $scheduled_backup) {
$last_days_backups = $scheduled_backup->get_last_days_backup_status();
if ($last_days_backups->isEmpty()) {
continue;
}
$failed = $last_days_backups->where('status', 'failed');
$database = $scheduled_backup->database;
$databases->put($database->name, [
'failed_count' => $failed->count(),
]);
}
$this->mail = (new DailyBackup($databases))->toMail();
$this->sendEmail();
break;
case 'application-deployment-success-daily':
$applications = Application::all();
foreach ($applications as $application) {
$deployments = $application->get_last_days_deployments();
ray($deployments);
if ($deployments->isEmpty()) {
continue;
}
$this->mail = (new DeploymentSuccess($application, 'test'))->toMail();
$this->sendEmail();
}
break;
2023-09-01 13:52:18 +00:00
case 'application-deployment-success':
$application = Application::all()->first();
$this->mail = (new DeploymentSuccess($application, 'test'))->toMail();
$this->sendEmail();
break;
case 'application-deployment-failed':
$application = Application::all()->first();
$preview = ApplicationPreview::all()->first();
2024-06-10 20:43:34 +00:00
if (! $preview) {
2023-09-01 13:52:18 +00:00
$preview = ApplicationPreview::create([
'application_id' => $application->id,
'pull_request_id' => 1,
'pull_request_html_url' => 'http://example.com',
'fqdn' => $application->fqdn,
]);
}
$this->mail = (new DeploymentFailed($application, 'test'))->toMail();
$this->sendEmail();
$this->mail = (new DeploymentFailed($application, 'test', $preview))->toMail();
$this->sendEmail();
break;
case 'application-status-changed':
$application = Application::all()->first();
$this->mail = (new StatusChanged($application))->toMail();
$this->sendEmail();
break;
case 'backup-failed':
$backup = ScheduledDatabaseBackup::all()->first();
$db = StandalonePostgresql::all()->first();
2024-06-10 20:43:34 +00:00
if (! $backup) {
2023-09-01 13:52:18 +00:00
$backup = ScheduledDatabaseBackup::create([
'enabled' => true,
'frequency' => 'daily',
'save_s3' => false,
'database_id' => $db->id,
'database_type' => $db->getMorphClass(),
'team_id' => 0,
]);
}
2024-06-10 20:43:34 +00:00
$output = 'Because of an error, the backup of the database '.$db->name.' failed.';
2023-09-01 13:52:18 +00:00
$this->mail = (new BackupFailed($backup, $db, $output))->toMail();
$this->sendEmail();
break;
case 'backup-success':
$backup = ScheduledDatabaseBackup::all()->first();
$db = StandalonePostgresql::all()->first();
2024-06-10 20:43:34 +00:00
if (! $backup) {
2023-09-01 13:52:18 +00:00
$backup = ScheduledDatabaseBackup::create([
'enabled' => true,
'frequency' => 'daily',
'save_s3' => false,
'database_id' => $db->id,
'database_type' => $db->getMorphClass(),
'team_id' => 0,
]);
}
$this->mail = (new BackupSuccess($backup, $db))->toMail();
$this->sendEmail();
break;
2023-09-25 18:57:52 +00:00
// case 'invitation-link':
// $user = User::all()->first();
// $invitation = TeamInvitation::whereEmail($user->email)->first();
// if (!$invitation) {
// $invitation = TeamInvitation::create([
// 'uuid' => Str::uuid(),
// 'email' => $user->email,
// 'team_id' => 1,
// 'link' => 'http://example.com',
// ]);
// }
// $this->mail = (new InvitationLink($user))->toMail();
// $this->sendEmail();
// break;
2023-09-01 13:52:18 +00:00
case 'waitlist-invitation-link':
2024-07-24 12:27:21 +00:00
$this->mail = new MailMessage;
2023-09-01 13:52:18 +00:00
$this->mail->view('emails.waitlist-invitation', [
'loginLink' => 'https://coolify.io',
2023-09-01 13:52:18 +00:00
]);
$this->mail->subject('Congratulations! You are invited to join Coolify Cloud.');
$this->sendEmail();
break;
case 'waitlist-confirmation':
$found = Waitlist::where('email', $this->email)->first();
if ($found) {
SendConfirmationForWaitlistJob::dispatch($this->email, $found->uuid);
} else {
throw new Exception('Waitlist not found');
}
2023-09-01 13:52:18 +00:00
break;
2023-09-12 10:03:17 +00:00
case 'realusers-before-trial':
2024-07-24 12:27:21 +00:00
$this->mail = new MailMessage;
2023-09-12 10:03:17 +00:00
$this->mail->view('emails.before-trial-conversion');
$this->mail->subject('Trial period has been added for all subscription plans.');
$teams = Team::doesntHave('subscription')->where('id', '!=', 0)->get();
2024-06-10 20:43:34 +00:00
if (! $teams || $teams->isEmpty()) {
echo 'No teams found.'.PHP_EOL;
2023-09-12 10:03:17 +00:00
return;
}
$emails = [];
foreach ($teams as $team) {
2023-09-12 11:19:55 +00:00
foreach ($team->members as $member) {
2023-09-12 10:03:17 +00:00
if ($member->email) {
$emails[] = $member->email;
}
}
}
$emails = array_unique($emails);
2024-06-10 20:43:34 +00:00
$this->info('Sending to '.count($emails).' emails.');
2023-09-12 10:03:17 +00:00
foreach ($emails as $email) {
2023-09-12 11:19:55 +00:00
$this->info($email);
2023-09-12 10:03:17 +00:00
}
2023-09-12 11:19:55 +00:00
$confirmed = confirm('Are you sure?');
if ($confirmed) {
foreach ($emails as $email) {
$this->sendEmail($email);
}
}
break;
2023-09-13 09:05:10 +00:00
case 'realusers-server-lost-connection':
$serverId = text('Server Id');
$server = Server::find($serverId);
2024-06-10 20:43:34 +00:00
if (! $server) {
2023-09-13 09:05:10 +00:00
throw new Exception('Server not found');
}
$admins = [];
$members = $server->team->members;
foreach ($members as $member) {
if ($member->isAdmin()) {
$admins[] = $member->email;
}
}
2024-06-10 20:43:34 +00:00
$this->info('Sending to '.count($admins).' admins.');
2023-09-13 09:05:10 +00:00
foreach ($admins as $admin) {
$this->info($admin);
}
2024-07-24 12:27:21 +00:00
$this->mail = new MailMessage;
2023-09-13 09:05:10 +00:00
$this->mail->view('emails.server-lost-connection', [
'name' => $server->name,
]);
2024-06-10 20:43:34 +00:00
$this->mail->subject('Action required: Server '.$server->name.' lost connection.');
2023-09-13 09:05:10 +00:00
foreach ($admins as $email) {
$this->sendEmail($email);
}
break;
2023-09-01 13:52:18 +00:00
}
}
2024-06-10 20:43:34 +00:00
private function sendEmail(?string $email = null)
2023-09-01 13:52:18 +00:00
{
2023-09-12 10:03:17 +00:00
if ($email) {
$this->email = $email;
}
2023-09-01 13:52:18 +00:00
Mail::send(
[],
[],
fn (Message $message) => $message
2023-09-08 15:42:08 +00:00
->to($this->email)
2023-09-01 13:52:18 +00:00
->subject($this->mail->subject)
2024-06-10 20:43:34 +00:00
->html((string) $this->mail->render())
2023-09-01 13:52:18 +00:00
);
2023-09-12 11:19:55 +00:00
$this->info("Email sent to $this->email successfully. 📧");
2023-09-01 13:52:18 +00:00
}
}