#!/usr/bin/env php addConnection([ 'driver' => 'pgsql', 'host' => $databaseUrl['host'], 'port' => $databaseUrl['port'] ?? 5432, 'database' => ltrim($databaseUrl['path'], '/'), 'username' => urldecode($databaseUrl['user'] ?? ''), 'password' => urldecode($databaseUrl['pass'] ?? ''), 'charset' => 'utf8', 'prefix' => '', ]); $capsule->setAsGlobal(); $capsule->bootEloquent(); $application = new Application('Laravel reminder console', '13'); $application->addCommand(new class extends Command { protected function configure(): void { $this ->setName('reminders:send') ->setDescription('Write reminders for bookings that begin in the next 24 hours'); } protected function execute(InputInterface $input, OutputInterface $output): int { $now = Carbon::now(); $bookings = Capsule::table('bookings') ->join('rooms', 'rooms.id', '=', 'bookings.room_id') ->leftJoin('notifications', function ($join): void { $join->on('notifications.booking_id', '=', 'bookings.id') ->where('notifications.kind', '=', '24 hour reminder'); }) ->whereNull('notifications.id') ->where('bookings.starts_at', '>=', $now) ->where('bookings.starts_at', '<', $now->copy()->addDay()) ->select('bookings.*', 'rooms.name as room_name') ->orderBy('bookings.starts_at') ->get(); $smtpHost = trim((string) getenv('SMTP_HOST')); $smtpPort = (int) (getenv('SMTP_PORT') ?: 587); $smtpUsername = trim((string) getenv('SMTP_USERNAME')); $smtpPassword = trim((string) getenv('SMTP_PASSWORD')); $from = trim((string) (getenv('SMTP_FROM') ?: 'bookings@example.test')); $mailer = null; if ($smtpHost !== '') { $credentials = $smtpUsername !== '' ? rawurlencode($smtpUsername).':'.rawurlencode($smtpPassword).'@' : ''; $mailer = new Mailer(Transport::fromDsn("smtp://{$credentials}{$smtpHost}:{$smtpPort}")); } foreach ($bookings as $booking) { $delivery = 'log'; if ($mailer) { $mailer->send( (new Email()) ->from($from) ->to($booking->email) ->subject('Your room booking is tomorrow') ->text("Hello {$booking->name},\n\nYour booking for {$booking->room_name} begins at {$booking->starts_at}.\n") ); $delivery = 'smtp'; } Capsule::table('notifications')->insert([ 'id' => (string) Str::uuid(), 'booking_id' => $booking->id, 'kind' => '24 hour reminder', 'sent_at' => Carbon::now(), 'delivery' => $delivery, 'created_at' => Carbon::now(), 'updated_at' => Carbon::now(), ]); $output->writeln(json_encode([ 'booking' => $booking->id, 'room' => $booking->room_name, 'starts_at' => $booking->starts_at, 'delivery' => $delivery, ], JSON_UNESCAPED_SLASHES)); } $output->writeln("Reminder pass complete. {$bookings->count()} booking(s) handled."); return self::SUCCESS; } }); // Tokay invokes the scheduled entry point directly. Local runs can still name the command. $application->setDefaultCommand('reminders:send'); exit($application->run());