Add virtual event sessions with Meet sync and platform-billed messaging.
Deploy Ladill Events / deploy (push) Successful in 41s
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>
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
<?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(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user