$clientId, 'redirect_uri' => $redirect, 'response_type' => 'code', 'scope' => 'https://www.googleapis.com/auth/calendar.events', 'access_type' => 'offline', 'prompt' => 'consent', ]); return 'https://accounts.google.com/o/oauth2/v2/auth?'.$params; } /** * @return array|null */ public function exchangeCode(string $code): ?array { $response = Http::asForm()->post('https://oauth2.googleapis.com/token', [ 'code' => $code, 'client_id' => config('meet.calendar.google.client_id'), 'client_secret' => config('meet.calendar.google.client_secret'), 'redirect_uri' => config('meet.calendar.google.redirect'), 'grant_type' => 'authorization_code', ]); return $response->successful() ? $response->json() : null; } public function createEvent(CalendarConnection $connection, Room $room, User $host): ?string { if (! $connection->access_token) { return null; } $response = Http::withToken($connection->access_token)->post( 'https://www.googleapis.com/calendar/v3/calendars/'.urlencode($connection->calendar_id ?? 'primary').'/events', $this->eventPayload($room, $host), ); return $response->successful() ? $response->json('id') : null; } public function updateEvent(CalendarConnection $connection, Room $room, User $host): bool { if (! $connection->access_token || ! $room->calendar_event_id) { return false; } $calendar = urlencode($connection->calendar_id ?? 'primary'); $event = urlencode($room->calendar_event_id); return Http::withToken($connection->access_token)->put( "https://www.googleapis.com/calendar/v3/calendars/{$calendar}/events/{$event}", $this->eventPayload($room, $host), )->successful(); } public function deleteEvent(CalendarConnection $connection, Room $room): bool { if (! $connection->access_token || ! $room->calendar_event_id) { return false; } $calendar = urlencode($connection->calendar_id ?? 'primary'); $event = urlencode($room->calendar_event_id); return Http::withToken($connection->access_token)->delete( "https://www.googleapis.com/calendar/v3/calendars/{$calendar}/events/{$event}", )->successful(); } /** @return array */ protected function eventPayload(Room $room, User $host): array { $start = ($room->scheduled_at ?? now())->toIso8601String(); $end = ($room->scheduled_at ?? now())->addMinutes($room->duration_minutes ?? 60)->toIso8601String(); return [ 'summary' => $room->title, 'description' => trim(($room->description ?? '')."\n\nJoin: ".$room->joinUrl()), 'location' => $room->joinUrl(), 'start' => ['dateTime' => $start, 'timeZone' => $room->timezone], 'end' => ['dateTime' => $end, 'timeZone' => $room->timezone], 'organizer' => ['email' => $host->email, 'displayName' => $host->name], ]; } }