type !== QrCode::TYPE_EVENT) { return $event; } $content = $event->content(); $format = (string) ($content['format'] ?? 'in_person'); if (! in_array($format, ['virtual', 'hybrid'], true)) { $this->cancelRemovedSessions($event, $owner, []); return $event; } if ((string) config('meet.key', '') === '') { return $event; } $sessions = (array) ($content['virtual_sessions'] ?? []); $client = MeetClient::for($owner->public_id); $synced = []; $activeIds = []; foreach ($sessions as $session) { if (! is_array($session)) { continue; } $sessionId = trim((string) ($session['id'] ?? '')); if ($sessionId === '') { $sessionId = 'vs-'.Str::lower(Str::random(12)); } $activeIds[] = $sessionId; $title = trim((string) ($session['title'] ?? '')); if ($title === '') { $synced[] = array_merge($session, ['id' => $sessionId]); continue; } $roomType = in_array($session['meet_room_type'] ?? '', ['town_hall', 'webinar'], true) ? (string) $session['meet_room_type'] : 'town_hall'; $scheduledAt = $session['scheduled_at'] ?? $content['starts_at'] ?? null; try { $result = $client->upsertRoom([ 'title' => $title, 'description' => trim((string) ($content['description'] ?? '')) ?: null, 'type' => $roomType, 'scheduled_at' => $scheduledAt, 'duration_minutes' => max(15, (int) ($session['duration_minutes'] ?? 60)), 'timezone' => config('app.timezone', 'UTC'), 'source' => [ 'app' => 'events', 'entity_type' => 'virtual_session', 'entity_id' => $sessionId, 'event_id' => (string) $event->id, ], ]); } catch (\Throwable $e) { Log::warning('Events Meet sync failed', [ 'event_id' => $event->id, 'session_id' => $sessionId, 'error' => $e->getMessage(), ]); $synced[] = array_merge($session, ['id' => $sessionId]); continue; } $room = (array) ($result['room'] ?? []); $synced[] = array_merge($session, [ 'id' => $sessionId, 'meet_room_uuid' => $room['uuid'] ?? $session['meet_room_uuid'] ?? null, 'join_url' => $result['join_url'] ?? $session['join_url'] ?? null, ]); } $this->cancelRemovedSessions($event, $owner, $activeIds); $payload = (array) ($event->payload ?? []); $payload['content'] = array_merge($content, ['virtual_sessions' => array_values($synced)]); $event->payload = $payload; $event->save(); return $event->fresh(); } /** @param list $keepIds */ private function cancelRemovedSessions(QrCode $event, User $owner, array $keepIds): void { if ((string) config('meet.key', '') === '') { return; } $previous = (array) ($event->content()['virtual_sessions'] ?? []); $client = MeetClient::for($owner->public_id); foreach ($previous as $session) { if (! is_array($session)) { continue; } $sessionId = (string) ($session['id'] ?? ''); $roomUuid = (string) ($session['meet_room_uuid'] ?? ''); if ($sessionId === '' || in_array($sessionId, $keepIds, true) || $roomUuid === '') { continue; } try { $client->cancelRoom($roomUuid); } catch (\Throwable $e) { Log::warning('Events Meet cancel failed', [ 'event_id' => $event->id, 'session_id' => $sessionId, 'error' => $e->getMessage(), ]); } } } }