<?php
 namespace App\Services\Tracking\Providers; use App\Services\Tracking\Contracts\TrackingProvider; use App\Services\Tracking\TrackingEvent; use Illuminate\Support\Facades\Log; use Segment\Client; class SegmentProvider implements TrackingProvider { public function __construct(private readonly ?Client $client = null) { } public function isEnabled(): bool { return !empty(setting('segment_write_key')); } public function send(TrackingEvent $event): void { $client = $this->resolveClient(); $userId = $event->user?->emailSha256; $anonymousId = $userId ? null : 'anon-' . ($event->eventId ?? bin2hex(random_bytes(6))); $properties = array_filter([ 'value' => $event->params['value'] ?? null, 'currency' => $event->params['currency'] ?? null, 'transaction_id' => $event->params['transaction_id'] ?? null, ], fn ($v) => $v !== null); $message = ['event' => $event->name]; if ($userId !== null) { $message['userId'] = $userId; } else { $message['anonymousId'] = $anonymousId; } $message['messageId'] = $event->eventId; $message['timestamp'] = $event->timestamp; if ($properties) { $message['properties'] = $properties; } if ($event->sourceUrl) { $message['context'] = ['page' => ['url' => $event->sourceUrl]]; } try { $client->track($message); $client->flush(); } catch (\Throwable $e) { Log::channel('tracking')->error('Segment send failed', [ 'event' => $event->name, 'event_id' => $event->eventId, 'error' => $e->getMessage(), ]); throw new \RuntimeException('Segment SDK dispatch failed: ' . $e->getMessage(), previous: $e); } Log::channel('tracking')->info('Segment sent', [ 'event' => $event->name, 'event_id' => $event->eventId, ]); } private function resolveClient(): Client { if ($this->client !== null) { return $this->client; } return new Client(setting('segment_write_key')); } } 