#!/usr/bin/php [ 'title' => 'FediList', 'description' => 'A custom playlist for federated videos' ], 'status' => [ 'privacyStatus' => 'private' ] ]; $ch = curl_init('https://www.googleapis.com/youtube/v3/playlists?part=snippet,status'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: Bearer $accessToken", "Content-Type: application/json", "User-Agent: curl/7.64.1" ]); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); $response = curl_exec($ch); if (curl_errno($ch)) { die("cURL error: " . curl_error($ch) . "\n"); } curl_close($ch); $result = json_decode($response, true); $result = json_decode($response, true); if (isset($result['id'])) { echo "FediList created!\nPlaylist ID: " . $result['id'] . "\n"; file_put_contents($path, $result['id']); } else { echo "Failed to create playlist:\n$response\n"; } } // === Step 1: Get device code === $deviceData = curlPost('https://oauth2.googleapis.com/device/code', [ 'client_id' => $clientId, 'scope' => 'https://www.googleapis.com/auth/youtube' ]); if (!isset($deviceData['user_code'])) { die("Failed to get device code.\n"); } echo "\n"; echo "==============================\n"; echo "==== DEVICE AUTHORIZATION ====\n"; echo "==============================\n"; echo "Visit: " . $deviceData['verification_url'] . "\n"; echo "\n"; echo "Enter code: " . $deviceData['user_code'] . "\n\nFinish login process and come back here."; echo "\n\nWaiting..."; // === Step 2: Poll for token === $token = null; $startTime = time(); while (true) { sleep($deviceData['interval']); echo "."; $tokenResponse = curlPost('https://oauth2.googleapis.com/token', [ 'client_id' => $clientId, 'client_secret' => $clientSecret, 'device_code' => $deviceData['device_code'], 'grant_type' => 'urn:ietf:params:oauth:grant-type:device_code' ]); if (isset($tokenResponse['access_token'])) { $tokenResponse['expires_at'] = time() + $tokenResponse['expires_in']; $path = __DIR__ . '/_credentials/token.json'; file_put_contents($path, json_encode($tokenResponse)); echo "\nāœ… Token saved as $path.\n"; break; } if (isset($tokenResponse['error']) && $tokenResponse['error'] !== 'authorization_pending') { die("\nAuth error: " . $tokenResponse['error'] . "\n"); } if (time() - $startTime > $deviceData['expires_in']) { die("\nAuthorization timed out.\n"); } } // === Step 3: Create FediList Playlist === createPlaylist($tokenResponse['access_token']); ?>