fix
This commit is contained in:
+1
-1
@@ -11,7 +11,7 @@ npm-debug.*
|
|||||||
web-build/
|
web-build/
|
||||||
ios/
|
ios/
|
||||||
android/
|
android/
|
||||||
|
youtube.md
|
||||||
# macOS
|
# macOS
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
YOUTUBE_CLIENT_ID=your-youtube-client-id
|
|
||||||
YOUTUBE_CLIENT_SECRET=your-youtube-client-secret
|
|
||||||
YOUTUBE_REFRESH_TOKEN=your-youtube-refresh-token
|
|
||||||
# YOUTUBE_REDIRECT_URI=http://localhost:8081
|
|
||||||
# YOUTUBE_PRIVACY_STATUS=unlisted
|
|
||||||
# YOUTUBE_CATEGORY_ID=10
|
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
require("dotenv").config();
|
|
||||||
|
|
||||||
const admin = require("firebase-admin");
|
const admin = require("firebase-admin");
|
||||||
|
|
||||||
// Use default credentials/environment provided by Cloud Functions.
|
// Use default credentials/environment provided by Cloud Functions.
|
||||||
|
|||||||
Generated
-12
@@ -11,7 +11,6 @@
|
|||||||
"@google-cloud/firestore": "^7.11.6",
|
"@google-cloud/firestore": "^7.11.6",
|
||||||
"@google-cloud/storage": "^7.17.1",
|
"@google-cloud/storage": "^7.17.1",
|
||||||
"axios": "^1.11.0",
|
"axios": "^1.11.0",
|
||||||
"dotenv": "^17.2.3",
|
|
||||||
"expo-server-sdk": "^4.0.0",
|
"expo-server-sdk": "^4.0.0",
|
||||||
"ffmpeg-static": "^5.2.0",
|
"ffmpeg-static": "^5.2.0",
|
||||||
"firebase-admin": "^12.6.0",
|
"firebase-admin": "^12.6.0",
|
||||||
@@ -3785,17 +3784,6 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dotenv": {
|
|
||||||
"version": "17.2.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz",
|
|
||||||
"integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://dotenvx.com"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/dotprompt": {
|
"node_modules/dotprompt": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/dotprompt/-/dotprompt-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/dotprompt/-/dotprompt-1.1.2.tgz",
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
"@google-cloud/firestore": "^7.11.6",
|
"@google-cloud/firestore": "^7.11.6",
|
||||||
"@google-cloud/storage": "^7.17.1",
|
"@google-cloud/storage": "^7.17.1",
|
||||||
"axios": "^1.11.0",
|
"axios": "^1.11.0",
|
||||||
"dotenv": "^17.2.3",
|
|
||||||
"expo-server-sdk": "^4.0.0",
|
"expo-server-sdk": "^4.0.0",
|
||||||
"ffmpeg-static": "^5.2.0",
|
"ffmpeg-static": "^5.2.0",
|
||||||
"firebase-admin": "^12.6.0",
|
"firebase-admin": "^12.6.0",
|
||||||
|
|||||||
+58
-15
@@ -1,6 +1,7 @@
|
|||||||
const { onCall, HttpsError } = require("firebase-functions/v2/https");
|
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 logger = require("firebase-functions/logger");
|
||||||
|
const functions = require("firebase-functions");
|
||||||
const admin = require("firebase-admin");
|
const admin = require("firebase-admin");
|
||||||
const axios = require("axios");
|
const axios = require("axios");
|
||||||
const fs = require("node:fs");
|
const fs = require("node:fs");
|
||||||
@@ -9,6 +10,15 @@ const os = require("node:os");
|
|||||||
const path = require("node:path");
|
const path = require("node:path");
|
||||||
const { google } = require("googleapis");
|
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 firestore = admin.firestore();
|
||||||
const projectsRef = firestore.collection("projects");
|
const projectsRef = firestore.collection("projects");
|
||||||
|
|
||||||
@@ -19,22 +29,47 @@ const YOUTUBE_IN_PROGRESS_STATUSES = [
|
|||||||
"QUEUED",
|
"QUEUED",
|
||||||
];
|
];
|
||||||
|
|
||||||
const getEnvYoutubeConfig = () =>
|
// Lecture des secrets (recommandé en v2)
|
||||||
|
const getSecretsYoutubeConfig = () =>
|
||||||
Object.fromEntries(
|
Object.fromEntries(
|
||||||
Object.entries({
|
Object.entries({
|
||||||
client_id: process.env.YOUTUBE_CLIENT_ID,
|
client_id: S_YT_CLIENT_ID.value(),
|
||||||
client_secret: process.env.YOUTUBE_CLIENT_SECRET,
|
client_secret: S_YT_CLIENT_SECRET.value(),
|
||||||
refresh_token: process.env.YOUTUBE_REFRESH_TOKEN,
|
refresh_token: S_YT_REFRESH_TOKEN.value(),
|
||||||
redirect_uri: process.env.YOUTUBE_REDIRECT_URI,
|
redirect_uri: S_YT_REDIRECT_URI.value(),
|
||||||
privacy_status: process.env.YOUTUBE_PRIVACY_STATUS,
|
privacy_status: S_YT_PRIVACY_STATUS.value(),
|
||||||
category_id: process.env.YOUTUBE_CATEGORY_ID,
|
category_id: S_YT_CATEGORY_ID.value(),
|
||||||
}).filter(([, value]) => value !== undefined && 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 ensureYoutubeConfig = () => {
|
||||||
const firebaseConfig = functions.config()?.youtube || {};
|
// Fusionne (par prudence) l’ancienne config et les secrets actuels
|
||||||
const envConfig = getEnvYoutubeConfig();
|
const firebaseConfig = getLegacyYoutubeConfig();
|
||||||
const cfg = { ...firebaseConfig, ...envConfig };
|
const secretConfig = getSecretsYoutubeConfig();
|
||||||
|
const cfg = { ...firebaseConfig, ...secretConfig };
|
||||||
|
|
||||||
const requiredKeys = ["client_id", "client_secret", "refresh_token"];
|
const requiredKeys = ["client_id", "client_secret", "refresh_token"];
|
||||||
const missing = requiredKeys.filter((key) => !cfg[key]);
|
const missing = requiredKeys.filter((key) => !cfg[key]);
|
||||||
if (missing.length) {
|
if (missing.length) {
|
||||||
@@ -48,10 +83,9 @@ const ensureYoutubeConfig = () => {
|
|||||||
clientId: cfg.client_id,
|
clientId: cfg.client_id,
|
||||||
clientSecret: cfg.client_secret,
|
clientSecret: cfg.client_secret,
|
||||||
refreshToken: cfg.refresh_token,
|
refreshToken: cfg.refresh_token,
|
||||||
redirectUri:
|
redirectUri: cfg.redirect_uri,
|
||||||
cfg.redirect_uri || "https://developers.google.com/oauthplayground",
|
defaultPrivacyStatus: cfg.privacy_status,
|
||||||
defaultPrivacyStatus: cfg.privacy_status || "unlisted",
|
defaultCategoryId: cfg.category_id,
|
||||||
defaultCategoryId: cfg.category_id || "10",
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -130,6 +164,15 @@ exports.publishPlaybackToYoutube = onCall(
|
|||||||
"https://musicland-one.vercel.app/",
|
"https://musicland-one.vercel.app/",
|
||||||
"https://musicland-d33f9.firebaseapp.com",
|
"https://musicland-d33f9.firebaseapp.com",
|
||||||
],
|
],
|
||||||
|
// Secrets requis pour l’exé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 }) => {
|
async ({ data = {}, auth }) => {
|
||||||
const uid = auth?.uid;
|
const uid = auth?.uid;
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ const PublishYoutube = () => {
|
|||||||
try {
|
try {
|
||||||
const publishCallable = firebase
|
const publishCallable = firebase
|
||||||
.functions()
|
.functions()
|
||||||
.httpsCallable("publishPlaybackToYoutube");
|
.httpsCallable("youtube-publishPlaybackToYoutube");
|
||||||
await publishCallable({ projectId });
|
await publishCallable({ projectId });
|
||||||
setTooltip?.({
|
setTooltip?.({
|
||||||
type: "success",
|
type: "success",
|
||||||
|
|||||||
-24
@@ -1,24 +0,0 @@
|
|||||||
https://accounts.google.com/o/oauth2/v2/auth
|
|
||||||
?client_id=305598753437-21ivo6din58aud9dph9bcob06fb52r5n.apps.googleusercontent.com
|
|
||||||
&redirect_uri=http://localhost:8081
|
|
||||||
&response_type=code
|
|
||||||
&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.upload
|
|
||||||
&access_type=offline
|
|
||||||
&prompt=consent
|
|
||||||
|
|
||||||
http://localhost:8081/?code=4/0Ab32j90LMDeJDShWSk1OkXwgbjrHS-qQpyYTlXhH9q3nlV0EJa6cTL-7nI9yOKHoz6rgRA&scope=https://www.googleapis.com/auth/youtube.upload
|
|
||||||
|
|
||||||
curl -X POST https://oauth2.googleapis.com/token \
|
|
||||||
-d client_id=305598753437-21ivo6din58aud9dph9bcob06fb52r5n.apps.googleusercontent.com \
|
|
||||||
-d client_secret=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 \
|
|
||||||
-d code=4/0Ab32j90LMDeJDShWSk1OkXwgbjrHS-qQpyYTlXhH9q3nlV0EJa6cTL-7nI9yOKHoz6rgRA \
|
|
||||||
-d grant_type=authorization_code \
|
|
||||||
-d redirect_uri=http://localhost:8081
|
|
||||||
|
|
||||||
{
|
|
||||||
"access_token": "ya29.a0ATi6K2uR4DhnmTDl0EN2tvDogwwEwl8SDJLpUzvnZ8LGgOYjgmhqg7MoMM0_iTJR_NBEDPe2LlJDqCFFnIi9s3qRv_zfw_NeTnN-LwUmAyVJkdqSP6GvzQCuZkE6OBuTvaU5b2obk5rHvDOkWXxAb7xjbVTzIBIg8O5VVhJ-VB8VEbTVsSq9bc0ljkbcyBEzm4JdQRwaCgYKAcgSAQ8SFQHGX2MiR1Owf2aiiEBUsU-LDUDgWg0206",
|
|
||||||
"expires_in": 3599,
|
|
||||||
"refresh_token": "1//03sy-LDVmCMcFCgYIARAAGAMSNwF-L9IrHwwdBBZvg3Hwun9hxHUx_AsJaa1qeozmtvGtdOXKIRIyKjTp7S_b0igvzM_1A5bLH34",
|
|
||||||
"scope": "https://www.googleapis.com/auth/youtube.upload",
|
|
||||||
"token_type": "Bearer"
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user