feat(sync): sélecteur de chaîne YouTube (multi-chaînes/marque) via PageId
This commit is contained in:
@@ -82,6 +82,7 @@ import {
|
||||
getOAuthConnection,
|
||||
updateOAuthTokens,
|
||||
deleteOAuthConnection,
|
||||
setOAuthChannel,
|
||||
upsertChannelRow,
|
||||
insertDownloadJob,
|
||||
getDownloadJob,
|
||||
@@ -107,6 +108,7 @@ import {
|
||||
fetchGoogleLiked, fetchTwitchProfile, fetchTwitchFollows, hasGoogleWriteScope,
|
||||
fetchGoogleWatchLater, pushGoogleWatchLater, fetchInnerTubeHistory,
|
||||
fetchInnerTubeWatchLaterViaLib, pushInnerTubeWatchLater, fetchGoogleWatchLaterId,
|
||||
fetchAccountChannels,
|
||||
} from './oauth.mjs';
|
||||
import { getSearchMode, getYtDlpBin, hasCookiesFile, metricsSnapshot } from './providers/youtube-common.mjs';
|
||||
import { ytScrapeCacheStats } from './providers/youtube.mjs';
|
||||
@@ -559,6 +561,39 @@ r.delete('/oauth/:provider', authMiddlewareCookieAware, oauthLimiter, (req, res)
|
||||
}
|
||||
});
|
||||
|
||||
// -------------------- Google : choix de la chaîne (multi-chaînes / marque) --------------------
|
||||
// La chaîne par défaut peut être une coquille vide (pas d'historique ni WL)
|
||||
// alors que l'activité est sur une chaîne secondaire : l'utilisateur la
|
||||
// choisit ici, et les appels InnerTube la ciblent via X-Goog-PageId.
|
||||
|
||||
r.get('/oauth/google/yt-channels', authMiddlewareCookieAware, oauthLimiter, async (req, res) => {
|
||||
try {
|
||||
const conn = await freshOAuthToken(req.user.id, 'google');
|
||||
const { channels } = await fetchAccountChannels(conn);
|
||||
try {
|
||||
console.log(`[oauth] yt-channels user=${req.user?.id} count=${channels.length}`);
|
||||
} catch {}
|
||||
return res.json({ channels, selected: { channelId: conn.ytChannelId || null, pageId: conn.ytPageId || null } });
|
||||
} catch (error) {
|
||||
const out = { error: error?.message || 'yt_channels_failed' };
|
||||
if (error?.detail) out.detail = error.detail;
|
||||
if (error?.hint) out.hint = error.hint;
|
||||
return res.status(error?.status || 502).json(out);
|
||||
}
|
||||
});
|
||||
|
||||
r.put('/oauth/google/yt-channel', authMiddlewareCookieAware, oauthLimiter, (req, res) => {
|
||||
try {
|
||||
const channelId = String(req.body?.channelId || '').trim().slice(0, 64) || null;
|
||||
const pageId = String(req.body?.pageId || '').trim().slice(0, 64) || null;
|
||||
const conn = setOAuthChannel(req.user.id, 'google', { channelId, pageId });
|
||||
if (!conn) return res.status(404).json({ error: 'oauth_not_connected' });
|
||||
return res.json({ selected: { channelId: conn.ytChannelId || null, pageId: conn.ytPageId || null } });
|
||||
} catch {
|
||||
return res.status(500).json({ error: 'yt_channel_save_failed' });
|
||||
}
|
||||
});
|
||||
|
||||
// Aperçu distant (sans rien importer) : abonnements + favoris.
|
||||
r.get('/oauth/:provider/preview', authMiddlewareCookieAware, oauthLimiter, async (req, res) => {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user