fedi_slurp/add_to_fedilist.php

150 lines
4.9 KiB
PHP
Raw Normal View History

2025-05-21 00:44:19 +00:00
<?php
2025-05-21 03:05:53 +00:00
2025-05-21 00:44:19 +00:00
// === Example use ===
#addVideoToFediList('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
2025-05-21 03:05:53 +00:00
require_once('utils.php');
2025-05-21 00:44:19 +00:00
function isYouTubeLink($url) {
return preg_match('#^(https?://)?(www\.)?(youtube\.com/watch\?v=|youtu\.be/)[a-zA-Z0-9_-]{11}#', $url);
}
function addVideoToFediList($videoUrl) {
2025-05-21 02:24:15 +00:00
$credentialsDir = __DIR__ . '/_credentials';
$tokenPath = "$credentialsDir/token.json";
$playlistId = @file_get_contents("$credentialsDir/fedilist_id.txt");
2025-05-21 00:44:19 +00:00
if (!$playlistId) {
echo "‼️ Error: FediList ID not found. Make sure fedilist_id.txt exists.\n";
return false;
}
2025-05-21 02:24:15 +00:00
// === Load client credentials ===
$secrets = json_decode(file_get_contents("$credentialsDir/client_secret.json"), true);
$client = $secrets['installed'] ?? $secrets['web'] ?? null;
if (!$client || !isset($client['client_id'], $client['client_secret'])) {
die("Error: Invalid client_secret.json format.\n");
}
$clientId = $client['client_id'];
$clientSecret = $client['client_secret'];
// === Load token ===
$token = @json_decode(file_get_contents($tokenPath), true);
2025-05-21 00:44:19 +00:00
if (!$token || !isset($token['access_token'])) {
echo "‼️ Error: token.json missing or invalid. Authenticate first.\n";
return false;
}
2025-05-21 02:36:26 +00:00
//print_r($token);
2025-05-21 00:44:19 +00:00
2025-05-21 02:24:15 +00:00
// === Refresh token if expired ===
2025-05-21 03:05:53 +00:00
// Don't let it expire, refresh if we have less than 15 minutes left
// Google Tokens usually last 60 min, so more ore less around 45min we get a new one
$refreshSecondMargin = 15*60;
2025-05-21 02:36:26 +00:00
if (isset($token['expires_at'])) {
$secondsLeft = $token['expires_at'] - time();
2025-05-21 03:05:53 +00:00
if ($secondsLeft > $refreshSecondMargin) {
2025-05-21 02:36:26 +00:00
$minutes = floor($secondsLeft / 60);
$seconds = $secondsLeft % 60;
echo "⏳ Token expires in $minutes minutes and $seconds seconds.\n";
} else {
2025-05-21 03:05:53 +00:00
echo "🔄 Access token expired or will expire in less than $refreshSecondMargin seconds. (Seconds Left: $secondsLeft). Refreshing...\n";
2025-05-21 02:24:15 +00:00
$refreshResponse = curlPost('https://oauth2.googleapis.com/token', [
'client_id' => $clientId,
'client_secret' => $clientSecret,
'refresh_token' => $token['refresh_token'],
'grant_type' => 'refresh_token'
]);
if (isset($refreshResponse['access_token'])) {
$token['access_token'] = $refreshResponse['access_token'];
$token['expires_in'] = $refreshResponse['expires_in'];
$token['expires_at'] = time() + $refreshResponse['expires_in'];
file_put_contents($tokenPath, json_encode($token));
echo "✅ Token refreshed.\n";
} else {
echo "‼️ Failed to refresh token: " . ($refreshResponse['error'] ?? 'unknown') . "\n";
return false;
}
}
2025-05-21 02:36:26 +00:00
}
2025-05-21 02:24:15 +00:00
// === Extract video ID ===
2025-05-21 00:44:19 +00:00
if (!preg_match('/(?:v=|\/)([a-zA-Z0-9_-]{11})/', $videoUrl, $matches)) {
echo "⁉️ Invalid YouTube URL: $videoUrl\n";
return false;
2025-05-21 02:24:15 +00:00
}
2025-05-21 00:44:19 +00:00
$videoId = $matches[1];
// === Step 1: Check if video is already in playlist ===
$checkUrl = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId={$playlistId}&maxResults=50";
$found = false;
do {
$ch = curl_init($checkUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $token['access_token'],
'User-Agent: curl/7.64.1'
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
foreach ($data['items'] ?? [] as $item) {
if (($item['snippet']['resourceId']['videoId'] ?? '') === $videoId) {
echo " Video already in FediList: $videoId\n";
return false;
}
}
$checkUrl = $data['nextPageToken'] ?? false
? $checkUrl . '&pageToken=' . $data['nextPageToken']
: false;
} while ($checkUrl);
// === Step 2: Add the video ===
$postData = [
'snippet' => [
'playlistId' => $playlistId,
'resourceId' => [
'kind' => 'youtube#video',
'videoId' => $videoId
]
]
];
$ch = curl_init('https://www.googleapis.com/youtube/v3/playlistItems?part=snippet');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $token['access_token'],
'Content-Type: application/json',
'User-Agent: curl/7.64.1'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData));
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
if (isset($result['id'])) {
echo "✅ Added video to FediList: $videoId\n";
return true;
} else {
echo "‼️ Failed to add video:\n$response\n";
return false;
}
}
?>