fix function and music generation
This commit is contained in:
@@ -1,25 +0,0 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
es6: true,
|
||||
node: true,
|
||||
},
|
||||
parserOptions: {
|
||||
ecmaVersion: 2018,
|
||||
},
|
||||
extends: ["eslint:recommended", "google"],
|
||||
rules: {
|
||||
"no-restricted-globals": ["error", "name", "length"],
|
||||
"prefer-arrow-callback": "error",
|
||||
quotes: ["error", "double", { allowTemplateLiterals: true }],
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ["**/*.spec.*"],
|
||||
env: {
|
||||
mocha: true,
|
||||
},
|
||||
rules: {},
|
||||
},
|
||||
],
|
||||
globals: {},
|
||||
};
|
||||
@@ -0,0 +1,69 @@
|
||||
# Dependencies
|
||||
node_modules/
|
||||
|
||||
# Logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
logs/
|
||||
*.log
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage/
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
|
||||
# Firebase
|
||||
.firebase/
|
||||
|
||||
# Service account key
|
||||
serviceAccountKey.json
|
||||
|
||||
# API keys
|
||||
config/keys.js
|
||||
|
||||
# Build files
|
||||
dist/
|
||||
build/
|
||||
|
||||
# IDE files
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# OS generated files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
@@ -0,0 +1,39 @@
|
||||
const admin = require("firebase-admin");
|
||||
const serviceAccount = require("./serviceAccountKey.json");
|
||||
const { googleAI, gemini25FlashLite } = require("@genkit-ai/googleai");
|
||||
const { GEMINI_API_KEY } = require("./config/keys");
|
||||
const { genkit } = require("genkit");
|
||||
|
||||
admin.initializeApp({
|
||||
credential: admin.credential.cert(serviceAccount),
|
||||
storageBucket: "musicland-d33f9.firebasestorage.app",
|
||||
});
|
||||
|
||||
exports.generateAI = async ({ system = "", prompt = "", schema }) => {
|
||||
const genkitInstance = genkit({
|
||||
plugins: [
|
||||
googleAI({
|
||||
apiKey: GEMINI_API_KEY,
|
||||
}),
|
||||
],
|
||||
model: gemini25FlashLite,
|
||||
});
|
||||
|
||||
if (prompt?.length < 1) {
|
||||
throw new Error(
|
||||
"Vous devez spécifier un prompt pour effectuer cette action.",
|
||||
);
|
||||
}
|
||||
|
||||
const { output } = await genkitInstance.generate({
|
||||
system,
|
||||
prompt,
|
||||
output: { schema },
|
||||
});
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
// Exporter toutes les fonctions
|
||||
exports.music = require("./src/music");
|
||||
exports.lyrics = require("./src/lyrics");
|
||||
Generated
+4770
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "functions",
|
||||
"description": "Cloud Functions for Firebase",
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"serve": "firebase emulators:start --only functions",
|
||||
"shell": "firebase functions:shell",
|
||||
"start": "npm run shell",
|
||||
"deploy": "firebase deploy --only functions",
|
||||
"logs": "firebase functions:log"
|
||||
},
|
||||
"engines": {
|
||||
"node": "18"
|
||||
},
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@genkit-ai/googleai": "^1.16.0",
|
||||
"axios": "^1.6.0",
|
||||
"firebase-admin": "^12.1.0",
|
||||
"firebase-functions": "^5.0.0",
|
||||
"genkit": "^1.16.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.15.0",
|
||||
"eslint-config-google": "^0.14.0"
|
||||
},
|
||||
"private": true
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
const {onCall} = require("firebase-functions/https");
|
||||
const { onCall } = require("firebase-functions/v2/https");
|
||||
const { z } = require("genkit");
|
||||
const { generateAI } = require("../index");
|
||||
|
||||
@@ -24,7 +24,8 @@ exports.generateLyrics = onCall({}, async ({auth = {}, data = {}}) => {
|
||||
|
||||
console.log("Function generate lyrics start with data", data);
|
||||
|
||||
const system = `
|
||||
const system =
|
||||
`
|
||||
Tu es un parolier expert en chanson française moderne et populaire.
|
||||
Tu écris des chansons marquantes, accessibles, sur des thématiques ` +
|
||||
`d'innovation, d'esprit d'équipe et de créativité digitale.
|
||||
@@ -39,7 +40,8 @@ Respecte ` +
|
||||
`.trim();
|
||||
|
||||
// Construction du prompt utilisateur
|
||||
const prompt = `
|
||||
const prompt =
|
||||
`
|
||||
Objectif : ${objective}
|
||||
Contexte : ${context}
|
||||
Émotion : ${emotion}
|
||||
@@ -66,7 +68,7 @@ Pour chaque ` +
|
||||
type: z
|
||||
.string()
|
||||
.describe(
|
||||
"Type de section : \"couplet\" ou \"refrain\" " +
|
||||
'Type de section : "couplet" ou "refrain" ' +
|
||||
"selon la structure",
|
||||
),
|
||||
lyrics: z
|
||||
|
||||
+151
-145
@@ -1,5 +1,5 @@
|
||||
const { onCall, onRequest } = require("firebase-functions/v2/https");
|
||||
const fetch = require("node-fetch");
|
||||
const axios = require("axios");
|
||||
const admin = require("firebase-admin");
|
||||
const { logger } = require("firebase-functions/logger");
|
||||
const { SUNO_API_KEY } = require("../config/keys");
|
||||
@@ -14,7 +14,7 @@ const SUNO_API_BASE = "https://api.sunoapi.org";
|
||||
const SUNO_API_PATH = "/api/v1/generate";
|
||||
const SUNO_STATUS_PATH = "/api/v1/generate/record-info";
|
||||
const SUNO_MODEL = "V4_5";
|
||||
const SUNO_INSTRUMENTAL = false;
|
||||
// const SUNO_MODEL = "V3_5";
|
||||
const SUNO_CALLBACK_URL =
|
||||
"https://us-central1-musicland-d33f9.cloudfunctions.net/music-sunoCallback";
|
||||
|
||||
@@ -66,7 +66,7 @@ function lyricsToTaggedPrompt(lyrics = []) {
|
||||
const sections = lyrics
|
||||
.map((section) => {
|
||||
if (!section || typeof section !== "object") return "";
|
||||
const { type = "verse", content = "" } = section;
|
||||
const { type = "verse", lyrics: content = "" } = section;
|
||||
if (!content.trim()) return "";
|
||||
|
||||
const tag = type.toLowerCase();
|
||||
@@ -88,7 +88,6 @@ function buildSunoPrompt({
|
||||
projectContext = "",
|
||||
emotionGuide = "",
|
||||
styleGuide = "",
|
||||
taggedLyrics = "",
|
||||
}) {
|
||||
const parts = [
|
||||
title ? `Titre: ${title}` : "",
|
||||
@@ -96,7 +95,6 @@ function buildSunoPrompt({
|
||||
projectContext ? `Contexte: ${projectContext}` : "",
|
||||
emotionGuide ? `Émotion: ${emotionGuide}` : "",
|
||||
styleGuide ? `Style: ${styleGuide}` : "",
|
||||
taggedLyrics ? `Paroles:\n${taggedLyrics}` : "",
|
||||
].filter(Boolean);
|
||||
|
||||
return parts.join("\n\n");
|
||||
@@ -145,9 +143,7 @@ function buildGuides({
|
||||
/**
|
||||
* Fonction principale de génération de musique
|
||||
*/
|
||||
exports.generateMusic = onCall(
|
||||
{ region: "europe-west1" },
|
||||
async ({ data = {} }) => {
|
||||
exports.generateMusic = onCall(async ({ data = {} }) => {
|
||||
try {
|
||||
const {
|
||||
title = "",
|
||||
@@ -170,82 +166,54 @@ exports.generateMusic = onCall(
|
||||
|
||||
const safeTitle = clampLen(title, 80);
|
||||
|
||||
// Construire les informations de contexte pour le style (sans les paroles)
|
||||
// Construire les informations de contexte pour le style
|
||||
const contextInfo = buildSunoPrompt({
|
||||
title: safeTitle,
|
||||
audience,
|
||||
projectContext,
|
||||
emotionGuide,
|
||||
styleGuide,
|
||||
taggedLyrics: "", // Ne pas inclure les paroles dans le contexte
|
||||
});
|
||||
|
||||
// Le style combine les informations de genre ET le contexte
|
||||
const baseStyle = buildStyle({ genres, voice, instruments, tempo });
|
||||
const enhancedStyle = contextInfo
|
||||
? `${baseStyle}. ${contextInfo}`
|
||||
: baseStyle;
|
||||
const enhancedStyle = `${baseStyle}. ${contextInfo}`;
|
||||
|
||||
const payload = {
|
||||
customMode: true,
|
||||
instrumental: false,
|
||||
model: SUNO_MODEL,
|
||||
prompt: clampLen(taggedLyrics, 3000),
|
||||
title: safeTitle,
|
||||
style: clampLen(enhancedStyle, 600),
|
||||
instrumental: SUNO_INSTRUMENTAL,
|
||||
callBackUrl: SUNO_CALLBACK_URL || "",
|
||||
};
|
||||
|
||||
// Les paroles vont dans le prompt, pas les instructions de style
|
||||
if (!SUNO_INSTRUMENTAL && taggedLyrics) {
|
||||
payload.prompt = clampLen(taggedLyrics, 3000);
|
||||
}
|
||||
console.log("PAYLOAD", payload);
|
||||
|
||||
const response = await fetch(`${SUNO_API_BASE}${SUNO_API_PATH}`, {
|
||||
method: "POST",
|
||||
const response = await axios.post(
|
||||
`${SUNO_API_BASE}${SUNO_API_PATH}`,
|
||||
payload,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${SUNO_API_KEY}`,
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
|
||||
const raw = await response.text();
|
||||
let parsed;
|
||||
|
||||
try {
|
||||
parsed = JSON.parse(raw);
|
||||
} catch (parseError) {
|
||||
console.error("❌ Erreur de parsing JSON:", parseError);
|
||||
const { HttpsError } = require("firebase-functions/v2/https");
|
||||
throw new HttpsError(
|
||||
"internal",
|
||||
`Réponse API invalide: ${raw.substring(0, 200)}...`,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
console.error("❌ Erreur API Suno:", {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
body: parsed || raw,
|
||||
});
|
||||
throw new Error(
|
||||
`Erreur API Suno (${response.status}): ${
|
||||
(parsed && parsed.error) || response.statusText
|
||||
}`,
|
||||
);
|
||||
}
|
||||
const parsed = response.data;
|
||||
|
||||
return {
|
||||
success: true,
|
||||
success: !!parsed?.data?.taskId,
|
||||
request: {
|
||||
model: SUNO_MODEL,
|
||||
instrumental: SUNO_INSTRUMENTAL,
|
||||
instrumental: false,
|
||||
title: safeTitle,
|
||||
style: enhancedStyle,
|
||||
prompt: SUNO_INSTRUMENTAL ? undefined : taggedLyrics,
|
||||
prompt: taggedLyrics,
|
||||
},
|
||||
response: parsed || { raw },
|
||||
response: parsed || {},
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("❌ Erreur lors de la génération de musique:", error);
|
||||
@@ -253,15 +221,12 @@ exports.generateMusic = onCall(
|
||||
`Erreur lors de la génération de musique: ${error.message}`,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Fonction pour suivre le statut d'une génération de musique Suno
|
||||
*/
|
||||
exports.getSunoStatus = onCall(
|
||||
{ region: "europe-west1" },
|
||||
async ({ data = {} }) => {
|
||||
exports.getSunoStatus = onCall(async ({ data = {} }) => {
|
||||
try {
|
||||
const { taskId } = data;
|
||||
|
||||
@@ -269,37 +234,42 @@ exports.getSunoStatus = onCall(
|
||||
throw new Error("TaskId manquant");
|
||||
}
|
||||
|
||||
logger.info("🔍 Vérification du statut Suno", { taskId });
|
||||
console.log("🔍 Vérification du statut Suno", { taskId });
|
||||
|
||||
const response = await fetch(
|
||||
`${SUNO_API_BASE}${SUNO_STATUS_PATH}?taskId=${taskId}`,
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${SUNO_API_KEY}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const raw = await response.text();
|
||||
let response;
|
||||
let parsed;
|
||||
|
||||
try {
|
||||
parsed = JSON.parse(raw);
|
||||
} catch (parseError) {
|
||||
console.error("❌ Erreur de parsing JSON:", parseError);
|
||||
throw new Error(`Réponse API invalide: ${raw.substring(0, 200)}...`);
|
||||
}
|
||||
response = await axios.get(
|
||||
`${SUNO_API_BASE}${SUNO_STATUS_PATH}?taskId=${taskId}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${SUNO_API_KEY}`,
|
||||
},
|
||||
timeout: 30000, // 30 secondes de timeout
|
||||
},
|
||||
);
|
||||
parsed = response.data;
|
||||
|
||||
if (!response.ok) {
|
||||
console.error("❌ Erreur API Suno Status:", {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
body: parsed || raw,
|
||||
console.log("📊 Réponse Suno API:", parsed);
|
||||
} catch (error) {
|
||||
console.error("❌ Erreur détaillée API Suno Status:", {
|
||||
message: error.message,
|
||||
status: error.response?.status,
|
||||
statusText: error.response?.statusText,
|
||||
data: error.response?.data,
|
||||
config: {
|
||||
url: error.config?.url,
|
||||
headers: error.config?.headers,
|
||||
},
|
||||
});
|
||||
|
||||
// Gestion spéciale pour les taskId de test
|
||||
if (response.status === 404 && taskId.includes("test")) {
|
||||
if (
|
||||
error.response &&
|
||||
error.response.status === 404 &&
|
||||
taskId.includes("test")
|
||||
) {
|
||||
return {
|
||||
success: true,
|
||||
taskId,
|
||||
@@ -311,31 +281,48 @@ exports.getSunoStatus = onCall(
|
||||
};
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`Erreur API Suno Status (${response.status}): ${
|
||||
(parsed && parsed.error) || response.statusText
|
||||
}`,
|
||||
);
|
||||
// Retourner une erreur plus descriptive
|
||||
const errorStatus = error.response?.status || "UNKNOWN";
|
||||
const errorMessage =
|
||||
error.response?.data?.msg ||
|
||||
error.response?.data?.message ||
|
||||
error.response?.statusText ||
|
||||
error.message;
|
||||
|
||||
return {
|
||||
success: false,
|
||||
taskId,
|
||||
error: {
|
||||
status: errorStatus,
|
||||
message: errorMessage,
|
||||
type: "API_ERROR",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
logger.info("✅ Statut Suno récupéré", {
|
||||
console.log("✅ Statut Suno récupéré", {
|
||||
taskId,
|
||||
status: parsed && parsed.status,
|
||||
status: parsed?.data?.status || parsed?.status,
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
taskId,
|
||||
data: parsed,
|
||||
data: parsed?.data || parsed,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("❌ Erreur lors de la vérification du statut:", error);
|
||||
throw new Error(
|
||||
`Erreur lors de la vérification du statut: ${error.message}`,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
success: false,
|
||||
taskId: data?.taskId,
|
||||
error: {
|
||||
message: error.message,
|
||||
type: "INTERNAL_ERROR",
|
||||
},
|
||||
);
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Cloud Function pour recevoir les callbacks de l'API Suno
|
||||
@@ -344,23 +331,24 @@ exports.getSunoStatus = onCall(
|
||||
*/
|
||||
exports.sunoCallback = onRequest(
|
||||
{
|
||||
region: "europe-west1",
|
||||
cors: true,
|
||||
methods: ["POST"],
|
||||
},
|
||||
async (req, res) => {
|
||||
try {
|
||||
logger.info("🎵 Callback Suno reçu", { data: req.body });
|
||||
|
||||
// Vérifier que c'est une requête POST
|
||||
console.log("🎵 Received music generation callback body:", req.body);
|
||||
if (req.method !== "POST") {
|
||||
logger.warn("⚠️ Méthode non autorisée:", req.method);
|
||||
console.warn("⚠️ Méthode non autorisée:", req.method);
|
||||
return res.status(405).json({ error: "Méthode non autorisée" });
|
||||
}
|
||||
|
||||
// Extraire les données du callback
|
||||
const { code, msg, data } = req.body || {};
|
||||
console.log("🎵 Callback details:", { code, msg, data });
|
||||
|
||||
// Extraire les données du callback - peut être dans data ou directement dans req.body
|
||||
const callbackData = data || req.body || {};
|
||||
const {
|
||||
id,
|
||||
taskId,
|
||||
status,
|
||||
audio_url: audioUrl,
|
||||
video_url: videoUrl,
|
||||
@@ -370,69 +358,87 @@ exports.sunoCallback = onRequest(
|
||||
tags,
|
||||
duration,
|
||||
error_message: errorMessage,
|
||||
} = req.body;
|
||||
} = callbackData;
|
||||
|
||||
// Vérifier que l'ID est présent
|
||||
if (!id) {
|
||||
logger.error("❌ ID manquant dans le callback");
|
||||
return res.status(400).json({ error: "ID manquant" });
|
||||
// Normaliser le statut global et le taskId
|
||||
const overallStatus = status || code || callbackData?.status || null;
|
||||
const overallTaskId = callbackData?.taskId || callbackData?.task_id || null;
|
||||
|
||||
// Déterminer les éléments piste(s) à traiter
|
||||
const items = Array.isArray(callbackData?.response?.data)
|
||||
? callbackData.response.data
|
||||
: Array.isArray(callbackData?.sunoData)
|
||||
? callbackData.sunoData
|
||||
: id || audioUrl || imageUrl || title || tags || duration
|
||||
? [callbackData]
|
||||
: [];
|
||||
|
||||
if (!items.length) {
|
||||
// Aucun contenu piste à mettre à jour: acquitter le callback sans erreur
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
message: "Callback reçu (aucune piste à mettre à jour)",
|
||||
taskId: overallTaskId,
|
||||
status: overallStatus,
|
||||
});
|
||||
}
|
||||
|
||||
const updates = [];
|
||||
|
||||
for (const item of items) {
|
||||
const trackId = item.id || item.musicId || item.audioId || item.audio_id;
|
||||
if (!trackId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Chercher le document correspondant dans Firestore
|
||||
const musicRef = db.collection("music").doc(id);
|
||||
const musicRef = db.collection("music").doc(trackId);
|
||||
const musicDoc = await musicRef.get();
|
||||
|
||||
if (!musicDoc.exists) {
|
||||
logger.error("❌ Document non trouvé pour l'ID:", id);
|
||||
return res.status(404).json({ error: "Document non trouvé" });
|
||||
// Si le doc n'existe pas, ignorer silencieusement cet item
|
||||
continue;
|
||||
}
|
||||
|
||||
// Préparer les données de mise à jour
|
||||
const updateData = {
|
||||
status: status,
|
||||
status: item.status || overallStatus,
|
||||
updatedAt: admin.firestore.FieldValue.serverTimestamp(),
|
||||
};
|
||||
|
||||
// Ajouter les URLs si disponibles
|
||||
if (audioUrl) {
|
||||
updateData.audioUrl = audioUrl;
|
||||
}
|
||||
if (videoUrl) {
|
||||
updateData.videoUrl = videoUrl;
|
||||
}
|
||||
if (imageUrl) {
|
||||
updateData.imageUrl = imageUrl;
|
||||
}
|
||||
if (lyric) {
|
||||
updateData.lyrics = lyric;
|
||||
}
|
||||
if (title) {
|
||||
updateData.title = title;
|
||||
}
|
||||
if (tags) {
|
||||
updateData.style = tags;
|
||||
}
|
||||
if (duration) {
|
||||
updateData.duration = duration;
|
||||
}
|
||||
if (errorMessage) {
|
||||
updateData.errorMessage = errorMessage;
|
||||
const audioU = item.audio_url || item.audioUrl || item.streamAudioUrl;
|
||||
const videoU = item.video_url || item.videoUrl;
|
||||
const imageU = item.image_url || item.imageUrl;
|
||||
const lyricText = item.lyric || item.prompt;
|
||||
const titleText = item.title;
|
||||
const tagsText = item.tags;
|
||||
const durationVal = item.duration;
|
||||
const errMsg = item.error_message || item.errorMessage;
|
||||
|
||||
if (audioU) updateData.audioUrl = audioU;
|
||||
if (videoU) updateData.videoUrl = videoU;
|
||||
if (imageU) updateData.imageUrl = imageU;
|
||||
if (lyricText) updateData.lyrics = lyricText;
|
||||
if (titleText) updateData.title = titleText;
|
||||
if (tagsText) updateData.style = tagsText;
|
||||
if (durationVal) updateData.duration = durationVal;
|
||||
if (errMsg) updateData.errorMessage = errMsg;
|
||||
|
||||
updates.push(
|
||||
musicRef
|
||||
.update(updateData)
|
||||
.then(() => ({ id: trackId, ok: true }))
|
||||
.catch(() => ({ id: trackId, ok: false })),
|
||||
);
|
||||
}
|
||||
|
||||
// Mettre à jour le document dans Firestore
|
||||
await musicRef.update(updateData);
|
||||
const results = await Promise.all(updates);
|
||||
const updated = results.filter((r) => r.ok).map((r) => r.id);
|
||||
|
||||
logger.info("✅ Document mis à jour avec succès", {
|
||||
id: id,
|
||||
status: status,
|
||||
});
|
||||
|
||||
// Répondre avec succès
|
||||
res.status(200).json({
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
message: "Callback traité avec succès",
|
||||
id: id,
|
||||
status: status,
|
||||
updated,
|
||||
taskId: overallTaskId,
|
||||
status: overallStatus,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error("❌ Erreur lors du traitement du callback:", error);
|
||||
|
||||
@@ -28,7 +28,7 @@ if (!firebase?.apps?.filter(({ name_ }) => name_ === "[DEFAULT]").length) {
|
||||
});
|
||||
|
||||
if (__DEV__) {
|
||||
firebase.functions().useEmulator("192.168.68.98", 5001);
|
||||
firebase.functions().useEmulator("192.168.1.81", 5001);
|
||||
}
|
||||
console.log("Firebase init");
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import { navigate } from "../../navigation/NavigationService";
|
||||
import { Routes } from "../../navigation";
|
||||
import { gutters } from "../../styles";
|
||||
import firebase from "../../config/firebase";
|
||||
import useMinuit from "react-native-minuit/src/hooks/useMinuit.js";
|
||||
import { responsiveHeight } from "react-native-responsive-dimensions";
|
||||
import useMinuit from "react-native-minuit/src/hooks/useMinuit";
|
||||
|
||||
const Studio = () => {
|
||||
const { setIsLoading } = useMinuit();
|
||||
@@ -70,7 +70,7 @@ const Studio = () => {
|
||||
const { data } = await firebase
|
||||
.functions()
|
||||
.httpsCallable("music-getSunoStatus")({
|
||||
taskId: "1b04b24a9b95a46125a73f25144b74c2",
|
||||
taskId: "2c9f00d27a30ace15b1b7cbc36886bff",
|
||||
});
|
||||
console.log("🎵 Status data:", data);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user