for($notifiable, $this->event) ? ['database', WhatsAppChannel::class] : []; } /** * Sends the ticket PDF as a WhatsApp document, falling back to a template * when the 24-hour service window has closed, and finally to plain text. */ public function toWhatsApp($notifiable) { try { PublicUrl::ensureConfigured(); $link = WhatsAppLink::issue($notifiable, 'ticket', ['event_id' => $this->event->id], minutes: 60 * 24 * 7); $ticketUrl = $link->url(); } catch (\DomainException $e) { report($e); Log::warning('Ticket notification skipped because APP_URL is not public HTTPS.', [ 'event_id' => $this->event->id, 'user_id' => $notifiable->id, ]); return null; } $parameters = [ $notifiable->name ?: 'there', $this->event->title, (string) data_get($this->event->timings, 'event_start_and_end.start', ''), $ticketUrl, ]; $mediaId = $this->uploadTicket($notifiable); if (! $mediaId) { // No PDF available — still confirm, with a link to the ticket. return ['template' => 'ticket_confirmation', 'parameters' => $parameters]; } $filename = 'ticket-'.$this->event->title.'.pdf'; $service = app(WhatsAppService::class); try { $response = $service->sendDocument( $notifiable->phone, $mediaId, $filename, "🎟 You're confirmed for {$this->event->title}. Your ticket is attached — show the QR code at check-in." ); } catch (WhatsAppApiException $exception) { if (! $service->failedOnWindow($exception)) { throw $exception; } $response = $exception; } if ($service->failedOnWindow($response)) { $service->sendDocumentTemplate( $notifiable->phone, 'ticket_confirmation_pdf', $mediaId, $filename, $parameters ); } // Already delivered directly; nothing further for the channel to send. return null; } protected function uploadTicket($notifiable): ?string { try { $enrollment = app(FindEligibleEnrollment::class) ->for($notifiable, $this->event); if (! $enrollment) { return null; } $tickets = new GenerateTicketPdf; $path = $tickets->file( $this->event, $notifiable, $enrollment, data_get($enrollment->payment?->notes, 'pricing.title', 'Registration') ); return app(WhatsAppService::class)->uploadMedia($path); } catch (\Throwable $e) { report($e); // a missing PDF must not block the confirmation Log::warning('Ticket PDF unavailable for WhatsApp delivery.', [ 'event_id' => $this->event->id, 'user_id' => $notifiable->id, ]); return null; } } public function toArray($notifiable) { return [ 'data' => [ 'meeting_title' => 'Registration confirmed', 'message' => 'Registration confirmed for '.$this->event->title.'.', 'event_id' => $this->event->id, 'user_id' => $notifiable->id, ], ]; } }