// ======================================== // SCRIPT: process_real.js // VRAI PROCESSEUR GOOGLE SHEETS + DIGITALOCEAN // ======================================== const { readCSVDataWithXMLFileName, fetchXMLFromDigitalOceanSimple } = require('./lib/DigitalOceanWorkflow'); const { handleFullWorkflow } = require('./lib/Main'); /** * Fonction principale qui fait VRAIMENT tout le processus * 1. Récupère données depuis Google Sheets (ligne rowNumber) * 2. Récupère XML depuis DigitalOcean (selon xmlFileName du GSheet) * 3. Lance le workflow complet */ async function processRealData(rowNumber) { console.log(`🚀 === TRAITEMENT RÉEL LIGNE ${rowNumber} ===\n`); // Réduire verbosité console process.env.LOG_LEVEL = 'INFO'; try { // 1. RÉCUPÉRER DONNÉES GOOGLE SHEETS console.log('1️⃣ Récupération données Google Sheets...'); const csvData = await readCSVDataWithXMLFileName(rowNumber); console.log(`✅ Données récupérées:`); console.log(` MC0: ${csvData.mc0}`); console.log(` T0: ${csvData.t0}`); console.log(` XML File: ${csvData.xmlFileName}`); console.log(` Personnalité: ${csvData.personality?.nom || 'N/A'}`); // 2. RÉCUPÉRER XML DEPUIS DIGITALOCEAN console.log('\n2️⃣ Récupération XML DigitalOcean...'); if (!csvData.xmlFileName) { throw new Error('Nom fichier XML manquant dans Google Sheets (colonne J)'); } const xmlContent = await fetchXMLFromDigitalOceanSimple(csvData.xmlFileName); console.log(`✅ XML récupéré: ${csvData.xmlFileName} (${xmlContent.length} caractères)`); // 3. PRÉPARER DONNÉES WORKFLOW console.log('\n3️⃣ Préparation workflow...'); const workflowData = { csvData: csvData, xmlTemplate: Buffer.from(xmlContent).toString('base64'), source: 'real_gsheets_digitalocean', rowNumber: rowNumber }; // 4. LANCER WORKFLOW COMPLET console.log('4️⃣ Lancement workflow (6 LLMs)...'); const startTime = Date.now(); const result = await handleFullWorkflow(workflowData); const duration = Date.now() - startTime; // 5. AFFICHER RÉSULTATS console.log(`\n🎯 === RÉSULTATS (${Math.round(duration/1000)}s) ===`); console.log(`✅ Success: ${result.success}`); console.log(`📊 Éléments générés: ${result.elementsGenerated}`); console.log(`📝 Mots total: ${result.stats?.wordCount || 'N/A'}`); console.log(`🤖 LLMs utilisés: ${result.llmsUsed?.join(', ') || 'N/A'}`); console.log(`📄 XML final: ${result.xmlContent?.length || 0} caractères`); console.log(`🔍 Validation: ${result.validationReport?.status || 'N/A'}`); console.log(`💾 Article ID: ${result.articleStorage?.articleId || 'N/A'}`); if (result.validationReport?.errors?.length > 0) { console.log(`\n⚠️ Erreurs détectées:`); result.validationReport.errors.forEach(error => { console.log(` - ${error.type}: ${error.message}`); }); } return result; } catch (error) { console.error(`\n❌ Erreur traitement ligne ${rowNumber}:`, error.message); console.log('\n📋 Vérifiez les logs détaillés dans:', `logs/seo-generator-${new Date().toISOString().split('T')[0]}.log`); throw error; } } /** * Traiter plusieurs lignes en séquence */ async function processMultipleRealRows(rowNumbers) { console.log(`🔄 === TRAITEMENT MULTI-LIGNES ===`); console.log(`Lignes à traiter: ${rowNumbers.join(', ')}\n`); const results = []; for (const rowNumber of rowNumbers) { try { console.log(`\n📍 === LIGNE ${rowNumber} ===`); const result = await processRealData(rowNumber); results.push({ rowNumber, success: true, result }); console.log(`✅ Ligne ${rowNumber} terminée\n`); } catch (error) { console.error(`❌ Ligne ${rowNumber} échouée: ${error.message}\n`); results.push({ rowNumber, success: false, error: error.message }); } } // Résumé final const successCount = results.filter(r => r.success).length; console.log(`\n🎯 === RÉSUMÉ FINAL ===`); console.log(`✅ Réussis: ${successCount}/${rowNumbers.length}`); console.log(`❌ Échoués: ${rowNumbers.length - successCount}/${rowNumbers.length}`); return results; } /** * Test simple d'une ligne sans traitement complet */ async function debugRealRow(rowNumber) { console.log(`🔍 === DEBUG LIGNE ${rowNumber} ===\n`); try { // 1. Test Google Sheets console.log('1️⃣ Test Google Sheets...'); const csvData = await readCSVDataWithXMLFileName(rowNumber); console.log('✅ Google Sheets OK'); console.log(` Données: ${csvData.mc0} | ${csvData.xmlFileName}`); // 2. Test DigitalOcean console.log('\n2️⃣ Test DigitalOcean...'); const xmlContent = await fetchXMLFromDigitalOceanSimple(csvData.xmlFileName); console.log('✅ DigitalOcean OK'); console.log(` XML: ${xmlContent.length} caractères`); console.log(` Début: ${xmlContent.substring(0, 100)}...`); return { csvData, xmlContent }; } catch (error) { console.error(`❌ Debug échoué:`, error.message); throw error; } } // Usage en ligne de commande if (require.main === module) { const args = process.argv.slice(2); if (args.includes('--help')) { console.log(` Usage: node process_real.js [options] [rowNumber(s)] Options: --help Afficher cette aide --debug Mode debug (pas de traitement complet) --multi Traiter plusieurs lignes (ex: --multi 2,3,4) Exemples: node process_real.js 2 # Traiter ligne 2 node process_real.js --debug 2 # Debug ligne 2 seulement node process_real.js --multi 2,3,4 # Traiter lignes 2,3,4 `); process.exit(0); } const isDebug = args.includes('--debug'); const isMulti = args.includes('--multi'); let targetRows = []; if (isMulti) { const multiIndex = args.indexOf('--multi'); const rowsArg = args[multiIndex + 1]; if (rowsArg) { targetRows = rowsArg.split(',').map(n => parseInt(n.trim())); } } else { const rowNumber = parseInt(args.find(arg => !arg.startsWith('--'))) || 2; targetRows = [rowNumber]; } // Lancer le traitement (async () => { try { if (isDebug) { for (const row of targetRows) { await debugRealRow(row); } } else if (isMulti) { await processMultipleRealRows(targetRows); } else { await processRealData(targetRows[0]); } console.log('\n🎉 Terminé avec succès !'); } catch (error) { console.error('\n💥 Échec:', error.message); process.exit(1); } })(); } module.exports = { processRealData, processMultipleRealRows, debugRealRow };