318 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			318 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
namespace App\Console\Commands;
 | 
						|
 | 
						|
use App\Jobs\SendConfirmationForWaitlistJob;
 | 
						|
use App\Models\Application;
 | 
						|
use App\Models\ApplicationPreview;
 | 
						|
use App\Models\ScheduledDatabaseBackup;
 | 
						|
use App\Models\Server;
 | 
						|
use App\Models\StandalonePostgresql;
 | 
						|
use App\Models\Team;
 | 
						|
use App\Models\Waitlist;
 | 
						|
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;
 | 
						|
use App\Notifications\Test;
 | 
						|
use Exception;
 | 
						|
use Illuminate\Console\Command;
 | 
						|
use Illuminate\Mail\Message;
 | 
						|
use Illuminate\Notifications\Messages\MailMessage;
 | 
						|
use Mail;
 | 
						|
 | 
						|
use function Laravel\Prompts\confirm;
 | 
						|
use function Laravel\Prompts\select;
 | 
						|
use function Laravel\Prompts\text;
 | 
						|
 | 
						|
class Emails extends Command
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * The name and signature of the console command.
 | 
						|
     *
 | 
						|
     * @var string
 | 
						|
     */
 | 
						|
    protected $signature = 'emails';
 | 
						|
 | 
						|
    /**
 | 
						|
     * The console command description.
 | 
						|
     *
 | 
						|
     * @var string
 | 
						|
     */
 | 
						|
    protected $description = 'Send out test / prod emails';
 | 
						|
 | 
						|
    /**
 | 
						|
     * Execute the console command.
 | 
						|
     */
 | 
						|
    private ?MailMessage $mail = null;
 | 
						|
 | 
						|
    private ?string $email = null;
 | 
						|
 | 
						|
    public function handle()
 | 
						|
    {
 | 
						|
        $type = select(
 | 
						|
            'Which Email should be sent?',
 | 
						|
            options: [
 | 
						|
                'updates' => 'Send Update Email to all users',
 | 
						|
                'emails-test' => 'Test',
 | 
						|
                'database-backup-statuses-daily' => 'Database - Backup Statuses (Daily)',
 | 
						|
                'application-deployment-success-daily' => 'Application - Deployment Success (Daily)',
 | 
						|
                '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',
 | 
						|
                // 'invitation-link' => 'Invitation Link',
 | 
						|
                'waitlist-invitation-link' => 'Waitlist Invitation Link',
 | 
						|
                'waitlist-confirmation' => 'Waitlist Confirmation',
 | 
						|
                'realusers-before-trial' => 'REAL - Registered Users Before Trial without Subscription',
 | 
						|
                'realusers-server-lost-connection' => 'REAL - Server Lost Connection',
 | 
						|
            ],
 | 
						|
        );
 | 
						|
        $emailsGathered = ['realusers-before-trial', 'realusers-server-lost-connection'];
 | 
						|
        if (isDev()) {
 | 
						|
            $this->email = 'test@example.com';
 | 
						|
        } else {
 | 
						|
            if (! in_array($type, $emailsGathered)) {
 | 
						|
                $this->email = text('Email Address to send to:');
 | 
						|
            }
 | 
						|
        }
 | 
						|
        set_transanctional_email_settings();
 | 
						|
 | 
						|
        $this->mail = new MailMessage();
 | 
						|
        $this->mail->subject('Test Email');
 | 
						|
        switch ($type) {
 | 
						|
            case 'updates':
 | 
						|
                $teams = Team::all();
 | 
						|
                if (! $teams || $teams->isEmpty()) {
 | 
						|
                    echo 'No teams found.'.PHP_EOL;
 | 
						|
 | 
						|
                    return;
 | 
						|
                }
 | 
						|
                $emails = [];
 | 
						|
                foreach ($teams as $team) {
 | 
						|
                    foreach ($team->members as $member) {
 | 
						|
                        if ($member->email && $member->marketing_emails) {
 | 
						|
                            $emails[] = $member->email;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                $emails = array_unique($emails);
 | 
						|
                $this->info('Sending to '.count($emails).' emails.');
 | 
						|
                foreach ($emails as $email) {
 | 
						|
                    $this->info($email);
 | 
						|
                }
 | 
						|
                $confirmed = confirm('Are you sure?');
 | 
						|
                if ($confirmed) {
 | 
						|
                    foreach ($emails as $email) {
 | 
						|
                        $this->mail = new MailMessage();
 | 
						|
                        $this->mail->subject('One-click Services, Docker Compose support');
 | 
						|
                        $unsubscribeUrl = route('unsubscribe.marketing.emails', [
 | 
						|
                            'token' => encrypt($email),
 | 
						|
                        ]);
 | 
						|
                        $this->mail->view('emails.updates', ['unsubscribeUrl' => $unsubscribeUrl]);
 | 
						|
                        $this->sendEmail($email);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                break;
 | 
						|
            case 'emails-test':
 | 
						|
                $this->mail = (new Test())->toMail();
 | 
						|
                $this->sendEmail();
 | 
						|
                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;
 | 
						|
            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();
 | 
						|
                if (! $preview) {
 | 
						|
                    $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();
 | 
						|
                if (! $backup) {
 | 
						|
                    $backup = ScheduledDatabaseBackup::create([
 | 
						|
                        'enabled' => true,
 | 
						|
                        'frequency' => 'daily',
 | 
						|
                        'save_s3' => false,
 | 
						|
                        'database_id' => $db->id,
 | 
						|
                        'database_type' => $db->getMorphClass(),
 | 
						|
                        'team_id' => 0,
 | 
						|
                    ]);
 | 
						|
                }
 | 
						|
                $output = 'Because of an error, the backup of the database '.$db->name.' failed.';
 | 
						|
                $this->mail = (new BackupFailed($backup, $db, $output))->toMail();
 | 
						|
                $this->sendEmail();
 | 
						|
                break;
 | 
						|
            case 'backup-success':
 | 
						|
                $backup = ScheduledDatabaseBackup::all()->first();
 | 
						|
                $db = StandalonePostgresql::all()->first();
 | 
						|
                if (! $backup) {
 | 
						|
                    $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;
 | 
						|
                // 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;
 | 
						|
            case 'waitlist-invitation-link':
 | 
						|
                $this->mail = new MailMessage();
 | 
						|
                $this->mail->view('emails.waitlist-invitation', [
 | 
						|
                    'loginLink' => 'https://coolify.io',
 | 
						|
                ]);
 | 
						|
                $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');
 | 
						|
                }
 | 
						|
 | 
						|
                break;
 | 
						|
            case 'realusers-before-trial':
 | 
						|
                $this->mail = new MailMessage();
 | 
						|
                $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();
 | 
						|
                if (! $teams || $teams->isEmpty()) {
 | 
						|
                    echo 'No teams found.'.PHP_EOL;
 | 
						|
 | 
						|
                    return;
 | 
						|
                }
 | 
						|
                $emails = [];
 | 
						|
                foreach ($teams as $team) {
 | 
						|
                    foreach ($team->members as $member) {
 | 
						|
                        if ($member->email) {
 | 
						|
                            $emails[] = $member->email;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                $emails = array_unique($emails);
 | 
						|
                $this->info('Sending to '.count($emails).' emails.');
 | 
						|
                foreach ($emails as $email) {
 | 
						|
                    $this->info($email);
 | 
						|
                }
 | 
						|
                $confirmed = confirm('Are you sure?');
 | 
						|
                if ($confirmed) {
 | 
						|
                    foreach ($emails as $email) {
 | 
						|
                        $this->sendEmail($email);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                break;
 | 
						|
            case 'realusers-server-lost-connection':
 | 
						|
                $serverId = text('Server Id');
 | 
						|
                $server = Server::find($serverId);
 | 
						|
                if (! $server) {
 | 
						|
                    throw new Exception('Server not found');
 | 
						|
                }
 | 
						|
                $admins = [];
 | 
						|
                $members = $server->team->members;
 | 
						|
                foreach ($members as $member) {
 | 
						|
                    if ($member->isAdmin()) {
 | 
						|
                        $admins[] = $member->email;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                $this->info('Sending to '.count($admins).' admins.');
 | 
						|
                foreach ($admins as $admin) {
 | 
						|
                    $this->info($admin);
 | 
						|
                }
 | 
						|
                $this->mail = new MailMessage();
 | 
						|
                $this->mail->view('emails.server-lost-connection', [
 | 
						|
                    'name' => $server->name,
 | 
						|
                ]);
 | 
						|
                $this->mail->subject('Action required: Server '.$server->name.' lost connection.');
 | 
						|
                foreach ($admins as $email) {
 | 
						|
                    $this->sendEmail($email);
 | 
						|
                }
 | 
						|
                break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    private function sendEmail(?string $email = null)
 | 
						|
    {
 | 
						|
        if ($email) {
 | 
						|
            $this->email = $email;
 | 
						|
        }
 | 
						|
        Mail::send(
 | 
						|
            [],
 | 
						|
            [],
 | 
						|
            fn (Message $message) => $message
 | 
						|
                ->to($this->email)
 | 
						|
                ->subject($this->mail->subject)
 | 
						|
                ->html((string) $this->mail->render())
 | 
						|
        );
 | 
						|
        $this->info("Email sent to $this->email successfully. 📧");
 | 
						|
    }
 | 
						|
}
 |