This commit is contained in:
2025-11-04 10:56:30 +01:00
parent a2e0819524
commit c7472d833a
8 changed files with 60 additions and 62 deletions
+58 -15
View File
@@ -1,6 +1,7 @@
const { onCall, HttpsError } = require("firebase-functions/v2/https");
const functions = require("firebase-functions");
const { defineSecret } = require("firebase-functions/params");
const logger = require("firebase-functions/logger");
const functions = require("firebase-functions");
const admin = require("firebase-admin");
const axios = require("axios");
const fs = require("node:fs");
@@ -9,6 +10,15 @@ const os = require("node:os");
const path = require("node:path");
const { google } = require("googleapis");
// ---- Secrets déclarés (gen2 + Secret Manager)
const S_YT_CLIENT_ID = defineSecret("YOUTUBE_CLIENT_ID");
const S_YT_CLIENT_SECRET = defineSecret("YOUTUBE_CLIENT_SECRET");
const S_YT_REFRESH_TOKEN = defineSecret("YOUTUBE_REFRESH_TOKEN");
const S_YT_REDIRECT_URI = defineSecret("YOUTUBE_REDIRECT_URI");
const S_YT_PRIVACY_STATUS = defineSecret("YOUTUBE_PRIVACY_STATUS");
const S_YT_CATEGORY_ID = defineSecret("YOUTUBE_CATEGORY_ID");
// Firestore
const firestore = admin.firestore();
const projectsRef = firestore.collection("projects");
@@ -19,22 +29,47 @@ const YOUTUBE_IN_PROGRESS_STATUSES = [
"QUEUED",
];
const getEnvYoutubeConfig = () =>
// Lecture des secrets (recommandé en v2)
const getSecretsYoutubeConfig = () =>
Object.fromEntries(
Object.entries({
client_id: process.env.YOUTUBE_CLIENT_ID,
client_secret: process.env.YOUTUBE_CLIENT_SECRET,
refresh_token: process.env.YOUTUBE_REFRESH_TOKEN,
redirect_uri: process.env.YOUTUBE_REDIRECT_URI,
privacy_status: process.env.YOUTUBE_PRIVACY_STATUS,
category_id: process.env.YOUTUBE_CATEGORY_ID,
client_id: S_YT_CLIENT_ID.value(),
client_secret: S_YT_CLIENT_SECRET.value(),
refresh_token: S_YT_REFRESH_TOKEN.value(),
redirect_uri: S_YT_REDIRECT_URI.value(),
privacy_status: S_YT_PRIVACY_STATUS.value(),
category_id: S_YT_CATEGORY_ID.value(),
}).filter(([, value]) => value !== undefined && value !== "")
);
// Compat facultative v1 -> renverra {} en v2 (et on log un warn propre)
const getLegacyYoutubeConfig = () => {
if (typeof functions.config !== "function") {
return {};
}
try {
return functions.config()?.youtube || {};
} catch (error) {
if (
typeof error?.message === "string" &&
error.message.includes("functions.config() is no longer available")
) {
logger.warn(
"[publishPlaybackToYoutube] functions.config() indisponible, utilisation des secrets (Secret Manager)"
);
return {};
}
throw error;
}
};
const ensureYoutubeConfig = () => {
const firebaseConfig = functions.config()?.youtube || {};
const envConfig = getEnvYoutubeConfig();
const cfg = { ...firebaseConfig, ...envConfig };
// Fusionne (par prudence) lancienne config et les secrets actuels
const firebaseConfig = getLegacyYoutubeConfig();
const secretConfig = getSecretsYoutubeConfig();
const cfg = { ...firebaseConfig, ...secretConfig };
const requiredKeys = ["client_id", "client_secret", "refresh_token"];
const missing = requiredKeys.filter((key) => !cfg[key]);
if (missing.length) {
@@ -48,10 +83,9 @@ const ensureYoutubeConfig = () => {
clientId: cfg.client_id,
clientSecret: cfg.client_secret,
refreshToken: cfg.refresh_token,
redirectUri:
cfg.redirect_uri || "https://developers.google.com/oauthplayground",
defaultPrivacyStatus: cfg.privacy_status || "unlisted",
defaultCategoryId: cfg.category_id || "10",
redirectUri: cfg.redirect_uri,
defaultPrivacyStatus: cfg.privacy_status,
defaultCategoryId: cfg.category_id,
};
};
@@ -130,6 +164,15 @@ exports.publishPlaybackToYoutube = onCall(
"https://musicland-one.vercel.app/",
"https://musicland-d33f9.firebaseapp.com",
],
// Secrets requis pour lexécution (v2)
secrets: [
S_YT_CLIENT_ID,
S_YT_CLIENT_SECRET,
S_YT_REFRESH_TOKEN,
S_YT_REDIRECT_URI,
S_YT_PRIVACY_STATUS,
S_YT_CATEGORY_ID,
],
},
async ({ data = {}, auth }) => {
const uid = auth?.uid;