fix(sync): historique/WL via youtubei.js authentifié + erreurs détaillées

This commit is contained in:
2026-09-27 07:36:16 -04:00
parent 186294f518
commit 8edf9de0c6
4 changed files with 108 additions and 35 deletions
+5 -4
View File
@@ -106,7 +106,7 @@ import {
refreshAccessToken, redirectUriFor, fetchGoogleProfile, fetchGoogleSubscriptions,
fetchGoogleLiked, fetchTwitchProfile, fetchTwitchFollows, hasGoogleWriteScope,
fetchGoogleWatchLater, pushGoogleWatchLater, fetchInnerTubeHistory,
fetchInnerTubeWatchLater, pushInnerTubeWatchLater, fetchGoogleWatchLaterId,
fetchInnerTubeWatchLaterViaLib, pushInnerTubeWatchLater, fetchGoogleWatchLaterId,
} from './oauth.mjs';
import { getSearchMode, getYtDlpBin, hasCookiesFile, metricsSnapshot } from './providers/youtube-common.mjs';
import { ytScrapeCacheStats } from './providers/youtube.mjs';
@@ -667,12 +667,12 @@ r.get('/oauth/google/watchlater', authMiddlewareCookieAware, oauthLimiter, async
return res.json({ items, count: items.length, writeGranted, via: 'api' });
} catch (apiError) {
// L'API Data ne renvoie pas d'ID WL pour certains comptes : repli
// InnerTube (playlist logique "WL", aucun ID requis).
// youtubei.js authentifié (getPlaylist WL, aucun ID requis).
if (apiError?.message !== 'watchlater_not_found' && apiError?.message !== 'youtube_no_channel') throw apiError;
try {
console.warn(`[oauth] WL Data API indisponible (${apiError.message}), repli InnerTube`);
console.warn(`[oauth] WL Data API indisponible (${apiError.message}), repli youtubei.js`);
} catch {}
const { items } = await fetchInnerTubeWatchLater(conn.accessToken, innertubeApiKey(), 100);
const { items } = await fetchInnerTubeWatchLaterViaLib(conn, 100);
return res.json({
items, count: items.length, writeGranted, via: 'innertube',
note: 'Liste lue via InnerTube (l’API YouTube ne l’expose pas pour ce compte).',
@@ -682,6 +682,7 @@ r.get('/oauth/google/watchlater', authMiddlewareCookieAware, oauthLimiter, async
const out = { error: error?.message || 'watchlater_fetch_failed' };
if (error?.hint) out.hint = error.hint;
if (error?.ytReason) out.ytReason = error.ytReason;
if (error?.detail) out.detail = error.detail;
if (!out.hint && String(error?.ytReason || '').toLowerCase().includes('insufficientpermissions')) {
out.hint = 'Scope manquant : déconnectez puis reconnectez Google pour autoriser l’accès complet YouTube.';
}