Deploy Ladill Events / deploy (push) Successful in 41s
Events can define hybrid/virtual sessions synced to Meet rooms; SMS and email use wallet-billed platform APIs instead of Termii and Laravel mail. Co-authored-by: Cursor <cursoragent@cursor.com>
138 lines
4.5 KiB
PHP
138 lines
4.5 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Meet;
|
|
|
|
use App\Models\QrCode;
|
|
use App\Models\User;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Str;
|
|
|
|
class EventMeetSyncService
|
|
{
|
|
public function sync(QrCode $event, User $owner): QrCode
|
|
{
|
|
if ($event->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<string> $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(),
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
}
|